diff --git a/kdb-bot/src/bot_api/abc/auth_service_abc.py b/kdb-bot/src/bot_api/abc/auth_service_abc.py index 7d526078..1ba5fbbb 100644 --- a/kdb-bot/src/bot_api/abc/auth_service_abc.py +++ b/kdb-bot/src/bot_api/abc/auth_service_abc.py @@ -52,17 +52,13 @@ class AuthServiceABC(ABC): pass @abstractmethod - async def add_auth_user_async(self, user_dto: AuthUserDTO): + def add_auth_user(self, user_dto: AuthUserDTO): pass @abstractmethod async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): pass - @abstractmethod - async def add_auth_user_by_discord_async(self, user_dto: AuthUserDTO, dc_id: int) -> OAuthDTO: - pass - @abstractmethod async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): pass @@ -84,7 +80,7 @@ class AuthServiceABC(ABC): pass @abstractmethod - async def verify_api_key(self, api_key: str) -> bool: + def verify_api_key(self, api_key: str) -> bool: pass @abstractmethod @@ -92,7 +88,7 @@ class AuthServiceABC(ABC): pass @abstractmethod - async def login_discord_async(self, oauth_dto: AuthUserDTO) -> TokenDTO: + async def login_discord_async(self, oauth_dto: AuthUserDTO, dc_id: int) -> TokenDTO: pass @abstractmethod diff --git a/kdb-bot/src/bot_api/controller/auth_controller.py b/kdb-bot/src/bot_api/controller/auth_controller.py index f47bf75e..911ceca8 100644 --- a/kdb-bot/src/bot_api/controller/auth_controller.py +++ b/kdb-bot/src/bot_api/controller/auth_controller.py @@ -6,8 +6,6 @@ from flask import request, jsonify, Response from bot_api.abc.auth_service_abc import AuthServiceABC from bot_api.api import Api -from bot_api.exception.service_error_code_enum import ServiceErrorCode -from bot_api.exception.service_exception import ServiceException from bot_api.filter.auth_user_select_criteria import AuthUserSelectCriteria from bot_api.json_processor import JSONProcessor from bot_api.logging.api_logger import ApiLogger @@ -73,7 +71,7 @@ class AuthController: @Route.post(f"{BasePath}/register") async def register(self): dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) - await self._auth_service.add_auth_user_async(dto) + await self._auth_service.add_auth_user(dto) return "", 200 @Route.post(f"{BasePath}/register-by-id/") diff --git a/kdb-bot/src/bot_api/controller/auth_discord_controller.py b/kdb-bot/src/bot_api/controller/auth_discord_controller.py index b9a13906..8ad193cc 100644 --- a/kdb-bot/src/bot_api/controller/auth_discord_controller.py +++ b/kdb-bot/src/bot_api/controller/auth_discord_controller.py @@ -77,23 +77,6 @@ class AuthDiscordController: login_url, state = oauth.authorization_url(self._auth_settings.auth_url) return jsonify({"loginUrl": login_url}) - @Route.get(f"{BasePath}/create-user") - async def discord_create_user(self) -> Response: - response = self._get_user_from_discord_response() - result = await self._auth_service.add_auth_user_by_discord_async( - AuthUserDTO( - 0, - response["username"], - response["discriminator"], - response["email"], - str(uuid.uuid4()), - None, - AuthRoleEnum.normal, - ), - response["id"], - ) - return jsonify(result.to_dict()) - @Route.get(f"{BasePath}/login") async def discord_login(self) -> Response: response = self._get_user_from_discord_response() @@ -107,5 +90,5 @@ class AuthDiscordController: AuthRoleEnum.normal, ) - result = await self._auth_service.login_discord_async(dto) + result = await self._auth_service.login_discord_async(dto, response["id"]) return jsonify(result.to_dict()) diff --git a/kdb-bot/src/bot_api/route/route.py b/kdb-bot/src/bot_api/route/route.py index 39a6044d..74278f28 100644 --- a/kdb-bot/src/bot_api/route/route.py +++ b/kdb-bot/src/bot_api/route/route.py @@ -1,6 +1,6 @@ import functools from functools import wraps -from typing import Optional, Callable +from typing import Optional, Callable, Union from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.environment import ApplicationEnvironmentABC @@ -13,6 +13,7 @@ from bot_api.exception.service_exception import ServiceException from bot_api.model.error_dto import ErrorDTO from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC from bot_data.model.auth_role_enum import AuthRoleEnum +from bot_data.model.auth_user import AuthUser class Route: @@ -29,6 +30,27 @@ class Route: cls._auth = auth cls._env = env.environment_name + @classmethod + def get_user(cls) -> Optional[Union[str, AuthUser]]: + token = None + api_key = None + authorization = request.headers.get("Authorization").split() + match authorization[0]: + case "Bearer": + token = authorization[1] + case "API-Key": + api_key = authorization[1] + + if api_key is not None: + return "system" + + if token is None: + return None + + jwt = cls._auth.decode_token(token) + user = cls._auth_users.get_auth_user_by_email(jwt["email"]) + return user + @classmethod def authorize(cls, f: Callable = None, role: AuthRoleEnum = None, skip_in_dev=False, by_api_key=False): if f is None: @@ -39,10 +61,25 @@ class Route: if skip_in_dev and cls._env == "development": return await f(*args, **kwargs) - if "Authorization" not in request.headers and by_api_key and "API-Key" in request.headers: + token = None + api_key = None + if "Authorization" in request.headers: + if " " not in request.headers.get("Authorization"): + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set") + error = ErrorDTO(ex.error_code, ex.message) + return jsonify(error.to_dict()), 401 + + authorization = request.headers.get("Authorization").split() + match authorization[0]: + case "Bearer": + token = authorization[1] + case "API-Key": + api_key = authorization[1] + + if api_key is not None: valid = False try: - valid = cls._auth.verify_api_key(request.headers["API-Key"]) + valid = cls._auth.verify_api_key(api_key) except ServiceException as e: error = ErrorDTO(e.error_code, e.message) return jsonify(error.to_dict()), 403 @@ -56,11 +93,6 @@ class Route: return await f(*args, **kwargs) - token = None - if "Authorization" in request.headers: - bearer = request.headers.get("Authorization") - token = bearer.split()[1] - if token is None: ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set") error = ErrorDTO(ex.error_code, ex.message) diff --git a/kdb-bot/src/bot_api/service/auth_service.py b/kdb-bot/src/bot_api/service/auth_service.py index 7193b434..675eca99 100644 --- a/kdb-bot/src/bot_api/service/auth_service.py +++ b/kdb-bot/src/bot_api/service/auth_service.py @@ -223,18 +223,13 @@ class AuthService(AuthServiceABC): user = self._auth_users.find_auth_user_by_email(email) return AUT.to_dto(user) if user is not None else None - async def add_auth_user_async(self, user_dto: AuthUserDTO): + def add_auth_user(self, user_dto: AuthUserDTO): db_user = self._auth_users.find_auth_user_by_email(user_dto.email) if db_user is not None: raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") user = AUT.to_db(user_dto) - if ( - self._auth_users.get_all_auth_users() - .where(lambda x: x.name != "internal" and x.email != "internal@localhost") - .count() - == 0 - ): + if self._auth_users.get_all_auth_users().count() == 0: user.auth_role = AuthRoleEnum.admin user.password_salt = uuid.uuid4() @@ -277,51 +272,6 @@ class AuthService(AuthServiceABC): self._db.save_changes() - async def add_auth_user_by_discord_async(self, user_dto: AuthUserDTO, dc_id: int) -> OAuthDTO: - db_auth_user = self._auth_users.find_auth_user_by_email(user_dto.email) - - # user exists - if db_auth_user is not None and db_auth_user.users.count() > 0: - # raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists') - self._logger.debug(__name__, f"Discord user already exists") - return OAuthDTO(AUT.to_dto(db_auth_user), None) - - # user exists but discord user id not set - elif db_auth_user is not None and db_auth_user.users.count() == 0: - self._logger.debug(__name__, f"Auth user exists but not linked with discord") - # users = self._users.get_users_by_discord_id(user_dto.user_id) - # add auth_user to user refs - db_auth_user.oauth_id = None - - else: - # user does not exists - self._logger.debug(__name__, f"Auth user does not exist") - try: - user_dto.user_id = self._users.get_users_by_discord_id(user_dto.user_id).single().user_id - except Exception as e: - self._logger.error(__name__, f"User not found") - user_dto.user_id = None - - await self.add_auth_user_async(user_dto) - db_auth_user = self._auth_users.get_auth_user_by_email(user_dto.email) - db_auth_user.oauth_id = uuid.uuid4() - - for g in self._bot.guilds: - member = g.get_member(int(dc_id)) - if member is None: - continue - - server = self._servers.get_server_by_discord_id(g.id) - users = self._users.get_users_by_discord_id(dc_id) - for user in users: - if user.server.server_id != server.server_id: - continue - self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_auth_user, user)) - - self._auth_users.update_auth_user(db_auth_user) - self._db.save_changes() - return OAuthDTO(AUT.to_dto(db_auth_user), db_auth_user.oauth_id) - async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): if update_user_dto is None: raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") @@ -498,7 +448,7 @@ class AuthService(AuthServiceABC): if not keys.contains(api_key): raise ServiceException(ServiceErrorCode.InvalidData, "API-Key invalid") except Exception as e: - self._logger.error(__name__, f"Token invalid", e) + self._logger.error(__name__, f"API-Key invalid", e) return False return True @@ -523,16 +473,21 @@ class AuthService(AuthServiceABC): self._db.save_changes() return TokenDTO(token, refresh_token) - async def login_discord_async(self, user_dto: AuthUserDTO) -> TokenDTO: + async def login_discord_async(self, user_dto: AuthUserDTO, dc_id: int) -> TokenDTO: if user_dto is None: raise ServiceException(ServiceErrorCode.InvalidData, "User not set") db_user = self._auth_users.find_auth_user_by_email(user_dto.email) if db_user is None: - await self.add_auth_user_async(user_dto) + self.add_auth_user(user_dto) # raise ServiceException(ServiceErrorCode.InvalidUser, f'User not found') db_user = self._auth_users.get_auth_user_by_email(user_dto.email) + if db_user.users.count() == 0: + self._users.get_users_by_discord_id(dc_id).for_each( + lambda x: self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_user, x)) + ) + token = self.generate_token(db_user) refresh_token = self._create_and_save_refresh_token(db_user) if db_user.forgot_password_id is not None: diff --git a/kdb-bot/src/bot_data/service/auth_user_repository_service.py b/kdb-bot/src/bot_data/service/auth_user_repository_service.py index 15592b4c..295e3c2f 100644 --- a/kdb-bot/src/bot_data/service/auth_user_repository_service.py +++ b/kdb-bot/src/bot_data/service/auth_user_repository_service.py @@ -11,7 +11,6 @@ from bot_data.filtered_result import FilteredResult from bot_data.model.auth_role_enum import AuthRoleEnum from bot_data.model.auth_user import AuthUser from bot_data.model.auth_user_users_relation import AuthUserUsersRelation -from bot_data.model.user import User class AuthUserRepositoryService(AuthUserRepositoryABC): diff --git a/kdb-bot/src/bot_graphql/abc/query_abc.py b/kdb-bot/src/bot_graphql/abc/query_abc.py index 4e291ae4..53215b97 100644 --- a/kdb-bot/src/bot_graphql/abc/query_abc.py +++ b/kdb-bot/src/bot_graphql/abc/query_abc.py @@ -1,11 +1,26 @@ from typing import Callable from ariadne import ObjectType +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC from cpl_query.extension import List +from bot_api.route.route import Route +from bot_data.model.auth_role_enum import AuthRoleEnum +from bot_data.model.auth_user import AuthUser +from bot_data.model.auto_role import AutoRole +from bot_data.model.auto_role_rule import AutoRoleRule +from bot_data.model.client import Client +from bot_data.model.known_user import KnownUser +from bot_data.model.level import Level +from bot_data.model.server import Server +from bot_data.model.user import User +from bot_data.model.user_joined_server import UserJoinedServer +from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel from bot_graphql.abc.filter_abc import FilterABC from bot_graphql.filter.page import Page from bot_graphql.filter.sort import Sort +from modules.permission.service.permission_service import PermissionService class QueryABC(ObjectType): @@ -31,11 +46,100 @@ class QueryABC(ObjectType): sort.from_dict(kwargs["sort"]) kwargs["sort"] = sort - return self._resolve_collection(get_collection(*args), *args, **kwargs) + collection = get_collection(*args) + user = Route.get_user() + + if user == "system" or user.auth_role == AuthRoleEnum.admin: + return self._resolve_collection(collection, *args, **kwargs) + + for x in collection: + if not self._can_user_see_element(user, x): + return List() + + return self._resolve_collection(collection, *args, **kwargs) self.set_field(f"{name}s", wrapper) self.set_field(f"{name}Count", lambda *args: get_collection(*args).count()) + @ServiceProviderABC.inject + def _can_user_see_element(self, user: AuthUser, element, services: ServiceProviderABC) -> bool: + permissions: PermissionService = services.get_service(PermissionService) + bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) + + access = False + if type(element) == AutoRole: + element: AutoRole = element + for u in user.users: + u: User = u + guild = bot.get_guild(u.server.discord_server_id) + member = guild.get_member(u.discord_id) + if permissions.is_member_moderator(member) and u.server.server_id == element.server.server_id: + access = True + break + + elif type(element) == AutoRoleRule: + element: AutoRole = element.auto_role + for u in user.users: + u: User = u + guild = bot.get_guild(u.server.discord_server_id) + member = guild.get_member(u.discord_id) + if permissions.is_member_moderator(member) and u.server.server_id == element.server.server_id: + access = True + break + + elif type(element) == Client: + for u in user.users: + u: User = u + if u.server.server_id == element.server.server_id: + access = True + break + + elif type(element) == KnownUser: + for u in user.users: + u: User = u + guild = bot.get_guild(u.server.discord_server_id) + member = guild.get_member(u.discord_id) + if permissions.is_member_moderator(member): + access = True + break + + elif type(element) == Level: + for u in user.users: + u: User = u + if u.server.server_id == element.server.server_id: + access = True + break + + elif type(element) == Server: + for u in user.users: + u: User = u + if u.server.server_id == element.server_id: + access = True + break + + elif type(element) == User: + for u in user.users: + u: User = u + if u.user_id == element.user_id: + access = True + break + + elif type(element) == UserJoinedServer: + for u in user.users: + u: User = u + if u.user_id == element.user.user_id: + access = True + break + + elif type(element) == UserJoinedVoiceChannel: + for u in user.users: + u: User = u + if u.user_id == element.user.user_id: + access = True + break + + return access + # @FilterABC.resolve_filter_annotation def _resolve_collection(self, collection: List, *_, filter: FilterABC = None, page: Page = None, sort: Sort = None): if filter is not None: diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_query.py index 53a2b97c..0876d62f 100644 --- a/kdb-bot/src/bot_graphql/queries/auto_role_query.py +++ b/kdb-bot/src/bot_graphql/queries/auto_role_query.py @@ -4,6 +4,7 @@ from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.model.auto_role import AutoRole from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.server_filter import ServerFilter @@ -26,7 +27,9 @@ class AutoRoleQuery(DataQueryABC): self.set_field("messageId", self.resolve_message_id) self.set_field("server", self.resolve_server) self.add_collection( - "autoRoleRule", lambda x, *_: self._auto_role_rules.get_auto_role_rules_by_auto_role_id(x.auto_role_id) + "autoRoleRule", + lambda x, *_: self._auto_role_rules.get_auto_role_rules_by_auto_role_id(x.auto_role_id), + AutoRoleFilter, ) @staticmethod diff --git a/kdb-bot/src/bot_graphql/queries/server_query.py b/kdb-bot/src/bot_graphql/queries/server_query.py index 515c4872..32b86259 100644 --- a/kdb-bot/src/bot_graphql/queries/server_query.py +++ b/kdb-bot/src/bot_graphql/queries/server_query.py @@ -8,6 +8,9 @@ from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoic from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.server import Server from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.filter.auto_role_filter import AutoRoleFilter +from bot_graphql.filter.client_filter import ClientFilter +from bot_graphql.filter.level_filter import LevelFilter from bot_graphql.filter.user_filter import UserFilter @@ -38,10 +41,16 @@ class ServerQuery(DataQueryABC): self.set_field("iconURL", self.resolve_icon_url) self.add_collection( - "autoRole", lambda server, *_: self._auto_roles.get_auto_roles_by_server_id(server.server_id) + "autoRole", + lambda server, *_: self._auto_roles.get_auto_roles_by_server_id(server.server_id), + AutoRoleFilter, + ) + self.add_collection( + "client", lambda server, *_: self._clients.get_clients_by_server_id(server.server_id), ClientFilter + ) + self.add_collection( + "level", lambda server, *_: self._levels.get_levels_by_server_id(server.server_id), LevelFilter ) - self.add_collection("client", lambda server, *_: self._clients.get_clients_by_server_id(server.server_id)) - self.add_collection("level", lambda server, *_: self._levels.get_levels_by_server_id(server.server_id)) self.add_collection("user", lambda server, *_: self._users.get_users_by_server_id(server.server_id), UserFilter) @staticmethod diff --git a/kdb-bot/src/bot_graphql/queries/user_query.py b/kdb-bot/src/bot_graphql/queries/user_query.py index 7bca0379..eca30928 100644 --- a/kdb-bot/src/bot_graphql/queries/user_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_query.py @@ -5,6 +5,8 @@ from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepos from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC from bot_data.model.user import User from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter +from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter from modules.level.service.level_service import LevelService @@ -31,9 +33,15 @@ class UserQuery(DataQueryABC): self.set_field("xp", self.resolve_xp) self.set_field("ontime", self.resolve_ontime) self.set_field("level", self.resolve_level) - self.add_collection("joinedServer", lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.user_id)) self.add_collection( - "joinedVoiceChannel", lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id) + "joinedServer", + lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.user_id), + UserJoinedServerFilter, + ) + self.add_collection( + "joinedVoiceChannel", + lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id), + UserJoinedVoiceChannelFilter, ) self.set_field("server", self.resolve_server) diff --git a/kdb-bot/src/bot_graphql/query.py b/kdb-bot/src/bot_graphql/query.py index 9c574ebc..aa5948d9 100644 --- a/kdb-bot/src/bot_graphql/query.py +++ b/kdb-bot/src/bot_graphql/query.py @@ -9,9 +9,12 @@ from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_graphql.abc.query_abc import QueryABC from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter +from bot_graphql.filter.client_filter import ClientFilter from bot_graphql.filter.level_filter import LevelFilter from bot_graphql.filter.server_filter import ServerFilter from bot_graphql.filter.user_filter import UserFilter +from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter +from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter class Query(QueryABC): @@ -38,12 +41,16 @@ class Query(QueryABC): self.add_collection("autoRole", lambda *_: self._auto_roles.get_auto_roles(), AutoRoleFilter) self.add_collection("autoRoleRule", lambda *_: self._auto_roles.get_auto_role_rules(), AutoRoleRuleFilter) - self.add_collection("client", lambda *_: self._clients.get_clients()) + self.add_collection("client", lambda *_: self._clients.get_clients(), ClientFilter) self.add_collection("knownUser", lambda *_: self._known_users.get_users()) self.add_collection("level", lambda *_: self._levels.get_levels(), LevelFilter) self.add_collection("server", lambda *_: self._servers.get_servers(), ServerFilter) - self.add_collection("userJoinedServer", lambda *_: self._user_joined_servers.get_user_joined_servers()) self.add_collection( - "userJoinedVoiceChannel", lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels() + "userJoinedServer", lambda *_: self._user_joined_servers.get_user_joined_servers(), UserJoinedServerFilter + ) + self.add_collection( + "userJoinedVoiceChannel", + lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels(), + UserJoinedVoiceChannelFilter, ) self.add_collection("user", lambda *_: self._users.get_users(), UserFilter) diff --git a/kdb-bot/src/modules/base/events/base_on_member_remove_event.py b/kdb-bot/src/modules/base/events/base_on_member_remove_event.py index ba9217f0..b63cc90d 100644 --- a/kdb-bot/src/modules/base/events/base_on_member_remove_event.py +++ b/kdb-bot/src/modules/base/events/base_on_member_remove_event.py @@ -57,7 +57,7 @@ class BaseOnMemberRemoveEvent(OnMemberRemoveABC): self._user_joins.update_user_joined_server(join) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f"Cannot get user {member.id}", e) + self._logger.error(__name__, f"Cannot remove user {member.id}", e) @EventChecks.check_is_ready() async def on_member_remove(self, member: discord.Member): diff --git a/kdb-web/package.json b/kdb-web/package.json index f303d0cd..02ac81a3 100644 --- a/kdb-web/package.json +++ b/kdb-web/package.json @@ -1,6 +1,6 @@ { "name": "kdb-web", - "version": "0.3.dev162-3", + "version": "0.3.dev89", "scripts": { "ng": "ng", "update-version": "ts-node-esm update-version.ts", diff --git a/kdb-web/src/app/services/auth/auth.service.ts b/kdb-web/src/app/services/auth/auth.service.ts index a96e231f..3a0c86cf 100644 --- a/kdb-web/src/app/services/auth/auth.service.ts +++ b/kdb-web/src/app/services/auth/auth.service.ts @@ -168,14 +168,6 @@ export class AuthService { }); } - discordCreateUser(code: string, state: string) { - return this.http.get(`${this.appsettings.getApiURL()}/api/auth/discord/create-user?code=${code}&state=${state}`, { - headers: new HttpHeaders({ - 'Content-Type': 'application/json' - }) - }); - } - discordLogin(code: string, state: string): Observable { return this.http.get(`${this.appsettings.getApiURL()}/api/auth/discord/login?code=${code}&state=${state}`, { headers: new HttpHeaders({ diff --git a/kdb-web/src/assets/config.json b/kdb-web/src/assets/config.json index 79720613..3aa6de44 100644 --- a/kdb-web/src/assets/config.json +++ b/kdb-web/src/assets/config.json @@ -3,7 +3,7 @@ "WebVersion": { "Major": "0", "Minor": "3", - "Micro": "dev162-2" + "Micro": "dev89" }, "Themes": [ {