Merge pull request '#440' (#441) from #440 into dev
All checks were successful
Deploy dev on push / on-push-deploy_sh-edraft (push) Successful in 4m43s
All checks were successful
Deploy dev on push / on-push-deploy_sh-edraft (push) Successful in 4m43s
Reviewed-on: #441
This commit is contained in:
commit
026331b397
@ -14,7 +14,10 @@ from bot_api.model.reset_password_dto import ResetPasswordDTO
|
|||||||
from bot_api.model.token_dto import TokenDTO
|
from bot_api.model.token_dto import TokenDTO
|
||||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
|
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
from bot_data.model.auth_role_enum import AuthRoleEnum
|
||||||
|
from bot_data.model.technician_config import TechnicianConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthController:
|
class AuthController:
|
||||||
@ -30,6 +33,7 @@ class AuthController:
|
|||||||
mail_settings: EMailClientSettings,
|
mail_settings: EMailClientSettings,
|
||||||
mailer: EMailClientABC,
|
mailer: EMailClientABC,
|
||||||
auth_service: AuthServiceABC,
|
auth_service: AuthServiceABC,
|
||||||
|
technician_config: TechnicianConfig,
|
||||||
):
|
):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._env = env
|
self._env = env
|
||||||
@ -39,6 +43,7 @@ class AuthController:
|
|||||||
self._mail_settings = mail_settings
|
self._mail_settings = mail_settings
|
||||||
self._mailer = mailer
|
self._mailer = mailer
|
||||||
self._auth_service = auth_service
|
self._auth_service = auth_service
|
||||||
|
self._technician_config = technician_config
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/users")
|
@Route.get(f"{BasePath}/users")
|
||||||
@Route.authorize(role=AuthRoleEnum.admin)
|
@Route.authorize(role=AuthRoleEnum.admin)
|
||||||
@ -70,17 +75,32 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/register")
|
@Route.post(f"{BasePath}/register")
|
||||||
async def register(self):
|
async def register(self):
|
||||||
|
if not FeatureFlagsSettings.get_flag_from_dict(
|
||||||
|
self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||||
self._auth_service.add_auth_user(dto)
|
self._auth_service.add_auth_user(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/register-by-id/<id>")
|
@Route.post(f"{BasePath}/register-by-id/<id>")
|
||||||
async def register_id(self, id: str):
|
async def register_id(self, id: str):
|
||||||
|
if not FeatureFlagsSettings.get_flag_from_dict(
|
||||||
|
self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
result = await self._auth_service.confirm_email_async(id)
|
result = await self._auth_service.confirm_email_async(id)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/login")
|
@Route.post(f"{BasePath}/login")
|
||||||
async def login(self) -> Response:
|
async def login(self) -> Response:
|
||||||
|
if not FeatureFlagsSettings.get_flag_from_dict(
|
||||||
|
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
||||||
|
):
|
||||||
|
return jsonify({})
|
||||||
|
|
||||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||||
result = await self._auth_service.login_async(dto)
|
result = await self._auth_service.login_async(dto)
|
||||||
return jsonify(result.to_dict())
|
return jsonify(result.to_dict())
|
||||||
@ -100,6 +120,11 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/forgot-password/<email>")
|
@Route.post(f"{BasePath}/forgot-password/<email>")
|
||||||
async def forgot_password(self, email: str):
|
async def forgot_password(self, email: str):
|
||||||
|
if not FeatureFlagsSettings.get_flag_from_dict(
|
||||||
|
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
||||||
|
):
|
||||||
|
return "", 409
|
||||||
|
|
||||||
await self._auth_service.forgot_password_async(email)
|
await self._auth_service.forgot_password_async(email)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@ -110,6 +135,11 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/reset-password")
|
@Route.post(f"{BasePath}/reset-password")
|
||||||
async def reset_password(self):
|
async def reset_password(self):
|
||||||
|
if not FeatureFlagsSettings.get_flag_from_dict(
|
||||||
|
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
||||||
|
):
|
||||||
|
return "", 409
|
||||||
|
|
||||||
dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True))
|
dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True))
|
||||||
await self._auth_service.reset_password_async(dto)
|
await self._auth_service.reset_password_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
@ -12,6 +12,9 @@ from bot_api.logging.api_logger import ApiLogger
|
|||||||
from bot_api.model.settings_dto import SettingsDTO
|
from bot_api.model.settings_dto import SettingsDTO
|
||||||
from bot_api.model.version_dto import VersionDTO
|
from bot_api.model.version_dto import VersionDTO
|
||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
|
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||||
|
from bot_data.model.technician_config import TechnicianConfig
|
||||||
|
|
||||||
|
|
||||||
class GuiController:
|
class GuiController:
|
||||||
@ -82,3 +85,11 @@ class GuiController:
|
|||||||
)
|
)
|
||||||
self._mailer.send_mail(mail)
|
self._mailer.send_mail(mail)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
|
@Route.get(f"{BasePath}/has-feature-flag/<flag>")
|
||||||
|
async def has_feature_flag(self, flag: str):
|
||||||
|
settings: TechnicianConfig = self._config.get_configuration(TechnicianConfig)
|
||||||
|
return {
|
||||||
|
"key": flag,
|
||||||
|
"value": FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(flag)),
|
||||||
|
}
|
||||||
|
@ -28,3 +28,5 @@ class FeatureFlagsEnum(Enum):
|
|||||||
technician_full_access = "TechnicianFullAccess"
|
technician_full_access = "TechnicianFullAccess"
|
||||||
steam_special_offers = "SteamSpecialOffers"
|
steam_special_offers = "SteamSpecialOffers"
|
||||||
scheduled_events = "ScheduledEvents"
|
scheduled_events = "ScheduledEvents"
|
||||||
|
basic_registration = "BasicRegistration"
|
||||||
|
basic_login = "BasicLogin"
|
||||||
|
@ -30,6 +30,8 @@ class FeatureFlagsSettings(ConfigurationModelABC):
|
|||||||
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
||||||
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
||||||
FeatureFlagsEnum.scheduled_events.value: False, # 14.11.2023 #410
|
FeatureFlagsEnum.scheduled_events.value: False, # 14.11.2023 #410
|
||||||
|
FeatureFlagsEnum.basic_registration.value: False, # 19.11.2023 #440
|
||||||
|
FeatureFlagsEnum.basic_login.value: False, # 19.11.2023 #440
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs: dict):
|
def __init__(self, **kwargs: dict):
|
||||||
|
@ -50,4 +50,6 @@ type Query {
|
|||||||
technicianConfig: TechnicianConfig
|
technicianConfig: TechnicianConfig
|
||||||
possibleFeatureFlags: [String]
|
possibleFeatureFlags: [String]
|
||||||
discord: Discord
|
discord: Discord
|
||||||
|
|
||||||
|
hasFeatureFlag(flag: String): FeatureFlag
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
|
from cpl_core.configuration import ConfigurationABC
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
|
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||||
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
||||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||||
@ -22,6 +24,7 @@ from bot_data.abc.user_joined_voice_channel_repository_abc import (
|
|||||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||||
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
||||||
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
|
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
|
||||||
|
from bot_data.model.technician_config import TechnicianConfig
|
||||||
from bot_graphql.abc.query_abc import QueryABC
|
from bot_graphql.abc.query_abc import QueryABC
|
||||||
from bot_graphql.filter.achievement_filter import AchievementFilter
|
from bot_graphql.filter.achievement_filter import AchievementFilter
|
||||||
from bot_graphql.filter.auto_role_filter import AutoRoleFilter
|
from bot_graphql.filter.auto_role_filter import AutoRoleFilter
|
||||||
@ -45,6 +48,7 @@ from modules.achievements.achievement_service import AchievementService
|
|||||||
class Query(QueryABC):
|
class Query(QueryABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
config: ConfigurationABC,
|
||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
auto_roles: AutoRoleRepositoryABC,
|
auto_roles: AutoRoleRepositoryABC,
|
||||||
clients: ClientRepositoryABC,
|
clients: ClientRepositoryABC,
|
||||||
@ -65,6 +69,8 @@ class Query(QueryABC):
|
|||||||
):
|
):
|
||||||
QueryABC.__init__(self, "Query")
|
QueryABC.__init__(self, "Query")
|
||||||
|
|
||||||
|
self._config = config
|
||||||
|
|
||||||
self.add_collection("autoRole", lambda *_: auto_roles.get_auto_roles(), AutoRoleFilter)
|
self.add_collection("autoRole", lambda *_: auto_roles.get_auto_roles(), AutoRoleFilter)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"autoRoleRule",
|
"autoRoleRule",
|
||||||
@ -120,3 +126,17 @@ class Query(QueryABC):
|
|||||||
|
|
||||||
self.set_field("possibleFeatureFlags", lambda *_: [e.value for e in FeatureFlagsEnum])
|
self.set_field("possibleFeatureFlags", lambda *_: [e.value for e in FeatureFlagsEnum])
|
||||||
self.set_field("discord", lambda *_: Discord(bot.guilds, List(any).extend(bot.users)))
|
self.set_field("discord", lambda *_: Discord(bot.guilds, List(any).extend(bot.users)))
|
||||||
|
|
||||||
|
self.set_field(
|
||||||
|
"hasFeatureFlag",
|
||||||
|
lambda *_, **kwargs: self._resolve_has_feature_flag(*_, **kwargs),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _resolve_has_feature_flag(self, *_, **kwargs):
|
||||||
|
settings: TechnicianConfig = self._config.get_configuration(TechnicianConfig)
|
||||||
|
if "flag" not in kwargs:
|
||||||
|
return False
|
||||||
|
return {
|
||||||
|
"key": kwargs["flag"],
|
||||||
|
"value": FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(kwargs["flag"])),
|
||||||
|
}
|
||||||
|
110
web/package.json
110
web/package.json
@ -1,56 +1,56 @@
|
|||||||
{
|
{
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "1.2.dev410",
|
"version": "1.2.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"update-version": "ts-node update-version.ts",
|
"update-version": "ts-node update-version.ts",
|
||||||
"prestart": "npm run update-version",
|
"prestart": "npm run update-version",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"prebuild": "npm run update-version",
|
"prebuild": "npm run update-version",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"gv": "echo $npm_package_version",
|
"gv": "echo $npm_package_version",
|
||||||
"predocker-build": "npm run update-version",
|
"predocker-build": "npm run update-version",
|
||||||
"docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .",
|
"docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .",
|
||||||
"docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .",
|
"docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .",
|
||||||
"docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ."
|
"docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ."
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^15.1.4",
|
"@angular/animations": "^15.1.4",
|
||||||
"@angular/common": "^15.1.4",
|
"@angular/common": "^15.1.4",
|
||||||
"@angular/compiler": "^15.1.4",
|
"@angular/compiler": "^15.1.4",
|
||||||
"@angular/core": "^15.1.4",
|
"@angular/core": "^15.1.4",
|
||||||
"@angular/forms": "^15.1.4",
|
"@angular/forms": "^15.1.4",
|
||||||
"@angular/platform-browser": "^15.1.4",
|
"@angular/platform-browser": "^15.1.4",
|
||||||
"@angular/platform-browser-dynamic": "^15.1.4",
|
"@angular/platform-browser-dynamic": "^15.1.4",
|
||||||
"@angular/router": "^15.1.4",
|
"@angular/router": "^15.1.4",
|
||||||
"@auth0/angular-jwt": "^5.1.0",
|
"@auth0/angular-jwt": "^5.1.0",
|
||||||
"@microsoft/signalr": "^6.0.9",
|
"@microsoft/signalr": "^6.0.9",
|
||||||
"@ngx-translate/core": "^14.0.0",
|
"@ngx-translate/core": "^14.0.0",
|
||||||
"@ngx-translate/http-loader": "^7.0.0",
|
"@ngx-translate/http-loader": "^7.0.0",
|
||||||
"@types/socket.io-client": "^3.0.0",
|
"@types/socket.io-client": "^3.0.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"primeicons": "^6.0.1",
|
"primeicons": "^6.0.1",
|
||||||
"primeng": "^15.2.0",
|
"primeng": "^15.2.0",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"socket.io-client": "^4.5.3",
|
"socket.io-client": "^4.5.3",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^15.1.5",
|
"@angular-devkit/build-angular": "^15.1.5",
|
||||||
"@angular/cli": "~15.1.5",
|
"@angular/cli": "~15.1.5",
|
||||||
"@angular/compiler-cli": "^15.1.4",
|
"@angular/compiler-cli": "^15.1.4",
|
||||||
"@types/jasmine": "~4.0.0",
|
"@types/jasmine": "~4.0.0",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"jasmine-core": "~4.1.0",
|
"jasmine-core": "~4.1.0",
|
||||||
"karma": "~6.3.0",
|
"karma": "~6.3.0",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-coverage": "~2.2.0",
|
"karma-coverage": "~2.2.0",
|
||||||
"karma-jasmine": "~5.0.0",
|
"karma-jasmine": "~5.0.0",
|
||||||
"karma-jasmine-html-reporter": "~1.7.0",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "~4.9.5"
|
"typescript": "~4.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,15 @@ export class Queries {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
static hasFeatureFlag = `
|
||||||
|
query HasFeatureFlag($flag: String) {
|
||||||
|
hasFeatureFlag(flag: $flag) {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
static hasServerFeatureFlag = `
|
static hasServerFeatureFlag = `
|
||||||
query HasServerFeatureFlag($filter: ServerFilter, $flag: String) {
|
query HasServerFeatureFlag($filter: ServerFilter, $flag: String) {
|
||||||
servers(filter: $filter) {
|
servers(filter: $filter) {
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
<form [formGroup]="loginForm">
|
<form [formGroup]="loginForm">
|
||||||
<h1>{{'auth.header' | translate}}</h1>
|
<h1>{{'auth.header' | translate}}</h1>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input type="email" pInputText formControlName="email" placeholder="{{'common.email' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
|
<input [disabled]="!basicLoginFeatureFlags" type="email" pInputText formControlName="email"
|
||||||
|
placeholder="{{'common.email' | translate}}"
|
||||||
|
[ngClass]="{ 'invalid-feedback-input': submitted && (
|
||||||
(loginForm.controls.email.errors && loginForm.controls.email.errors['required'] || authUserAtrErrors.email.required) ||
|
(loginForm.controls.email.errors && loginForm.controls.email.errors['required'] || authUserAtrErrors.email.required) ||
|
||||||
(authUserAtrErrors.email.wrongData) ||
|
(authUserAtrErrors.email.wrongData) ||
|
||||||
(authUserAtrErrors.email.notConfirmed)
|
(authUserAtrErrors.email.notConfirmed)
|
||||||
@ -24,7 +26,8 @@
|
|||||||
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
|
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
|
||||||
Remove after update!
|
Remove after update!
|
||||||
-->
|
-->
|
||||||
<p-password formControlName="password" placeholder="{{'auth.login.password' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
|
<p-password [disabled]="!basicLoginFeatureFlags" formControlName="password"
|
||||||
|
placeholder="{{'auth.login.password' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
|
||||||
(loginForm.controls.password.errors && loginForm.controls.password.errors['required'] || authUserAtrErrors.password.required) ||
|
(loginForm.controls.password.errors && loginForm.controls.password.errors['required'] || authUserAtrErrors.password.required) ||
|
||||||
(authUserAtrErrors.password.wrongData)
|
(authUserAtrErrors.password.wrongData)
|
||||||
)}" [toggleMask]="true" [feedback]="false"
|
)}" [toggleMask]="true" [feedback]="false"
|
||||||
@ -39,17 +42,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="login-form-submit">
|
<div class="login-form-submit">
|
||||||
<button pButton label="{{'auth.login.login' | translate}}" class="btn login-form-submit-btn" (click)="login()"
|
<button pButton label="{{'auth.login.login' | translate}}" class="btn login-form-submit-btn" (click)="login()"
|
||||||
[disabled]="loginForm.invalid"></button>
|
[disabled]="loginForm.invalid || !basicLoginFeatureFlags"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form-sub-button-wrapper" *ngIf="!code && !state">
|
<div class="login-form-sub-button-wrapper" *ngIf="!code && !state">
|
||||||
<div class="login-form-sub-btn-wrapper">
|
<div class="login-form-sub-btn-wrapper">
|
||||||
<button pButton label="{{'auth.login.login_with_discord' | translate}}" class="btn login-form-sub-btn" (click)="discordLogin()"></button>
|
<button pButton label="{{'auth.login.login_with_discord' | translate}}" class="btn login-form-sub-btn"
|
||||||
|
(click)="discordLogin()"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form-sub-button-wrapper">
|
<div class="login-form-sub-button-wrapper">
|
||||||
<div class="login-form-sub-btn-wrapper">
|
<div class="login-form-sub-btn-wrapper">
|
||||||
<button pButton label="{{'auth.login.register' | translate}}" class="btn login-form-sub-btn"
|
<button pButton label="{{'auth.login.register' | translate}}" class="btn login-form-sub-btn"
|
||||||
(click)="register()"></button>
|
(click)="register()" [disabled]="!basicRegistrationFeatureFlags"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form-sub-btn-wrapper">
|
<div class="login-form-sub-btn-wrapper">
|
||||||
<button pButton label="{{'auth.login.forgot_password' | translate}}"
|
<button pButton label="{{'auth.login.forgot_password' | translate}}"
|
||||||
|
@ -13,6 +13,7 @@ import { ThemeService } from "src/app/services/theme/theme.service";
|
|||||||
import { throwError } from "rxjs";
|
import { throwError } from "rxjs";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { ConfirmationDialogService } from "../../../../services/confirmation-dialog/confirmation-dialog.service";
|
import { ConfirmationDialogService } from "../../../../services/confirmation-dialog/confirmation-dialog.service";
|
||||||
|
import { GuiService } from "../../../../services/gui/gui.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-login",
|
selector: "app-login",
|
||||||
@ -32,6 +33,8 @@ export class LoginComponent implements OnInit {
|
|||||||
state!: string;
|
state!: string;
|
||||||
user!: AuthUserDTO;
|
user!: AuthUserDTO;
|
||||||
oAuthId!: string;
|
oAuthId!: string;
|
||||||
|
public basicLoginFeatureFlags = false;
|
||||||
|
public basicRegistrationFeatureFlags = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
@ -41,11 +44,19 @@ export class LoginComponent implements OnInit {
|
|||||||
private themeService: ThemeService,
|
private themeService: ThemeService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private confirmDialog: ConfirmationDialogService,
|
private confirmDialog: ConfirmationDialogService,
|
||||||
private translate: TranslateService
|
private translate: TranslateService,
|
||||||
|
private gui: GuiService
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.gui.hasFeatureFlag("BasicLogin").subscribe(flag => {
|
||||||
|
this.basicLoginFeatureFlags = flag.value;
|
||||||
|
});
|
||||||
|
this.gui.hasFeatureFlag("BasicRegistration").subscribe(flag => {
|
||||||
|
this.basicRegistrationFeatureFlags = flag.value;
|
||||||
|
});
|
||||||
|
|
||||||
this.initLoginForm();
|
this.initLoginForm();
|
||||||
this.spinnerService.showSpinner();
|
this.spinnerService.showSpinner();
|
||||||
if (this.authService.isLoggedIn$.value) {
|
if (this.authService.isLoggedIn$.value) {
|
||||||
@ -107,8 +118,8 @@ export class LoginComponent implements OnInit {
|
|||||||
|
|
||||||
initLoginForm(): void {
|
initLoginForm(): void {
|
||||||
this.loginForm = this.formBuilder.group({
|
this.loginForm = this.formBuilder.group({
|
||||||
email: ["", [Validators.required, Validators.email]],
|
email: [{ value: "", disabled: !this.basicLoginFeatureFlags }, [Validators.required, Validators.email]],
|
||||||
password: ["", [Validators.required, Validators.minLength(8)]]
|
password: [{ value: "", disabled: !this.basicLoginFeatureFlags }, [Validators.required, Validators.minLength(8)]]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
<div class="login-form-wrapper register-form-wrapper">
|
<div class="login-form-wrapper register-form-wrapper">
|
||||||
<div class="login-form">
|
<div class="login-form">
|
||||||
<form [formGroup]="loginForm">
|
<form [formGroup]="loginForm">
|
||||||
<h1>sh-edraft.de</h1>
|
<h1>{{'auth.header' | translate}}</h1>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input type="text" pInputText formControlName="firstName" placeholder="{{'auth.register.first_name' | translate}}"
|
<input type="text" pInputText formControlName="firstName"
|
||||||
|
placeholder="{{'auth.register.first_name' | translate}}"
|
||||||
autocomplete="given-name">
|
autocomplete="given-name">
|
||||||
<div *ngIf="submitted" class="invalid-feedback">
|
<div *ngIf="submitted" class="invalid-feedback">
|
||||||
<div
|
<div
|
||||||
@ -15,7 +16,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input type="text" pInputText formControlName="lastName" placeholder="{{'auth.register.last_name' | translate}}"
|
<input type="text" pInputText formControlName="lastName"
|
||||||
|
placeholder="{{'auth.register.last_name' | translate}}"
|
||||||
autocomplete="family-name">
|
autocomplete="family-name">
|
||||||
<div *ngIf="submitted" class="invalid-feedback">
|
<div *ngIf="submitted" class="invalid-feedback">
|
||||||
<div
|
<div
|
||||||
@ -74,12 +76,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="login-form-submit">
|
<div class="login-form-submit">
|
||||||
<button pButton label="{{'auth.register.register' | translate}}" class="btn login-form-submit-btn" (click)="register()"
|
<button pButton label="{{'auth.register.register' | translate}}" class="btn login-form-submit-btn"
|
||||||
|
(click)="register()"
|
||||||
[disabled]="loginForm.invalid"></button>
|
[disabled]="loginForm.invalid"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form-sub-button-wrapper">
|
<div class="login-form-sub-button-wrapper">
|
||||||
<div class="login-form-sub-btn-wrapper">
|
<div class="login-form-sub-btn-wrapper">
|
||||||
<button pButton label="{{'auth.register.login' | translate}}" class="btn login-form-sub-btn" (click)="login()"></button>
|
<button pButton label="{{'auth.register.login' | translate}}" class="btn login-form-sub-btn"
|
||||||
|
(click)="login()"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -12,6 +12,7 @@ import { SpinnerService } from "src/app/services/spinner/spinner.service";
|
|||||||
import { Subject, throwError } from "rxjs";
|
import { Subject, throwError } from "rxjs";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { SettingsService } from "../../../../services/settings/settings.service";
|
import { SettingsService } from "../../../../services/settings/settings.service";
|
||||||
|
import { GuiService } from "../../../../services/gui/gui.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-registration",
|
selector: "app-registration",
|
||||||
@ -46,7 +47,8 @@ export class RegistrationComponent implements OnInit, OnDestroy {
|
|||||||
private spinnerService: SpinnerService,
|
private spinnerService: SpinnerService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private settings: SettingsService
|
private settings: SettingsService,
|
||||||
|
private gui: GuiService
|
||||||
) {
|
) {
|
||||||
this.spinnerService.showSpinner();
|
this.spinnerService.showSpinner();
|
||||||
if (this.authService.isLoggedIn$.value) {
|
if (this.authService.isLoggedIn$.value) {
|
||||||
@ -56,6 +58,14 @@ export class RegistrationComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.gui.hasFeatureFlag("BasicRegistration").subscribe(flag => {
|
||||||
|
if (flag.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.router.navigate(["/auth/login"]);
|
||||||
|
});
|
||||||
|
|
||||||
this.translate.onLangChange.pipe(takeUntil(this.unsubscriber)).subscribe(lang => {
|
this.translate.onLangChange.pipe(takeUntil(this.unsubscriber)).subscribe(lang => {
|
||||||
this.confirmPrivacyString = this.translate.instant("auth.register.confirm_privacy", { url: this.settings.getPrivacyURL() });
|
this.confirmPrivacyString = this.translate.instant("auth.register.confirm_privacy", { url: this.settings.getPrivacyURL() });
|
||||||
});
|
});
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from "@angular/core";
|
||||||
import { Observable, Subscribable } from 'rxjs';
|
import { Observable } from "rxjs";
|
||||||
import { SettingsDTO } from 'src/app/models/config/settings.dto';
|
import { SettingsDTO } from "src/app/models/config/settings.dto";
|
||||||
import { SoftwareVersionDTO } from 'src/app/models/config/software-version.dto';
|
import { SoftwareVersionDTO } from "src/app/models/config/software-version.dto";
|
||||||
import { SettingsService } from '../settings/settings.service';
|
import { SettingsService } from "../settings/settings.service";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: "root"
|
||||||
})
|
})
|
||||||
export class GuiService {
|
export class GuiService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private appsettings: SettingsService,
|
private appsettings: SettingsService,
|
||||||
private http: HttpClient,
|
private http: HttpClient
|
||||||
) { }
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
getApiVersion(): Observable<SoftwareVersionDTO> {
|
getApiVersion(): Observable<SoftwareVersionDTO> {
|
||||||
return this.http.get<SoftwareVersionDTO>(`${this.appsettings.getApiURL()}/api/gui/api-version`, {
|
return this.http.get<SoftwareVersionDTO>(`${this.appsettings.getApiURL()}/api/gui/api-version`, {
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json"
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -26,7 +27,7 @@ export class GuiService {
|
|||||||
getSettings(): Observable<SettingsDTO> {
|
getSettings(): Observable<SettingsDTO> {
|
||||||
return this.http.get<SettingsDTO>(`${this.appsettings.getApiURL()}/api/gui/settings`, {
|
return this.http.get<SettingsDTO>(`${this.appsettings.getApiURL()}/api/gui/settings`, {
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json"
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -34,7 +35,18 @@ export class GuiService {
|
|||||||
sendTestMail(mail: string): Observable<unknown> {
|
sendTestMail(mail: string): Observable<unknown> {
|
||||||
return this.http.post(`${this.appsettings.getApiURL()}/api/gui/send-test-mail/${mail}`, {
|
return this.http.post(`${this.appsettings.getApiURL()}/api/gui/send-test-mail/${mail}`, {
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFeatureFlag(flag: string): Observable<{ key: string, value: boolean }> {
|
||||||
|
return this.http.get<{
|
||||||
|
key: string,
|
||||||
|
value: boolean
|
||||||
|
}>(`${this.appsettings.getApiURL()}/api/gui/has-feature-flag/${flag}`, {
|
||||||
|
headers: new HttpHeaders({
|
||||||
|
"Content-Type": "application/json"
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"WebVersion": {
|
"WebVersion": {
|
||||||
"Major": "1",
|
"Major": "1",
|
||||||
"Minor": "2",
|
"Minor": "2",
|
||||||
"Micro": "dev410"
|
"Micro": "2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user