@mintplayer/ng-spark-auth 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +36 -0
  2. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -0
  3. package/fesm2022/mintplayer-ng-spark-auth-core.mjs +106 -0
  4. package/fesm2022/mintplayer-ng-spark-auth-core.mjs.map +1 -0
  5. package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +58 -0
  6. package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs.map +1 -0
  7. package/fesm2022/mintplayer-ng-spark-auth-guards.mjs +23 -0
  8. package/fesm2022/mintplayer-ng-spark-auth-guards.mjs.map +1 -0
  9. package/fesm2022/mintplayer-ng-spark-auth-interceptors.mjs +26 -0
  10. package/fesm2022/mintplayer-ng-spark-auth-interceptors.mjs.map +1 -0
  11. package/fesm2022/mintplayer-ng-spark-auth-login.mjs +72 -0
  12. package/fesm2022/mintplayer-ng-spark-auth-login.mjs.map +1 -0
  13. package/fesm2022/mintplayer-ng-spark-auth-models.mjs +17 -0
  14. package/fesm2022/mintplayer-ng-spark-auth-models.mjs.map +1 -0
  15. package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +23 -0
  16. package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs.map +1 -0
  17. package/fesm2022/mintplayer-ng-spark-auth-register.mjs +86 -0
  18. package/fesm2022/mintplayer-ng-spark-auth-register.mjs.map +1 -0
  19. package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +90 -0
  20. package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs.map +1 -0
  21. package/fesm2022/mintplayer-ng-spark-auth-routes.mjs +52 -0
  22. package/fesm2022/mintplayer-ng-spark-auth-routes.mjs.map +1 -0
  23. package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +73 -0
  24. package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs.map +1 -0
  25. package/fesm2022/mintplayer-ng-spark-auth.mjs +16 -521
  26. package/fesm2022/mintplayer-ng-spark-auth.mjs.map +1 -1
  27. package/package.json +49 -1
  28. package/types/mintplayer-ng-spark-auth-auth-bar.d.ts +14 -0
  29. package/types/mintplayer-ng-spark-auth-core.d.ts +33 -0
  30. package/types/mintplayer-ng-spark-auth-forgot-password.d.ts +23 -0
  31. package/types/mintplayer-ng-spark-auth-guards.d.ts +5 -0
  32. package/types/mintplayer-ng-spark-auth-interceptors.d.ts +5 -0
  33. package/types/mintplayer-ng-spark-auth-login.d.ts +27 -0
  34. package/types/mintplayer-ng-spark-auth-models.d.ts +33 -0
  35. package/types/mintplayer-ng-spark-auth-pipes.d.ts +11 -0
  36. package/types/mintplayer-ng-spark-auth-register.d.ts +25 -0
  37. package/types/mintplayer-ng-spark-auth-reset-password.d.ts +30 -0
  38. package/types/mintplayer-ng-spark-auth-routes.d.ts +5 -0
  39. package/types/mintplayer-ng-spark-auth-two-factor.d.ts +28 -0
  40. package/types/mintplayer-ng-spark-auth.d.ts +5 -191
@@ -0,0 +1,36 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { Router, RouterLink } from '@angular/router';
4
+ import { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';
5
+ import { SparkAuthService } from '@mintplayer/ng-spark-auth/core';
6
+ import { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';
7
+
8
+ class SparkAuthBarComponent {
9
+ authService = inject(SparkAuthService);
10
+ config = inject(SPARK_AUTH_CONFIG);
11
+ router = inject(Router);
12
+ async onLogout() {
13
+ try {
14
+ await this.authService.logout();
15
+ }
16
+ finally {
17
+ // Always navigate away from the authenticated area, even if the server-side
18
+ // logout call fails (network error, session already expired, etc.). The local
19
+ // session state has been cleared by SparkAuthService regardless.
20
+ this.router.navigateByUrl('/');
21
+ }
22
+ }
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SparkAuthBarComponent, isStandalone: true, selector: "spark-auth-bar", ngImport: i0, template: "@if (authService.isAuthenticated()) {\n <span class=\"me-2\">{{ authService.user()?.userName }}</span>\n <button class=\"btn btn-outline-light btn-sm\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n} @else {\n <a class=\"btn btn-outline-light btn-sm\" [routerLink]=\"config.loginUrl\">{{ 'auth.login' | t }}</a>\n}\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthBarComponent, decorators: [{
27
+ type: Component,
28
+ args: [{ selector: 'spark-auth-bar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, TranslateKeyPipe], template: "@if (authService.isAuthenticated()) {\n <span class=\"me-2\">{{ authService.user()?.userName }}</span>\n <button class=\"btn btn-outline-light btn-sm\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n} @else {\n <a class=\"btn btn-outline-light btn-sm\" [routerLink]=\"config.loginUrl\">{{ 'auth.login' | t }}</a>\n}\n" }]
29
+ }] });
30
+
31
+ /**
32
+ * Generated bundle index. Do not edit.
33
+ */
34
+
35
+ export { SparkAuthBarComponent };
36
+ //# sourceMappingURL=mintplayer-ng-spark-auth-auth-bar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-auth-bar.mjs","sources":["../../auth-bar/src/spark-auth-bar.component.ts","../../auth-bar/src/spark-auth-bar.component.html","../../auth-bar/mintplayer-ng-spark-auth-auth-bar.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { RouterLink, Router } from '@angular/router';\nimport { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';\nimport { SparkAuthService } from '@mintplayer/ng-spark-auth/core';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';\n\n@Component({\n selector: 'spark-auth-bar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterLink, TranslateKeyPipe],\n templateUrl: './spark-auth-bar.component.html',\n})\nexport class SparkAuthBarComponent {\n readonly authService = inject(SparkAuthService);\n readonly config = inject(SPARK_AUTH_CONFIG);\n private readonly router = inject(Router);\n\n async onLogout(): Promise<void> {\n try {\n await this.authService.logout();\n } finally {\n // Always navigate away from the authenticated area, even if the server-side\n // logout call fails (network error, session already expired, etc.). The local\n // session state has been cleared by SparkAuthService regardless.\n this.router.navigateByUrl('/');\n }\n }\n}\n\nexport default SparkAuthBarComponent;\n","@if (authService.isAuthenticated()) {\n <span class=\"me-2\">{{ authService.user()?.userName }}</span>\n <button class=\"btn btn-outline-light btn-sm\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n} @else {\n <a class=\"btn btn-outline-light btn-sm\" [routerLink]=\"config.loginUrl\">{{ 'auth.login' | t }}</a>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;MAaa,qBAAqB,CAAA;AACvB,IAAA,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACtC,IAAA,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC1B,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAExC,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI;AACF,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QACjC;gBAAU;;;;AAIR,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC;QAChC;IACF;uGAdW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECblC,4UAMA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDIY,UAAU,+NAAE,gBAAgB,EAAA,IAAA,EAAA,GAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAG3B,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAPjC,SAAS;+BACE,gBAAgB,EAAA,UAAA,EACd,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAA,QAAA,EAAA,4UAAA,EAAA;;;AEVzC;;AAEG;;;;"}
@@ -0,0 +1,106 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, Injectable } from '@angular/core';
3
+ import { HttpClient } from '@angular/common/http';
4
+ import { firstValueFrom } from 'rxjs';
5
+ import { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';
6
+
7
+ class SparkAuthService {
8
+ http = inject(HttpClient);
9
+ config = inject(SPARK_AUTH_CONFIG);
10
+ currentUser = signal(null, ...(ngDevMode ? [{ debugName: "currentUser" }] : []));
11
+ user = this.currentUser.asReadonly();
12
+ isAuthenticated = computed(() => this.currentUser()?.isAuthenticated === true, ...(ngDevMode ? [{ debugName: "isAuthenticated" }] : []));
13
+ constructor() {
14
+ this.checkAuth();
15
+ }
16
+ async login(email, password) {
17
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/login?useCookies=true`, { email, password }));
18
+ await this.csrfRefresh();
19
+ await this.checkAuth();
20
+ }
21
+ async loginTwoFactor(twoFactorCode, twoFactorRecoveryCode) {
22
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/login?useCookies=true`, {
23
+ twoFactorCode,
24
+ twoFactorRecoveryCode,
25
+ }));
26
+ await this.csrfRefresh();
27
+ await this.checkAuth();
28
+ }
29
+ async register(email, password) {
30
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/register`, { email, password }));
31
+ }
32
+ async logout() {
33
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/logout`, {}));
34
+ await this.csrfRefresh();
35
+ this.currentUser.set(null);
36
+ }
37
+ async csrfRefresh() {
38
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/csrf-refresh`, {}));
39
+ }
40
+ async checkAuth() {
41
+ try {
42
+ const user = await firstValueFrom(this.http.get(`${this.config.apiBasePath}/me`));
43
+ this.currentUser.set(user);
44
+ return user;
45
+ }
46
+ catch {
47
+ this.currentUser.set(null);
48
+ return null;
49
+ }
50
+ }
51
+ async forgotPassword(email) {
52
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/forgotPassword`, { email }));
53
+ }
54
+ async resetPassword(email, resetCode, newPassword) {
55
+ await firstValueFrom(this.http.post(`${this.config.apiBasePath}/resetPassword`, {
56
+ email,
57
+ resetCode,
58
+ newPassword,
59
+ }));
60
+ }
61
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
62
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthService, providedIn: 'root' });
63
+ }
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthService, decorators: [{
65
+ type: Injectable,
66
+ args: [{ providedIn: 'root' }]
67
+ }], ctorParameters: () => [] });
68
+
69
+ /** Read the global language signal set by @mintplayer/ng-spark */
70
+ const currentLanguage = globalThis.__sparkCurrentLanguage ?? signal('en');
71
+ class SparkAuthTranslationService {
72
+ http = inject(HttpClient);
73
+ translationsMap = signal({}, ...(ngDevMode ? [{ debugName: "translationsMap" }] : []));
74
+ constructor() {
75
+ this.loadTranslations();
76
+ }
77
+ async loadTranslations() {
78
+ try {
79
+ const t = await firstValueFrom(this.http.get('/spark/translations'));
80
+ this.translationsMap.set(t);
81
+ }
82
+ catch {
83
+ // Translations failed to load; keys will be shown as-is
84
+ }
85
+ }
86
+ t(key) {
87
+ const ts = this.translationsMap()[key];
88
+ if (!ts)
89
+ return key;
90
+ const lang = currentLanguage();
91
+ return ts[lang] ?? ts['en'] ?? Object.values(ts)[0] ?? key;
92
+ }
93
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthTranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
94
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthTranslationService, providedIn: 'root' });
95
+ }
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkAuthTranslationService, decorators: [{
97
+ type: Injectable,
98
+ args: [{ providedIn: 'root' }]
99
+ }], ctorParameters: () => [] });
100
+
101
+ /**
102
+ * Generated bundle index. Do not edit.
103
+ */
104
+
105
+ export { SparkAuthService, SparkAuthTranslationService };
106
+ //# sourceMappingURL=mintplayer-ng-spark-auth-core.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-core.mjs","sources":["../../core/src/spark-auth.service.ts","../../core/src/spark-auth-translation.service.ts","../../core/mintplayer-ng-spark-auth-core.ts"],"sourcesContent":["import { computed, inject, Injectable, signal } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthUser, SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';\n\n@Injectable({ providedIn: 'root' })\nexport class SparkAuthService {\n private readonly http = inject(HttpClient);\n private readonly config = inject(SPARK_AUTH_CONFIG);\n\n private readonly currentUser = signal<AuthUser | null>(null);\n\n readonly user = this.currentUser.asReadonly();\n readonly isAuthenticated = computed(() => this.currentUser()?.isAuthenticated === true);\n\n constructor() {\n this.checkAuth();\n }\n\n async login(email: string, password: string): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/login?useCookies=true`, { email, password }));\n await this.csrfRefresh();\n await this.checkAuth();\n }\n\n async loginTwoFactor(twoFactorCode: string, twoFactorRecoveryCode?: string): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/login?useCookies=true`, {\n twoFactorCode,\n twoFactorRecoveryCode,\n }));\n await this.csrfRefresh();\n await this.checkAuth();\n }\n\n async register(email: string, password: string): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/register`, { email, password }));\n }\n\n async logout(): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/logout`, {}));\n await this.csrfRefresh();\n this.currentUser.set(null);\n }\n\n async csrfRefresh(): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/csrf-refresh`, {}));\n }\n\n async checkAuth(): Promise<AuthUser | null> {\n try {\n const user = await firstValueFrom(this.http.get<AuthUser>(`${this.config.apiBasePath}/me`));\n this.currentUser.set(user);\n return user;\n } catch {\n this.currentUser.set(null);\n return null;\n }\n }\n\n async forgotPassword(email: string): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/forgotPassword`, { email }));\n }\n\n async resetPassword(email: string, resetCode: string, newPassword: string): Promise<void> {\n await firstValueFrom(this.http.post<void>(`${this.config.apiBasePath}/resetPassword`, {\n email,\n resetCode,\n newPassword,\n }));\n }\n}\n","import { Injectable, inject, signal, type Signal } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { firstValueFrom } from 'rxjs';\n\ntype TranslatedString = Record<string, string>;\n\n/** Read the global language signal set by @mintplayer/ng-spark */\nconst currentLanguage: Signal<string> =\n (globalThis as any).__sparkCurrentLanguage ?? signal('en');\n\n@Injectable({ providedIn: 'root' })\nexport class SparkAuthTranslationService {\n private readonly http = inject(HttpClient);\n private readonly translationsMap = signal<Record<string, TranslatedString>>({});\n\n constructor() {\n this.loadTranslations();\n }\n\n private async loadTranslations(): Promise<void> {\n try {\n const t = await firstValueFrom(this.http.get<Record<string, TranslatedString>>('/spark/translations'));\n this.translationsMap.set(t);\n } catch {\n // Translations failed to load; keys will be shown as-is\n }\n }\n\n t(key: string): string {\n const ts = this.translationsMap()[key];\n if (!ts) return key;\n const lang = currentLanguage();\n return ts[lang] ?? ts['en'] ?? Object.values(ts)[0] ?? key;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
4
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
5
+ import { RouterLink } from '@angular/router';
6
+ import { Color } from '@mintplayer/ng-bootstrap';
7
+ import { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';
8
+ import { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';
9
+ import { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';
10
+ import { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';
11
+ import { SPARK_AUTH_ROUTE_PATHS } from '@mintplayer/ng-spark-auth/models';
12
+ import { SparkAuthService, SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';
13
+ import { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';
14
+
15
+ class SparkForgotPasswordComponent {
16
+ fb = inject(FormBuilder);
17
+ authService = inject(SparkAuthService);
18
+ translation = inject(SparkAuthTranslationService);
19
+ routePaths = inject(SPARK_AUTH_ROUTE_PATHS);
20
+ colors = Color;
21
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
22
+ errorMessage = signal('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
23
+ successMessage = signal('', ...(ngDevMode ? [{ debugName: "successMessage" }] : []));
24
+ form = this.fb.group({
25
+ email: ['', [Validators.required, Validators.email]],
26
+ });
27
+ async onSubmit() {
28
+ if (this.form.invalid) {
29
+ this.form.markAllAsTouched();
30
+ return;
31
+ }
32
+ this.loading.set(true);
33
+ this.errorMessage.set('');
34
+ this.successMessage.set('');
35
+ const { email } = this.form.value;
36
+ try {
37
+ await this.authService.forgotPassword(email);
38
+ }
39
+ catch {
40
+ // Don't reveal whether the email exists
41
+ }
42
+ this.successMessage.set(this.translation.t('auth.forgotPasswordSuccess'));
43
+ this.loading.set(false);
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkForgotPasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SparkForgotPasswordComponent, isStandalone: true, selector: "spark-forgot-password", ngImport: i0, template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.forgotPasswordTitle' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (successMessage()) {\n <bs-alert [type]=\"colors.success\" class=\"mb-3\">{{ successMessage() }}</bs-alert>\n }\n\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n @if (!successMessage()) {\n <p class=\"text-muted mb-3\">\n {{ 'auth.forgotPasswordDescription' | t }}\n </p>\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"email\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n />\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.sendResetLink' | t }}\n </button>\n </form>\n </bs-form>\n }\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.login\">{{ 'auth.backToLogin' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsCardComponent, selector: "bs-card", inputs: ["rounded"] }, { kind: "component", type: BsCardHeaderComponent, selector: "bs-card-header", inputs: ["noPadding"] }, { kind: "component", type: BsFormComponent, selector: "bs-form", inputs: ["action", "method"], outputs: ["submitted"] }, { kind: "directive", type: BsFormControlDirective, selector: "bs-form input:not(.no-form-control), bs-form textarea:not(.no-form-control)" }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkForgotPasswordComponent, decorators: [{
49
+ type: Component,
50
+ args: [{ selector: 'spark-forgot-password', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, RouterLink, BsAlertComponent, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsSpinnerComponent, TranslateKeyPipe], template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.forgotPasswordTitle' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (successMessage()) {\n <bs-alert [type]=\"colors.success\" class=\"mb-3\">{{ successMessage() }}</bs-alert>\n }\n\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n @if (!successMessage()) {\n <p class=\"text-muted mb-3\">\n {{ 'auth.forgotPasswordDescription' | t }}\n </p>\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"email\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n />\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.sendResetLink' | t }}\n </button>\n </form>\n </bs-form>\n }\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.login\">{{ 'auth.backToLogin' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n" }]
51
+ }] });
52
+
53
+ /**
54
+ * Generated bundle index. Do not edit.
55
+ */
56
+
57
+ export { SparkForgotPasswordComponent };
58
+ //# sourceMappingURL=mintplayer-ng-spark-auth-forgot-password.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-forgot-password.mjs","sources":["../../forgot-password/src/spark-forgot-password.component.ts","../../forgot-password/src/spark-forgot-password.component.html","../../forgot-password/mintplayer-ng-spark-auth-forgot-password.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';\nimport { RouterLink } from '@angular/router';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';\nimport { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SPARK_AUTH_ROUTE_PATHS } from '@mintplayer/ng-spark-auth/models';\nimport { SparkAuthService, SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';\n\n@Component({\n selector: 'spark-forgot-password',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ReactiveFormsModule, RouterLink, BsAlertComponent, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsSpinnerComponent, TranslateKeyPipe],\n templateUrl: './spark-forgot-password.component.html',\n})\nexport class SparkForgotPasswordComponent {\n private readonly fb = inject(FormBuilder);\n private readonly authService = inject(SparkAuthService);\n private readonly translation = inject(SparkAuthTranslationService);\n readonly routePaths = inject(SPARK_AUTH_ROUTE_PATHS);\n\n colors = Color;\n readonly loading = signal(false);\n readonly errorMessage = signal('');\n readonly successMessage = signal('');\n\n readonly form = this.fb.group({\n email: ['', [Validators.required, Validators.email]],\n });\n\n async onSubmit(): Promise<void> {\n if (this.form.invalid) {\n this.form.markAllAsTouched();\n return;\n }\n\n this.loading.set(true);\n this.errorMessage.set('');\n this.successMessage.set('');\n\n const { email } = this.form.value;\n\n try {\n await this.authService.forgotPassword(email!);\n } catch {\n // Don't reveal whether the email exists\n }\n this.successMessage.set(this.translation.t('auth.forgotPasswordSuccess'));\n this.loading.set(false);\n }\n}\n\nexport default SparkForgotPasswordComponent;\n","<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.forgotPasswordTitle' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (successMessage()) {\n <bs-alert [type]=\"colors.success\" class=\"mb-3\">{{ successMessage() }}</bs-alert>\n }\n\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n @if (!successMessage()) {\n <p class=\"text-muted mb-3\">\n {{ 'auth.forgotPasswordDescription' | t }}\n </p>\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"email\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n />\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.sendResetLink' | t }}\n </button>\n </form>\n </bs-form>\n }\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.login\">{{ 'auth.backToLogin' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { inject } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+ import { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';
4
+ import { SparkAuthService } from '@mintplayer/ng-spark-auth/core';
5
+
6
+ const sparkAuthGuard = (route, state) => {
7
+ const authService = inject(SparkAuthService);
8
+ const router = inject(Router);
9
+ const config = inject(SPARK_AUTH_CONFIG);
10
+ if (authService.isAuthenticated()) {
11
+ return true;
12
+ }
13
+ return router.createUrlTree([config.loginUrl], {
14
+ queryParams: { returnUrl: state.url },
15
+ });
16
+ };
17
+
18
+ /**
19
+ * Generated bundle index. Do not edit.
20
+ */
21
+
22
+ export { sparkAuthGuard };
23
+ //# sourceMappingURL=mintplayer-ng-spark-auth-guards.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-guards.mjs","sources":["../../guards/src/spark-auth.guard.ts","../../guards/mintplayer-ng-spark-auth-guards.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';\nimport { SparkAuthService } from '@mintplayer/ng-spark-auth/core';\n\nexport const sparkAuthGuard: CanActivateFn = (route, state) => {\n const authService = inject(SparkAuthService);\n const router = inject(Router);\n const config = inject(SPARK_AUTH_CONFIG);\n\n if (authService.isAuthenticated()) {\n return true;\n }\n\n return router.createUrlTree([config.loginUrl], {\n queryParams: { returnUrl: state.url },\n });\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAKa,cAAc,GAAkB,CAAC,KAAK,EAAE,KAAK,KAAI;AAC5D,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC5C,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAExC,IAAA,IAAI,WAAW,CAAC,eAAe,EAAE,EAAE;AACjC,QAAA,OAAO,IAAI;IACb;IAEA,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AAC7C,QAAA,WAAW,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE;AACtC,KAAA,CAAC;AACJ;;ACjBA;;AAEG;;;;"}
@@ -0,0 +1,26 @@
1
+ import { inject } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+ import { tap } from 'rxjs';
4
+ import { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';
5
+
6
+ const sparkAuthInterceptor = (req, next) => {
7
+ const config = inject(SPARK_AUTH_CONFIG);
8
+ const router = inject(Router);
9
+ return next(req).pipe(tap({
10
+ error: (error) => {
11
+ if (error.status === 401 &&
12
+ !req.url.startsWith(config.apiBasePath)) {
13
+ router.navigate([config.loginUrl], {
14
+ queryParams: { returnUrl: router.url },
15
+ });
16
+ }
17
+ },
18
+ }));
19
+ };
20
+
21
+ /**
22
+ * Generated bundle index. Do not edit.
23
+ */
24
+
25
+ export { sparkAuthInterceptor };
26
+ //# sourceMappingURL=mintplayer-ng-spark-auth-interceptors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-interceptors.mjs","sources":["../../interceptors/src/spark-auth.interceptor.ts","../../interceptors/mintplayer-ng-spark-auth-interceptors.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { HttpInterceptorFn } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { tap } from 'rxjs';\nimport { SPARK_AUTH_CONFIG } from '@mintplayer/ng-spark-auth/models';\n\nexport const sparkAuthInterceptor: HttpInterceptorFn = (req, next) => {\n const config = inject(SPARK_AUTH_CONFIG);\n const router = inject(Router);\n\n return next(req).pipe(\n tap({\n error: (error) => {\n if (\n error.status === 401 &&\n !req.url.startsWith(config.apiBasePath)\n ) {\n router.navigate([config.loginUrl], {\n queryParams: { returnUrl: router.url },\n });\n }\n },\n }),\n );\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAMa,oBAAoB,GAAsB,CAAC,GAAG,EAAE,IAAI,KAAI;AACnE,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;AACxC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CACnB,GAAG,CAAC;AACF,QAAA,KAAK,EAAE,CAAC,KAAK,KAAI;AACf,YAAA,IACE,KAAK,CAAC,MAAM,KAAK,GAAG;gBACpB,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,EACvC;gBACA,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACjC,oBAAA,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE;AACvC,iBAAA,CAAC;YACJ;QACF,CAAC;AACF,KAAA,CAAC,CACH;AACH;;ACxBA;;AAEG;;;;"}
@@ -0,0 +1,72 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
4
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
5
+ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
6
+ import { HttpErrorResponse } from '@angular/common/http';
7
+ import { Color } from '@mintplayer/ng-bootstrap';
8
+ import { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';
9
+ import { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';
10
+ import { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';
11
+ import { BsToggleButtonComponent } from '@mintplayer/ng-bootstrap/toggle-button';
12
+ import { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';
13
+ import { SPARK_AUTH_CONFIG, SPARK_AUTH_ROUTE_PATHS } from '@mintplayer/ng-spark-auth/models';
14
+ import { SparkAuthService, SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';
15
+ import { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';
16
+
17
+ class SparkLoginComponent {
18
+ fb = inject(FormBuilder);
19
+ authService = inject(SparkAuthService);
20
+ router = inject(Router);
21
+ route = inject(ActivatedRoute);
22
+ config = inject(SPARK_AUTH_CONFIG);
23
+ translation = inject(SparkAuthTranslationService);
24
+ routePaths = inject(SPARK_AUTH_ROUTE_PATHS);
25
+ colors = Color;
26
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
27
+ errorMessage = signal('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
28
+ form = this.fb.group({
29
+ email: ['', Validators.required],
30
+ password: ['', Validators.required],
31
+ rememberMe: [false],
32
+ });
33
+ async onSubmit() {
34
+ if (this.form.invalid)
35
+ return;
36
+ this.loading.set(true);
37
+ this.errorMessage.set('');
38
+ const { email, password } = this.form.value;
39
+ try {
40
+ await this.authService.login(email, password);
41
+ const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl');
42
+ this.router.navigateByUrl(returnUrl || this.config.defaultRedirectUrl);
43
+ }
44
+ catch (err) {
45
+ if (err instanceof HttpErrorResponse && err.status === 401 && err.error?.detail === 'RequiresTwoFactor') {
46
+ const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl');
47
+ this.router.navigate([this.routePaths.twoFactor], {
48
+ queryParams: returnUrl ? { returnUrl } : undefined,
49
+ });
50
+ }
51
+ else {
52
+ this.errorMessage.set(this.translation.t('auth.invalidCredentials'));
53
+ }
54
+ }
55
+ finally {
56
+ this.loading.set(false);
57
+ }
58
+ }
59
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkLoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
60
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SparkLoginComponent, isStandalone: true, selector: "spark-login", ngImport: i0, template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.login' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"text\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"username\"\n />\n </div>\n\n <div class=\"mb-3\">\n <label for=\"password\" class=\"form-label\">{{ 'auth.password' | t }}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div class=\"mb-3\">\n <bs-toggle-button [type]=\"'checkbox'\" formControlName=\"rememberMe\" [name]=\"'rememberMe'\">{{ 'auth.rememberMe' | t }}</bs-toggle-button>\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.login' | t }}\n </button>\n </form>\n </bs-form>\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.register\">{{ 'auth.createAccount' | t }}</a>\n </div>\n <div class=\"mt-2 text-center\">\n <a [routerLink]=\"routePaths.forgotPassword\">{{ 'auth.forgotPassword' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsCardComponent, selector: "bs-card", inputs: ["rounded"] }, { kind: "component", type: BsCardHeaderComponent, selector: "bs-card-header", inputs: ["noPadding"] }, { kind: "component", type: BsFormComponent, selector: "bs-form", inputs: ["action", "method"], outputs: ["submitted"] }, { kind: "directive", type: BsFormControlDirective, selector: "bs-form input:not(.no-form-control), bs-form textarea:not(.no-form-control)" }, { kind: "component", type: BsToggleButtonComponent, selector: "bs-toggle-button", inputs: ["type", "isToggled", "name", "value", "group"], outputs: ["isToggledChange"] }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
61
+ }
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkLoginComponent, decorators: [{
63
+ type: Component,
64
+ args: [{ selector: 'spark-login', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, RouterLink, BsAlertComponent, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsToggleButtonComponent, BsSpinnerComponent, TranslateKeyPipe], template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.login' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"text\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"username\"\n />\n </div>\n\n <div class=\"mb-3\">\n <label for=\"password\" class=\"form-label\">{{ 'auth.password' | t }}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div class=\"mb-3\">\n <bs-toggle-button [type]=\"'checkbox'\" formControlName=\"rememberMe\" [name]=\"'rememberMe'\">{{ 'auth.rememberMe' | t }}</bs-toggle-button>\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.login' | t }}\n </button>\n </form>\n </bs-form>\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.register\">{{ 'auth.createAccount' | t }}</a>\n </div>\n <div class=\"mt-2 text-center\">\n <a [routerLink]=\"routePaths.forgotPassword\">{{ 'auth.forgotPassword' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n" }]
65
+ }] });
66
+
67
+ /**
68
+ * Generated bundle index. Do not edit.
69
+ */
70
+
71
+ export { SparkLoginComponent };
72
+ //# sourceMappingURL=mintplayer-ng-spark-auth-login.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-login.mjs","sources":["../../login/src/spark-login.component.ts","../../login/src/spark-login.component.html","../../login/mintplayer-ng-spark-auth-login.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';\nimport { RouterLink, ActivatedRoute, Router } from '@angular/router';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';\nimport { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';\nimport { BsToggleButtonComponent } from '@mintplayer/ng-bootstrap/toggle-button';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SPARK_AUTH_CONFIG, SPARK_AUTH_ROUTE_PATHS } from '@mintplayer/ng-spark-auth/models';\nimport { SparkAuthService, SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';\n\n@Component({\n selector: 'spark-login',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ReactiveFormsModule, RouterLink, BsAlertComponent, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsToggleButtonComponent, BsSpinnerComponent, TranslateKeyPipe],\n templateUrl: './spark-login.component.html',\n})\nexport class SparkLoginComponent {\n private readonly fb = inject(FormBuilder);\n private readonly authService = inject(SparkAuthService);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly config = inject(SPARK_AUTH_CONFIG);\n private readonly translation = inject(SparkAuthTranslationService);\n readonly routePaths = inject(SPARK_AUTH_ROUTE_PATHS);\n\n colors = Color;\n readonly loading = signal(false);\n readonly errorMessage = signal('');\n\n readonly form = this.fb.group({\n email: ['', Validators.required],\n password: ['', Validators.required],\n rememberMe: [false],\n });\n\n async onSubmit(): Promise<void> {\n if (this.form.invalid) return;\n\n this.loading.set(true);\n this.errorMessage.set('');\n\n const { email, password } = this.form.value;\n\n try {\n await this.authService.login(email!, password!);\n const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl');\n this.router.navigateByUrl(returnUrl || this.config.defaultRedirectUrl);\n } catch (err: any) {\n if (err instanceof HttpErrorResponse && err.status === 401 && err.error?.detail === 'RequiresTwoFactor') {\n const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl');\n this.router.navigate([this.routePaths.twoFactor], {\n queryParams: returnUrl ? { returnUrl } : undefined,\n });\n } else {\n this.errorMessage.set(this.translation.t('auth.invalidCredentials'));\n }\n } finally {\n this.loading.set(false);\n }\n }\n}\n\nexport default SparkLoginComponent;\n","<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.login' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"text\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"username\"\n />\n </div>\n\n <div class=\"mb-3\">\n <label for=\"password\" class=\"form-label\">{{ 'auth.password' | t }}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div class=\"mb-3\">\n <bs-toggle-button [type]=\"'checkbox'\" formControlName=\"rememberMe\" [name]=\"'rememberMe'\">{{ 'auth.rememberMe' | t }}</bs-toggle-button>\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.login' | t }}\n </button>\n </form>\n </bs-form>\n\n <div class=\"mt-3 text-center\">\n <a [routerLink]=\"routePaths.register\">{{ 'auth.createAccount' | t }}</a>\n </div>\n <div class=\"mt-2 text-center\">\n <a [routerLink]=\"routePaths.forgotPassword\">{{ 'auth.forgotPassword' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;MAqBa,mBAAmB,CAAA;AACb,IAAA,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AACxB,IAAA,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACtC,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAC9B,IAAA,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAClC,IAAA,WAAW,GAAG,MAAM,CAAC,2BAA2B,CAAC;AACzD,IAAA,UAAU,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAEpD,MAAM,GAAG,KAAK;AACL,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAC;AACvB,IAAA,YAAY,GAAG,MAAM,CAAC,EAAE,wDAAC;AAEzB,IAAA,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;AAC5B,QAAA,KAAK,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AAChC,QAAA,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;QACnC,UAAU,EAAE,CAAC,KAAK,CAAC;AACpB,KAAA,CAAC;AAEF,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAEvB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QAEzB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK;AAE3C,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAM,EAAE,QAAS,CAAC;AAC/C,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC;AACpE,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;QACxE;QAAE,OAAO,GAAQ,EAAE;AACjB,YAAA,IAAI,GAAG,YAAY,iBAAiB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,EAAE;AACvG,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC;AACpE,gBAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;oBAChD,WAAW,EAAE,SAAS,GAAG,EAAE,SAAS,EAAE,GAAG,SAAS;AACnD,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;YACtE;QACF;gBAAU;AACR,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB;IACF;uGA3CW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrBhC,k6DA0DA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDxCY,mBAAmB,y9BAAE,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,eAAe,yEAAE,qBAAqB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,eAAe,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,sBAAsB,wHAAE,uBAAuB,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,kBAAkB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,IAAA,EAAA,GAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGhM,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAP/B,SAAS;+BACE,aAAa,EAAA,UAAA,EACX,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,EAAA,QAAA,EAAA,k6DAAA,EAAA;;;AElB9M;;AAEG;;;;"}
@@ -0,0 +1,17 @@
1
+ import { InjectionToken } from '@angular/core';
2
+
3
+ const SPARK_AUTH_CONFIG = new InjectionToken('SPARK_AUTH_CONFIG');
4
+ const defaultSparkAuthConfig = {
5
+ apiBasePath: '/spark/auth',
6
+ defaultRedirectUrl: '/',
7
+ loginUrl: '/login',
8
+ };
9
+
10
+ const SPARK_AUTH_ROUTE_PATHS = new InjectionToken('SPARK_AUTH_ROUTE_PATHS');
11
+
12
+ /**
13
+ * Generated bundle index. Do not edit.
14
+ */
15
+
16
+ export { SPARK_AUTH_CONFIG, SPARK_AUTH_ROUTE_PATHS, defaultSparkAuthConfig };
17
+ //# sourceMappingURL=mintplayer-ng-spark-auth-models.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-models.mjs","sources":["../../models/src/auth-config.ts","../../models/src/auth-route-config.ts","../../models/mintplayer-ng-spark-auth-models.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface SparkAuthConfig {\n apiBasePath: string;\n defaultRedirectUrl: string;\n loginUrl: string;\n}\n\nexport const SPARK_AUTH_CONFIG = new InjectionToken<SparkAuthConfig>('SPARK_AUTH_CONFIG');\n\nexport const defaultSparkAuthConfig: SparkAuthConfig = {\n apiBasePath: '/spark/auth',\n defaultRedirectUrl: '/',\n loginUrl: '/login',\n};\n","import { InjectionToken, Type } from '@angular/core';\n\nexport type SparkAuthRouteEntry = string | { path: string; component?: Type<unknown> };\n\nexport interface SparkAuthRouteConfig {\n login?: SparkAuthRouteEntry;\n twoFactor?: SparkAuthRouteEntry;\n register?: SparkAuthRouteEntry;\n forgotPassword?: SparkAuthRouteEntry;\n resetPassword?: SparkAuthRouteEntry;\n}\n\nexport type SparkAuthRoutePaths = Required<Record<keyof SparkAuthRouteConfig, string>>;\n\nexport const SPARK_AUTH_ROUTE_PATHS = new InjectionToken<SparkAuthRoutePaths>('SPARK_AUTH_ROUTE_PATHS');\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;MAQa,iBAAiB,GAAG,IAAI,cAAc,CAAkB,mBAAmB;AAEjF,MAAM,sBAAsB,GAAoB;AACrD,IAAA,WAAW,EAAE,aAAa;AAC1B,IAAA,kBAAkB,EAAE,GAAG;AACvB,IAAA,QAAQ,EAAE,QAAQ;;;MCCP,sBAAsB,GAAG,IAAI,cAAc,CAAsB,wBAAwB;;ACdtG;;AAEG;;;;"}
@@ -0,0 +1,23 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Pipe } from '@angular/core';
3
+ import { SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';
4
+
5
+ class TranslateKeyPipe {
6
+ translation = inject(SparkAuthTranslationService);
7
+ transform(key) {
8
+ return this.translation.t(key);
9
+ }
10
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: TranslateKeyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
11
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: TranslateKeyPipe, isStandalone: true, name: "t", pure: false });
12
+ }
13
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: TranslateKeyPipe, decorators: [{
14
+ type: Pipe,
15
+ args: [{ name: 't', pure: false, standalone: true }]
16
+ }] });
17
+
18
+ /**
19
+ * Generated bundle index. Do not edit.
20
+ */
21
+
22
+ export { TranslateKeyPipe };
23
+ //# sourceMappingURL=mintplayer-ng-spark-auth-pipes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-pipes.mjs","sources":["../../pipes/src/translate-key.pipe.ts","../../pipes/mintplayer-ng-spark-auth-pipes.ts"],"sourcesContent":["import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';\n\n@Pipe({ name: 't', pure: false, standalone: true })\nexport class TranslateKeyPipe implements PipeTransform {\n private readonly translation = inject(SparkAuthTranslationService);\n\n transform(key: string): string {\n return this.translation.t(key);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAIa,gBAAgB,CAAA;AACV,IAAA,WAAW,GAAG,MAAM,CAAC,2BAA2B,CAAC;AAElE,IAAA,SAAS,CAAC,GAAW,EAAA;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;IAChC;uGALW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA;qGAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,EAAA,KAAA,EAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,IAAI;mBAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;;;ACHlD;;AAEG;;;;"}
@@ -0,0 +1,86 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
4
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
5
+ import { Router, RouterLink } from '@angular/router';
6
+ import { HttpErrorResponse } from '@angular/common/http';
7
+ import { Color } from '@mintplayer/ng-bootstrap';
8
+ import { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';
9
+ import { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';
10
+ import { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';
11
+ import { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';
12
+ import { SPARK_AUTH_ROUTE_PATHS } from '@mintplayer/ng-spark-auth/models';
13
+ import { SparkAuthService, SparkAuthTranslationService } from '@mintplayer/ng-spark-auth/core';
14
+ import { TranslateKeyPipe } from '@mintplayer/ng-spark-auth/pipes';
15
+
16
+ function passwordMatchValidator(control) {
17
+ const password = control.get('password');
18
+ const confirmPassword = control.get('confirmPassword');
19
+ if (password && confirmPassword && password.value !== confirmPassword.value) {
20
+ return { passwordMismatch: true };
21
+ }
22
+ return null;
23
+ }
24
+ class SparkRegisterComponent {
25
+ fb = inject(FormBuilder);
26
+ authService = inject(SparkAuthService);
27
+ router = inject(Router);
28
+ translation = inject(SparkAuthTranslationService);
29
+ routePaths = inject(SPARK_AUTH_ROUTE_PATHS);
30
+ colors = Color;
31
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
32
+ errorMessage = signal('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
33
+ form = this.fb.group({
34
+ email: ['', [Validators.required, Validators.email]],
35
+ password: ['', Validators.required],
36
+ confirmPassword: ['', Validators.required],
37
+ }, { validators: passwordMatchValidator });
38
+ async onSubmit() {
39
+ if (this.form.invalid) {
40
+ this.form.markAllAsTouched();
41
+ return;
42
+ }
43
+ this.loading.set(true);
44
+ this.errorMessage.set('');
45
+ const { email, password } = this.form.value;
46
+ try {
47
+ await this.authService.register(email, password);
48
+ this.router.navigate([this.routePaths.login], {
49
+ queryParams: { registered: 'true' },
50
+ });
51
+ }
52
+ catch (err) {
53
+ if (err instanceof HttpErrorResponse) {
54
+ if (err.status === 400 && err.error?.errors) {
55
+ const messages = [].concat(...Object.values(err.error.errors));
56
+ this.errorMessage.set(messages.join(' '));
57
+ }
58
+ else if (err.error?.detail) {
59
+ this.errorMessage.set(err.error.detail);
60
+ }
61
+ else {
62
+ this.errorMessage.set(this.translation.t('auth.registrationFailed'));
63
+ }
64
+ }
65
+ else {
66
+ this.errorMessage.set(this.translation.t('auth.registrationFailed'));
67
+ }
68
+ }
69
+ finally {
70
+ this.loading.set(false);
71
+ }
72
+ }
73
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkRegisterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
74
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SparkRegisterComponent, isStandalone: true, selector: "spark-register", ngImport: i0, template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.register' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"email\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n />\n @if (form.get('email')?.touched && form.get('email')?.hasError('email')) {\n <div class=\"text-danger mt-1\">{{ 'auth.invalidEmail' | t }}</div>\n }\n </div>\n\n <div class=\"mb-3\">\n <label for=\"password\" class=\"form-label\">{{ 'auth.password' | t }}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </div>\n\n <div class=\"mb-3\">\n <label for=\"confirmPassword\" class=\"form-label\">{{ 'auth.confirmPassword' | t }}</label>\n <input\n type=\"password\"\n id=\"confirmPassword\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\"\n />\n @if (form.touched && form.hasError('passwordMismatch')) {\n <div class=\"text-danger mt-1\">{{ 'auth.passwordMismatch' | t }}</div>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.register' | t }}\n </button>\n </form>\n </bs-form>\n\n <div class=\"mt-3 text-center\">\n <span>{{ 'auth.alreadyHaveAccount' | t }} </span>\n <a [routerLink]=\"routePaths.login\">{{ 'auth.login' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsCardComponent, selector: "bs-card", inputs: ["rounded"] }, { kind: "component", type: BsCardHeaderComponent, selector: "bs-card-header", inputs: ["noPadding"] }, { kind: "component", type: BsFormComponent, selector: "bs-form", inputs: ["action", "method"], outputs: ["submitted"] }, { kind: "directive", type: BsFormControlDirective, selector: "bs-form input:not(.no-form-control), bs-form textarea:not(.no-form-control)" }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
75
+ }
76
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkRegisterComponent, decorators: [{
77
+ type: Component,
78
+ args: [{ selector: 'spark-register', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ReactiveFormsModule, RouterLink, BsAlertComponent, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsSpinnerComponent, TranslateKeyPipe], template: "<div class=\"d-flex justify-content-center\">\n <bs-card style=\"width: 100%; max-width: 400px;\">\n <bs-card-header>\n <h3 class=\"mb-0 text-center\">{{ 'auth.register' | t }}</h3>\n </bs-card-header>\n <div class=\"p-4\">\n @if (errorMessage()) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">{{ errorMessage() }}</bs-alert>\n }\n\n <bs-form>\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3\">\n <label for=\"email\" class=\"form-label\">{{ 'auth.email' | t }}</label>\n <input\n type=\"email\"\n id=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n />\n @if (form.get('email')?.touched && form.get('email')?.hasError('email')) {\n <div class=\"text-danger mt-1\">{{ 'auth.invalidEmail' | t }}</div>\n }\n </div>\n\n <div class=\"mb-3\">\n <label for=\"password\" class=\"form-label\">{{ 'auth.password' | t }}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </div>\n\n <div class=\"mb-3\">\n <label for=\"confirmPassword\" class=\"form-label\">{{ 'auth.confirmPassword' | t }}</label>\n <input\n type=\"password\"\n id=\"confirmPassword\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\"\n />\n @if (form.touched && form.hasError('passwordMismatch')) {\n <div class=\"text-danger mt-1\">{{ 'auth.passwordMismatch' | t }}</div>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"btn btn-primary w-100\"\n [disabled]=\"loading()\"\n >\n @if (loading()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'auth.register' | t }}\n </button>\n </form>\n </bs-form>\n\n <div class=\"mt-3 text-center\">\n <span>{{ 'auth.alreadyHaveAccount' | t }} </span>\n <a [routerLink]=\"routePaths.login\">{{ 'auth.login' | t }}</a>\n </div>\n </div>\n </bs-card>\n</div>\n" }]
79
+ }] });
80
+
81
+ /**
82
+ * Generated bundle index. Do not edit.
83
+ */
84
+
85
+ export { SparkRegisterComponent };
86
+ //# sourceMappingURL=mintplayer-ng-spark-auth-register.mjs.map