@processpuzzle/auth 0.0.5 → 0.1.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.
- package/README.md +0 -9
- package/assets/auth/silent-check-sso.html +12 -0
- package/assets/i18n/auth/en.json +3 -3
- package/fesm2022/processpuzzle-auth-domain.mjs +220 -0
- package/fesm2022/processpuzzle-auth-domain.mjs.map +1 -0
- package/fesm2022/processpuzzle-auth-feature.mjs +343 -0
- package/fesm2022/processpuzzle-auth-feature.mjs.map +1 -0
- package/fesm2022/processpuzzle-auth.mjs +2 -304
- package/fesm2022/processpuzzle-auth.mjs.map +1 -1
- package/package.json +30 -12
- package/types/processpuzzle-auth-domain.d.ts +64 -0
- package/types/processpuzzle-auth-feature.d.ts +17 -0
- package/types/processpuzzle-auth.d.ts +2 -0
- package/index.d.ts +0 -5
- package/lib/auth-button/auth-button.component.d.ts +0 -8
- package/lib/auth.routes.d.ts +0 -2
- package/lib/domain/auth.service.d.ts +0 -12
- package/lib/login/login.component.d.ts +0 -19
- package/lib/logout/logout.component.d.ts +0 -10
- package/lib/my-profile/my-profile.component.d.ts +0 -5
- package/lib/registration/registration.component.d.ts +0 -20
- package/public-api.d.ts +0 -2
|
@@ -1,309 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { Auth, signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup, createUserWithEmailAndPassword, authState } from '@angular/fire/auth';
|
|
4
|
-
import { Router, RouterLink } from '@angular/router';
|
|
5
|
-
import * as i2 from '@angular/forms';
|
|
6
|
-
import { FormBuilder, Validators, ReactiveFormsModule, NonNullableFormBuilder } from '@angular/forms';
|
|
7
|
-
import { MatError, MatFormField, MatSuffix } from '@angular/material/form-field';
|
|
8
|
-
import { MatInput, MatLabel } from '@angular/material/input';
|
|
9
|
-
import * as i3 from '@angular/material/button';
|
|
10
|
-
import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
|
|
11
|
-
import * as i2$1 from '@angular/material/icon';
|
|
12
|
-
import { MatIcon, MatIconModule } from '@angular/material/icon';
|
|
13
|
-
import { MatDivider } from '@angular/material/divider';
|
|
14
|
-
import * as i1$1 from '@angular/common';
|
|
15
|
-
import { NgIf, CommonModule } from '@angular/common';
|
|
16
|
-
import * as i1 from '@angular/material/snack-bar';
|
|
17
|
-
import { TranslocoDirective, provideTranslocoScope } from '@jsverse/transloco';
|
|
18
|
-
import { MatProgressBar } from '@angular/material/progress-bar';
|
|
19
|
-
import { NavigateBackService } from '@processpuzzle/widgets';
|
|
20
|
-
import { MatDialogTitle, MatDialogContent, MatDialogActions } from '@angular/material/dialog';
|
|
21
|
-
import { toSignal } from '@angular/core/rxjs-interop';
|
|
22
|
-
import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
|
|
23
|
-
import { SubstringPipe } from '@processpuzzle/util';
|
|
24
|
-
|
|
25
|
-
class LoginComponent {
|
|
26
|
-
snackBar;
|
|
27
|
-
auth = inject(Auth);
|
|
28
|
-
fb = inject(FormBuilder);
|
|
29
|
-
router = inject(Router);
|
|
30
|
-
loginForm;
|
|
31
|
-
isLoading = signal(false);
|
|
32
|
-
errorMessage = signal('');
|
|
33
|
-
hidePassword = true;
|
|
34
|
-
constructor(snackBar) {
|
|
35
|
-
this.snackBar = snackBar;
|
|
36
|
-
this.loginForm = this.fb.group({
|
|
37
|
-
email: ['', [Validators.required, Validators.email]],
|
|
38
|
-
password: ['', Validators.required],
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
async onSubmit() {
|
|
42
|
-
if (this.loginForm.invalid)
|
|
43
|
-
return;
|
|
44
|
-
this.isLoading.set(true);
|
|
45
|
-
try {
|
|
46
|
-
const { email, password } = this.loginForm.value;
|
|
47
|
-
await signInWithEmailAndPassword(this.auth, email, password);
|
|
48
|
-
await this.router.navigate(['/']);
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
this.snackBar.open(this.getErrorMessage(error.code), 'Close', { duration: 5000, panelClass: ['error-snackbar'] });
|
|
52
|
-
}
|
|
53
|
-
finally {
|
|
54
|
-
this.isLoading.set(false);
|
|
55
|
-
this.errorMessage.set('');
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async signInWithGoogle() {
|
|
59
|
-
this.isLoading.set(true);
|
|
60
|
-
try {
|
|
61
|
-
const provider = new GoogleAuthProvider();
|
|
62
|
-
await signInWithPopup(this.auth, provider);
|
|
63
|
-
await this.router.navigate(['/']); // Navigate to home page after successful login
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
this.snackBar.open(this.getErrorMessage(error.code), 'Close', { duration: 5000, panelClass: ['error-snackbar'] });
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
this.isLoading.set(false);
|
|
70
|
-
this.errorMessage.set('');
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
getErrorMessage(errorCode) {
|
|
74
|
-
switch (errorCode) {
|
|
75
|
-
case 'auth/invalid-email':
|
|
76
|
-
return 'Invalid email address';
|
|
77
|
-
case 'auth/user-disabled':
|
|
78
|
-
return 'This account has been disabled';
|
|
79
|
-
case 'auth/user-not-found':
|
|
80
|
-
return 'No account found with this email';
|
|
81
|
-
case 'auth/wrong-password':
|
|
82
|
-
return 'Invalid password';
|
|
83
|
-
case 'auth/popup-closed-by-user':
|
|
84
|
-
return 'Sign-in popup was closed before completion';
|
|
85
|
-
default:
|
|
86
|
-
return 'An error occurred during sign in';
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: LoginComponent, deps: [{ token: i1.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
|
|
90
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: LoginComponent, isStandalone: true, selector: "pp-login", providers: [provideTranslocoScope('auth')], ngImport: i0, template: "<div class=\"login-container\">\n <ng-container *transloco=\"let t;\">\n <h2>{{t('auth.login-form.title')}}</h2>\n\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Login Form\">\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" placeholder=\"Enter your email\">\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('required')\">{{t('auth.login-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('email')\">{{t('auth.login-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\">\n <button mat-icon-button matSuffix type=\"button\" (click)=\"hidePassword = !hidePassword\" aria-label=\"Toggle Password Visibility\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"loginForm.get('password')?.hasError('required')\">{{t('auth.login-form.password_err_required')}}</mat-error>\n </mat-form-field>\n\n <div class=\"actions\">\n <button mat-raised-button color=\"secondary\" routerLink=\"/auth/register\">{{t('auth.login-form.create_account_button')}}</button>\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"loginForm.invalid || isLoading()\">{{ isLoading() ? t('auth.login-form.signing_in_button') : t('auth.login-form.sign_in_button') }}</button>\n </div>\n </form>\n\n <mat-divider class=\"divider\">OR</mat-divider>\n\n <button mat-stroked-button (click)=\"signInWithGoogle()\" [disabled]=\"isLoading()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 48 48\">\n <path fill=\"#FFC107\" d=\"M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12\ts5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24s8.955,20,20,20\ts20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z\"/>\n <path fill=\"#FF3D00\" d=\"M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039\tl5.657-5.657C34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z\"/>\n <path fill=\"#4CAF50\" d=\"M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36\tc-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z\"/>\n <path fill=\"#1976D2\" d=\"M43.611,20.083H42V20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571\tc0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z\"/>\n </svg>\n {{t('auth.login-form.google_button')}}\n </button>\n <div class=\"error-message\" *ngIf=\"errorMessage\">{{ errorMessage() }}</div>\n </ng-container>\n</div>\n", styles: [".login-container{max-width:400px;margin:2rem auto;padding:2rem;border-radius:8px;box-shadow:0 2px 4px #0000001a}h2{text-align:center;margin-bottom:2rem}form{display:flex;flex-direction:column;gap:1rem}mat-form-field{width:100%}.actions{display:flex;justify-content:center;margin-top:1rem;gap:10px}.divider{margin:2rem 0;text-align:center}button[mat-stroked-button]{width:100%;margin-top:1rem;display:flex;align-items:center;justify-content:center;gap:.5rem}.google-icon{width:18px;height:18px}.error-message{color:red;text-align:center;margin-top:1rem}.mat-form-field-suffix{visibility:visible!important;opacity:1!important;display:flex!important}.mat-form-field-suffix button{z-index:10}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
91
|
-
}
|
|
92
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: LoginComponent, decorators: [{
|
|
93
|
-
type: Component,
|
|
94
|
-
args: [{ selector: 'pp-login', imports: [MatButton, MatDivider, MatError, MatFormField, MatIcon, MatIconButton, MatInput, MatLabel, MatSuffix, ReactiveFormsModule, NgIf, RouterLink, TranslocoDirective], providers: [provideTranslocoScope('auth')], template: "<div class=\"login-container\">\n <ng-container *transloco=\"let t;\">\n <h2>{{t('auth.login-form.title')}}</h2>\n\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Login Form\">\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" placeholder=\"Enter your email\">\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('required')\">{{t('auth.login-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('email')\">{{t('auth.login-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\">\n <button mat-icon-button matSuffix type=\"button\" (click)=\"hidePassword = !hidePassword\" aria-label=\"Toggle Password Visibility\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"loginForm.get('password')?.hasError('required')\">{{t('auth.login-form.password_err_required')}}</mat-error>\n </mat-form-field>\n\n <div class=\"actions\">\n <button mat-raised-button color=\"secondary\" routerLink=\"/auth/register\">{{t('auth.login-form.create_account_button')}}</button>\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"loginForm.invalid || isLoading()\">{{ isLoading() ? t('auth.login-form.signing_in_button') : t('auth.login-form.sign_in_button') }}</button>\n </div>\n </form>\n\n <mat-divider class=\"divider\">OR</mat-divider>\n\n <button mat-stroked-button (click)=\"signInWithGoogle()\" [disabled]=\"isLoading()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 48 48\">\n <path fill=\"#FFC107\" d=\"M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12\ts5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24s8.955,20,20,20\ts20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z\"/>\n <path fill=\"#FF3D00\" d=\"M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039\tl5.657-5.657C34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z\"/>\n <path fill=\"#4CAF50\" d=\"M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36\tc-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z\"/>\n <path fill=\"#1976D2\" d=\"M43.611,20.083H42V20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571\tc0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z\"/>\n </svg>\n {{t('auth.login-form.google_button')}}\n </button>\n <div class=\"error-message\" *ngIf=\"errorMessage\">{{ errorMessage() }}</div>\n </ng-container>\n</div>\n", styles: [".login-container{max-width:400px;margin:2rem auto;padding:2rem;border-radius:8px;box-shadow:0 2px 4px #0000001a}h2{text-align:center;margin-bottom:2rem}form{display:flex;flex-direction:column;gap:1rem}mat-form-field{width:100%}.actions{display:flex;justify-content:center;margin-top:1rem;gap:10px}.divider{margin:2rem 0;text-align:center}button[mat-stroked-button]{width:100%;margin-top:1rem;display:flex;align-items:center;justify-content:center;gap:.5rem}.google-icon{width:18px;height:18px}.error-message{color:red;text-align:center;margin-top:1rem}.mat-form-field-suffix{visibility:visible!important;opacity:1!important;display:flex!important}.mat-form-field-suffix button{z-index:10}\n"] }]
|
|
95
|
-
}], ctorParameters: () => [{ type: i1.MatSnackBar }] });
|
|
96
|
-
|
|
97
|
-
class MyProfileComponent {
|
|
98
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MyProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
99
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: MyProfileComponent, isStandalone: true, selector: "pp-my-profile", providers: [provideTranslocoScope('auth')], ngImport: i0, template: "<h1>My profile</h1>\n", styles: [""] });
|
|
100
|
-
}
|
|
101
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: MyProfileComponent, decorators: [{
|
|
102
|
-
type: Component,
|
|
103
|
-
args: [{ selector: 'pp-my-profile', imports: [], providers: [provideTranslocoScope('auth')], template: "<h1>My profile</h1>\n" }]
|
|
104
|
-
}] });
|
|
105
|
-
|
|
106
|
-
class RegistrationComponent {
|
|
107
|
-
snackBar;
|
|
108
|
-
auth = inject(Auth);
|
|
109
|
-
fb = inject(NonNullableFormBuilder);
|
|
110
|
-
navigateBack = inject(NavigateBackService);
|
|
111
|
-
registerForm;
|
|
112
|
-
isLoading = signal(false);
|
|
113
|
-
errorMessage = signal('');
|
|
114
|
-
hidePassword = true;
|
|
115
|
-
hideConfirmPassword = true;
|
|
116
|
-
constructor(snackBar) {
|
|
117
|
-
this.snackBar = snackBar;
|
|
118
|
-
this.registerForm = this.fb.group({
|
|
119
|
-
email: ['', [Validators.required, Validators.email]],
|
|
120
|
-
password: ['', [Validators.required, Validators.minLength(6)]],
|
|
121
|
-
confirmPassword: ['', Validators.required],
|
|
122
|
-
}, {
|
|
123
|
-
validators: [this.passwordMatchValidator],
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
passwordMatchValidator() {
|
|
127
|
-
return (form) => {
|
|
128
|
-
const password = form.get('password')?.value;
|
|
129
|
-
const confirmPassword = form.get('confirmPassword')?.value;
|
|
130
|
-
if (password !== confirmPassword) {
|
|
131
|
-
return { passwordMismatch: true };
|
|
132
|
-
}
|
|
133
|
-
return null;
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
async onSubmit() {
|
|
137
|
-
if (this.registerForm.invalid)
|
|
138
|
-
return;
|
|
139
|
-
this.isLoading.set(true);
|
|
140
|
-
try {
|
|
141
|
-
const { email, password } = this.registerForm.value;
|
|
142
|
-
await createUserWithEmailAndPassword(this.auth, email, password);
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
this.snackBar.open(this.getErrorMessage(error.code), 'Close', {
|
|
146
|
-
duration: 5000,
|
|
147
|
-
panelClass: ['error-snackbar'],
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
this.isLoading.set(false);
|
|
152
|
-
this.errorMessage.set('');
|
|
153
|
-
this.navigateBack.goBack();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
getErrorMessage(errorCode) {
|
|
157
|
-
switch (errorCode) {
|
|
158
|
-
case 'auth/email-already-in-use':
|
|
159
|
-
return 'This email address is already registered';
|
|
160
|
-
case 'auth/invalid-email':
|
|
161
|
-
return 'Please enter a valid email address';
|
|
162
|
-
case 'auth/operation-not-allowed':
|
|
163
|
-
return 'Email/password registration is not enabled';
|
|
164
|
-
case 'auth/weak-password':
|
|
165
|
-
return 'Please choose a stronger password';
|
|
166
|
-
default:
|
|
167
|
-
return 'An error occurred during registration. Please try again.';
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RegistrationComponent, deps: [{ token: i1.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
|
|
171
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: RegistrationComponent, isStandalone: true, selector: "pp-registration", providers: [provideTranslocoScope('auth')], ngImport: i0, template: "<div class=\"registration-container\">\n <ng-container *transloco=\"let t;\">\n <h1>{{t('auth.registration-form.title')}}</h1>\n\n <form [formGroup]=\"registerForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Registration Form\">\n <mat-progress-bar *ngIf=\"isLoading()\" mode=\"indeterminate\"></mat-progress-bar>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" [placeholder]=\"t('auth.registration-form.email_placeholder')\">\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['required']\">{{t('auth.registration-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['email']\">{{t('auth.registration-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\" [placeholder]=\"t('auth.registration-form.password_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hidePassword = !hidePassword\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['required']\">{{t('auth.registration-form.password_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['minlength']\">{{t('auth.registration-form.password_err_min_length')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_confirm_label')}}</mat-label>\n <input matInput [type]=\"hideConfirmPassword ? 'password' : 'text'\" formControlName=\"confirmPassword\" [placeholder]=\"t('auth.registration-form.password_confirm_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hideConfirmPassword = !hideConfirmPassword\">\n <mat-icon>{{hideConfirmPassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.errors?.['passwordMismatch']\">{{t('auth.registration-form.password_confirm_err_mismatch')}}</mat-error>\n </mat-form-field>\n\n <div class=\"form-actions\">\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"registerForm.invalid || isLoading()\">{{t('auth.registration-form.create_button')}}</button>\n <button mat-button type=\"button\" routerLink=\"/auth/login\" [disabled]=\"isLoading()\">{{t('auth.registration-form.sign_in_button')}}</button>\n </div>\n\n <mat-error *ngIf=\"errorMessage() !== ''\" class=\"server-error\">{{ errorMessage() }}</mat-error>\n </form>\n </ng-container>\n</div>\n", styles: [".registration-container{max-width:400px;margin:2rem auto;padding:2rem}form{display:flex;flex-direction:column;gap:1rem}.form-actions{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem}.server-error{margin-top:1rem;text-align:center}h1{text-align:center;margin-bottom:2rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
172
|
-
}
|
|
173
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RegistrationComponent, decorators: [{
|
|
174
|
-
type: Component,
|
|
175
|
-
args: [{ selector: 'pp-registration', imports: [ReactiveFormsModule, MatProgressBar, MatFormField, MatInput, NgIf, MatIconButton, MatIcon, MatLabel, MatButton, RouterLink, MatError, TranslocoDirective], providers: [provideTranslocoScope('auth')], template: "<div class=\"registration-container\">\n <ng-container *transloco=\"let t;\">\n <h1>{{t('auth.registration-form.title')}}</h1>\n\n <form [formGroup]=\"registerForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Registration Form\">\n <mat-progress-bar *ngIf=\"isLoading()\" mode=\"indeterminate\"></mat-progress-bar>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" [placeholder]=\"t('auth.registration-form.email_placeholder')\">\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['required']\">{{t('auth.registration-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['email']\">{{t('auth.registration-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\" [placeholder]=\"t('auth.registration-form.password_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hidePassword = !hidePassword\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['required']\">{{t('auth.registration-form.password_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['minlength']\">{{t('auth.registration-form.password_err_min_length')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_confirm_label')}}</mat-label>\n <input matInput [type]=\"hideConfirmPassword ? 'password' : 'text'\" formControlName=\"confirmPassword\" [placeholder]=\"t('auth.registration-form.password_confirm_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hideConfirmPassword = !hideConfirmPassword\">\n <mat-icon>{{hideConfirmPassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.errors?.['passwordMismatch']\">{{t('auth.registration-form.password_confirm_err_mismatch')}}</mat-error>\n </mat-form-field>\n\n <div class=\"form-actions\">\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"registerForm.invalid || isLoading()\">{{t('auth.registration-form.create_button')}}</button>\n <button mat-button type=\"button\" routerLink=\"/auth/login\" [disabled]=\"isLoading()\">{{t('auth.registration-form.sign_in_button')}}</button>\n </div>\n\n <mat-error *ngIf=\"errorMessage() !== ''\" class=\"server-error\">{{ errorMessage() }}</mat-error>\n </form>\n </ng-container>\n</div>\n", styles: [".registration-container{max-width:400px;margin:2rem auto;padding:2rem}form{display:flex;flex-direction:column;gap:1rem}.form-actions{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem}.server-error{margin-top:1rem;text-align:center}h1{text-align:center;margin-bottom:2rem}\n"] }]
|
|
176
|
-
}], ctorParameters: () => [{ type: i1.MatSnackBar }] });
|
|
177
|
-
|
|
178
|
-
class AuthService {
|
|
179
|
-
auth = inject(Auth);
|
|
180
|
-
user = toSignal(authState(this.auth), { initialValue: null });
|
|
181
|
-
isAuthenticated = computed(() => !!this.user());
|
|
182
|
-
async signOut() {
|
|
183
|
-
return this.auth.signOut();
|
|
184
|
-
}
|
|
185
|
-
getCurrentUser() {
|
|
186
|
-
return this.auth.currentUser;
|
|
187
|
-
}
|
|
188
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
189
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
190
|
-
}
|
|
191
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AuthService, decorators: [{
|
|
192
|
-
type: Injectable,
|
|
193
|
-
args: [{
|
|
194
|
-
providedIn: 'root',
|
|
195
|
-
}]
|
|
196
|
-
}] });
|
|
197
|
-
|
|
198
|
-
class LogoutComponent {
|
|
199
|
-
authService = inject(AuthService);
|
|
200
|
-
navigateBackService = inject(NavigateBackService);
|
|
201
|
-
isLoading = signal(false);
|
|
202
|
-
onCancel() {
|
|
203
|
-
this.navigateBackService.goBack();
|
|
204
|
-
}
|
|
205
|
-
async onLogout() {
|
|
206
|
-
try {
|
|
207
|
-
this.isLoading.set(true);
|
|
208
|
-
await this.authService.signOut();
|
|
209
|
-
this.navigateBackService.goBack();
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
console.error('Error during logout:', error);
|
|
213
|
-
}
|
|
214
|
-
finally {
|
|
215
|
-
this.isLoading.set(false);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: LogoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
219
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: LogoutComponent, isStandalone: true, selector: "pp-logout", providers: [provideTranslocoScope('auth')], ngImport: i0, template: `
|
|
220
|
-
<div class="logout-dialog">
|
|
221
|
-
<ng-container *transloco="let t">
|
|
222
|
-
<h2 mat-dialog-title>{{ t('auth.logout-dialog.title') }}</h2>
|
|
223
|
-
<mat-dialog-content>{{ t('auth.logout-dialog.content') }}</mat-dialog-content>
|
|
224
|
-
<mat-dialog-actions align="end">
|
|
225
|
-
<button mat-button (click)="onCancel()">{{ t('auth.logout-dialog.cancel_button') }}</button>
|
|
226
|
-
<button mat-raised-button color="primary" (click)="onLogout()" [disabled]="isLoading()">{{ t('auth.logout-dialog.logout_button') }}</button>
|
|
227
|
-
</mat-dialog-actions>
|
|
228
|
-
</ng-container>
|
|
229
|
-
</div>
|
|
230
|
-
`, isInline: true, styles: [".logout-dialog{padding:1rem}mat-dialog-actions{gap:.5rem}mat-dialog-content{margin:1rem 0}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
231
|
-
}
|
|
232
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: LogoutComponent, decorators: [{
|
|
233
|
-
type: Component,
|
|
234
|
-
args: [{ selector: 'pp-logout', template: `
|
|
235
|
-
<div class="logout-dialog">
|
|
236
|
-
<ng-container *transloco="let t">
|
|
237
|
-
<h2 mat-dialog-title>{{ t('auth.logout-dialog.title') }}</h2>
|
|
238
|
-
<mat-dialog-content>{{ t('auth.logout-dialog.content') }}</mat-dialog-content>
|
|
239
|
-
<mat-dialog-actions align="end">
|
|
240
|
-
<button mat-button (click)="onCancel()">{{ t('auth.logout-dialog.cancel_button') }}</button>
|
|
241
|
-
<button mat-raised-button color="primary" (click)="onLogout()" [disabled]="isLoading()">{{ t('auth.logout-dialog.logout_button') }}</button>
|
|
242
|
-
</mat-dialog-actions>
|
|
243
|
-
</ng-container>
|
|
244
|
-
</div>
|
|
245
|
-
`, imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButton, TranslocoDirective], providers: [provideTranslocoScope('auth')], styles: [".logout-dialog{padding:1rem}mat-dialog-actions{gap:.5rem}mat-dialog-content{margin:1rem 0}\n"] }]
|
|
246
|
-
}] });
|
|
247
|
-
|
|
248
|
-
const authRoutes = [
|
|
249
|
-
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
|
250
|
-
{ path: 'login', component: LoginComponent, title: 'login', data: { icon: 'login', authToggle: true } },
|
|
251
|
-
{ path: 'logout', component: LogoutComponent, title: 'logout', data: { icon: 'logout', authToggle: false } },
|
|
252
|
-
{ path: 'register', component: RegistrationComponent, title: 'register', data: { icon: 'person_add', authToggle: true } },
|
|
253
|
-
{ path: 'my-profile', component: MyProfileComponent, title: 'my_profile', data: { icon: 'person', authToggle: false } },
|
|
254
|
-
];
|
|
255
|
-
|
|
256
|
-
class AuthButtonComponent {
|
|
257
|
-
authService = inject(AuthService);
|
|
258
|
-
isAuthenticated = computed(() => this.authService.isAuthenticated());
|
|
259
|
-
routes = authRoutes.filter((item) => item.title !== null && item.title !== undefined);
|
|
260
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AuthButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
261
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AuthButtonComponent, isStandalone: true, selector: "pp-auth-button", providers: [provideTranslocoScope('auth')], ngImport: i0, template: `
|
|
262
|
-
<div class="auth-button">
|
|
263
|
-
<ng-container *transloco="let t">
|
|
264
|
-
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Auth Button">
|
|
265
|
-
<mat-icon>person</mat-icon>
|
|
266
|
-
</button>
|
|
267
|
-
<mat-menu #menu="matMenu">
|
|
268
|
-
@for (item of routes; track item) {
|
|
269
|
-
<ng-container *ngIf="(isAuthenticated() && !item.data?.['authToggle']) || (!isAuthenticated() && item.data?.['authToggle'])">
|
|
270
|
-
<button mat-menu-item [routerLink]="'auth/' + item.path">
|
|
271
|
-
<mat-icon>{{ item.data?.['icon'] }}</mat-icon>
|
|
272
|
-
<span> {{ t('auth.button.' + item.title | substring: 0) }}</span>
|
|
273
|
-
</button>
|
|
274
|
-
</ng-container>
|
|
275
|
-
}
|
|
276
|
-
</mat-menu>
|
|
277
|
-
</ng-container>
|
|
278
|
-
</div>
|
|
279
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "pipe", type: SubstringPipe, name: "substring" }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
280
|
-
}
|
|
281
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AuthButtonComponent, decorators: [{
|
|
282
|
-
type: Component,
|
|
283
|
-
args: [{ selector: 'pp-auth-button', template: `
|
|
284
|
-
<div class="auth-button">
|
|
285
|
-
<ng-container *transloco="let t">
|
|
286
|
-
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Auth Button">
|
|
287
|
-
<mat-icon>person</mat-icon>
|
|
288
|
-
</button>
|
|
289
|
-
<mat-menu #menu="matMenu">
|
|
290
|
-
@for (item of routes; track item) {
|
|
291
|
-
<ng-container *ngIf="(isAuthenticated() && !item.data?.['authToggle']) || (!isAuthenticated() && item.data?.['authToggle'])">
|
|
292
|
-
<button mat-menu-item [routerLink]="'auth/' + item.path">
|
|
293
|
-
<mat-icon>{{ item.data?.['icon'] }}</mat-icon>
|
|
294
|
-
<span> {{ t('auth.button.' + item.title | substring: 0) }}</span>
|
|
295
|
-
</button>
|
|
296
|
-
</ng-container>
|
|
297
|
-
}
|
|
298
|
-
</mat-menu>
|
|
299
|
-
</ng-container>
|
|
300
|
-
</div>
|
|
301
|
-
`, imports: [CommonModule, MatIconModule, MatButtonModule, MatMenu, MatMenuItem, RouterLink, MatMenuTrigger, SubstringPipe, TranslocoDirective], providers: [provideTranslocoScope('auth')] }]
|
|
302
|
-
}] });
|
|
1
|
+
export * from '@processpuzzle/auth/domain';
|
|
2
|
+
export * from '@processpuzzle/auth/feature';
|
|
303
3
|
|
|
304
4
|
/**
|
|
305
5
|
* Generated bundle index. Do not edit.
|
|
306
6
|
*/
|
|
307
|
-
|
|
308
|
-
export { AuthButtonComponent, authRoutes };
|
|
309
7
|
//# sourceMappingURL=processpuzzle-auth.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processpuzzle-auth.mjs","sources":["../../../../libs/auth/src/lib/login/login.component.ts","../../../../libs/auth/src/lib/login/login.component.html","../../../../libs/auth/src/lib/my-profile/my-profile.component.ts","../../../../libs/auth/src/lib/my-profile/my-profile.component.html","../../../../libs/auth/src/lib/registration/registration.component.ts","../../../../libs/auth/src/lib/registration/registration.component.html","../../../../libs/auth/src/lib/domain/auth.service.ts","../../../../libs/auth/src/lib/logout/logout.component.ts","../../../../libs/auth/src/lib/auth.routes.ts","../../../../libs/auth/src/lib/auth-button/auth-button.component.ts","../../../../libs/auth/src/processpuzzle-auth.ts"],"sourcesContent":["import { Component, inject, signal } from '@angular/core';\nimport { Auth, GoogleAuthProvider, signInWithEmailAndPassword, signInWithPopup } from '@angular/fire/auth';\nimport { Router, RouterLink } from '@angular/router';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MatError, MatFormField, MatSuffix } from '@angular/material/form-field';\nimport { MatInput, MatLabel } from '@angular/material/input';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatDivider } from '@angular/material/divider';\nimport { NgIf } from '@angular/common';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { FirebaseError } from 'firebase-admin/lib/utils/error';\nimport { provideTranslocoScope, TranslocoDirective } from '@jsverse/transloco';\n\n@Component({\n selector: 'pp-login',\n templateUrl: 'login.component.html',\n styleUrls: ['login.component.css'],\n imports: [MatButton, MatDivider, MatError, MatFormField, MatIcon, MatIconButton, MatInput, MatLabel, MatSuffix, ReactiveFormsModule, NgIf, RouterLink, TranslocoDirective],\n providers: [provideTranslocoScope('auth')],\n})\nexport class LoginComponent {\n private readonly auth: Auth = inject(Auth);\n private readonly fb = inject(FormBuilder);\n private readonly router = inject(Router);\n\n loginForm: FormGroup;\n isLoading = signal(false);\n errorMessage = signal('');\n hidePassword = true;\n\n constructor(private readonly snackBar: MatSnackBar) {\n this.loginForm = this.fb.group({\n email: ['', [Validators.required, Validators.email]],\n password: ['', Validators.required],\n });\n }\n\n async onSubmit() {\n if (this.loginForm.invalid) return;\n\n this.isLoading.set(true);\n\n try {\n const { email, password } = this.loginForm.value;\n await signInWithEmailAndPassword(this.auth, email, password);\n await this.router.navigate(['/']);\n } catch (error: unknown) {\n this.snackBar.open(this.getErrorMessage((error as FirebaseError).code), 'Close', { duration: 5000, panelClass: ['error-snackbar'] });\n } finally {\n this.isLoading.set(false);\n this.errorMessage.set('');\n }\n }\n\n async signInWithGoogle() {\n this.isLoading.set(true);\n\n try {\n const provider = new GoogleAuthProvider();\n await signInWithPopup(this.auth, provider);\n await this.router.navigate(['/']); // Navigate to home page after successful login\n } catch (error: unknown) {\n this.snackBar.open(this.getErrorMessage((error as FirebaseError).code), 'Close', { duration: 5000, panelClass: ['error-snackbar'] });\n } finally {\n this.isLoading.set(false);\n this.errorMessage.set('');\n }\n }\n\n private getErrorMessage(errorCode: string): string {\n switch (errorCode) {\n case 'auth/invalid-email':\n return 'Invalid email address';\n case 'auth/user-disabled':\n return 'This account has been disabled';\n case 'auth/user-not-found':\n return 'No account found with this email';\n case 'auth/wrong-password':\n return 'Invalid password';\n case 'auth/popup-closed-by-user':\n return 'Sign-in popup was closed before completion';\n default:\n return 'An error occurred during sign in';\n }\n }\n}\n","<div class=\"login-container\">\n <ng-container *transloco=\"let t;\">\n <h2>{{t('auth.login-form.title')}}</h2>\n\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Login Form\">\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" placeholder=\"Enter your email\">\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('required')\">{{t('auth.login-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"loginForm.get('email')?.hasError('email')\">{{t('auth.login-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.login-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\">\n <button mat-icon-button matSuffix type=\"button\" (click)=\"hidePassword = !hidePassword\" aria-label=\"Toggle Password Visibility\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"loginForm.get('password')?.hasError('required')\">{{t('auth.login-form.password_err_required')}}</mat-error>\n </mat-form-field>\n\n <div class=\"actions\">\n <button mat-raised-button color=\"secondary\" routerLink=\"/auth/register\">{{t('auth.login-form.create_account_button')}}</button>\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"loginForm.invalid || isLoading()\">{{ isLoading() ? t('auth.login-form.signing_in_button') : t('auth.login-form.sign_in_button') }}</button>\n </div>\n </form>\n\n <mat-divider class=\"divider\">OR</mat-divider>\n\n <button mat-stroked-button (click)=\"signInWithGoogle()\" [disabled]=\"isLoading()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 48 48\">\n <path fill=\"#FFC107\" d=\"M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12\ts5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24s8.955,20,20,20\ts20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z\"/>\n <path fill=\"#FF3D00\" d=\"M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039\tl5.657-5.657C34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z\"/>\n <path fill=\"#4CAF50\" d=\"M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36\tc-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z\"/>\n <path fill=\"#1976D2\" d=\"M43.611,20.083H42V20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571\tc0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z\"/>\n </svg>\n {{t('auth.login-form.google_button')}}\n </button>\n <div class=\"error-message\" *ngIf=\"errorMessage\">{{ errorMessage() }}</div>\n </ng-container>\n</div>\n","import { Component } from '@angular/core';\nimport { provideTranslocoScope } from '@jsverse/transloco';\n\n@Component({\n selector: 'pp-my-profile',\n templateUrl: 'my-profile.component.html',\n styles: ``,\n imports: [],\n providers: [provideTranslocoScope('auth')],\n})\nexport class MyProfileComponent {}\n","<h1>My profile</h1>\n","import { Component, inject, signal } from '@angular/core';\nimport { AbstractControl, FormGroup, NonNullableFormBuilder, ReactiveFormsModule, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';\nimport { Auth, createUserWithEmailAndPassword } from '@angular/fire/auth';\nimport { RouterLink } from '@angular/router';\nimport { MatProgressBar } from '@angular/material/progress-bar';\nimport { MatError, MatFormField } from '@angular/material/form-field';\nimport { MatInput, MatLabel } from '@angular/material/input';\nimport { NgIf } from '@angular/common';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { NavigateBackService } from '@processpuzzle/widgets';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { FirebaseError } from 'firebase-admin/lib/utils/error';\nimport { provideTranslocoScope, TranslocoDirective } from '@jsverse/transloco';\n\n@Component({\n selector: 'pp-registration',\n templateUrl: 'registration.component.html',\n styleUrls: ['registration.component.css'],\n imports: [ReactiveFormsModule, MatProgressBar, MatFormField, MatInput, NgIf, MatIconButton, MatIcon, MatLabel, MatButton, RouterLink, MatError, TranslocoDirective],\n providers: [provideTranslocoScope('auth')],\n})\nexport class RegistrationComponent {\n private readonly auth = inject(Auth);\n private readonly fb = inject(NonNullableFormBuilder);\n private readonly navigateBack = inject(NavigateBackService);\n\n protected registerForm: FormGroup;\n protected isLoading = signal<boolean>(false);\n protected errorMessage = signal<string>('');\n protected hidePassword = true;\n protected hideConfirmPassword = true;\n\n constructor(private readonly snackBar: MatSnackBar) {\n this.registerForm = this.fb.group(\n {\n email: ['', [Validators.required, Validators.email]],\n password: ['', [Validators.required, Validators.minLength(6)]],\n confirmPassword: ['', Validators.required],\n },\n {\n validators: [this.passwordMatchValidator],\n },\n );\n }\n\n private passwordMatchValidator(): ValidatorFn {\n return (form: AbstractControl): ValidationErrors | null => {\n const password = form.get('password')?.value;\n const confirmPassword = form.get('confirmPassword')?.value;\n\n if (password !== confirmPassword) {\n return { passwordMismatch: true };\n }\n return null;\n };\n }\n\n async onSubmit(): Promise<void> {\n if (this.registerForm.invalid) return;\n\n this.isLoading.set(true);\n\n try {\n const { email, password } = this.registerForm.value;\n await createUserWithEmailAndPassword(this.auth, email, password);\n } catch (error: unknown) {\n this.snackBar.open(this.getErrorMessage((error as FirebaseError).code), 'Close', {\n duration: 5000,\n panelClass: ['error-snackbar'],\n });\n } finally {\n this.isLoading.set(false);\n this.errorMessage.set('');\n this.navigateBack.goBack();\n }\n }\n\n private getErrorMessage(errorCode: string): string {\n switch (errorCode) {\n case 'auth/email-already-in-use':\n return 'This email address is already registered';\n case 'auth/invalid-email':\n return 'Please enter a valid email address';\n case 'auth/operation-not-allowed':\n return 'Email/password registration is not enabled';\n case 'auth/weak-password':\n return 'Please choose a stronger password';\n default:\n return 'An error occurred during registration. Please try again.';\n }\n }\n}\n","<div class=\"registration-container\">\n <ng-container *transloco=\"let t;\">\n <h1>{{t('auth.registration-form.title')}}</h1>\n\n <form [formGroup]=\"registerForm\" (ngSubmit)=\"onSubmit()\" aria-label=\"Registration Form\">\n <mat-progress-bar *ngIf=\"isLoading()\" mode=\"indeterminate\"></mat-progress-bar>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.email_label')}}</mat-label>\n <input matInput type=\"email\" formControlName=\"email\" [placeholder]=\"t('auth.registration-form.email_placeholder')\">\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['required']\">{{t('auth.registration-form.email_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('email')?.errors?.['email']\">{{t('auth.registration-form.email_err_invalid')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_label')}}</mat-label>\n <input matInput [type]=\"hidePassword ? 'password' : 'text'\" formControlName=\"password\" [placeholder]=\"t('auth.registration-form.password_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hidePassword = !hidePassword\">\n <mat-icon>{{hidePassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['required']\">{{t('auth.registration-form.password_err_required')}}</mat-error>\n <mat-error *ngIf=\"registerForm.get('password')?.errors?.['minlength']\">{{t('auth.registration-form.password_err_min_length')}}</mat-error>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{t('auth.registration-form.password_confirm_label')}}</mat-label>\n <input matInput [type]=\"hideConfirmPassword ? 'password' : 'text'\" formControlName=\"confirmPassword\" [placeholder]=\"t('auth.registration-form.password_confirm_placeholder')\">\n <button mat-icon-button type=\"button\" matSuffix (click)=\"hideConfirmPassword = !hideConfirmPassword\">\n <mat-icon>{{hideConfirmPassword ? 'visibility_off' : 'visibility'}}</mat-icon>\n </button>\n <mat-error *ngIf=\"registerForm.errors?.['passwordMismatch']\">{{t('auth.registration-form.password_confirm_err_mismatch')}}</mat-error>\n </mat-form-field>\n\n <div class=\"form-actions\">\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"registerForm.invalid || isLoading()\">{{t('auth.registration-form.create_button')}}</button>\n <button mat-button type=\"button\" routerLink=\"/auth/login\" [disabled]=\"isLoading()\">{{t('auth.registration-form.sign_in_button')}}</button>\n </div>\n\n <mat-error *ngIf=\"errorMessage() !== ''\" class=\"server-error\">{{ errorMessage() }}</mat-error>\n </form>\n </ng-container>\n</div>\n","import { computed, inject, Injectable, Signal } from '@angular/core';\nimport { Auth, authState, User } from '@angular/fire/auth';\nimport { toSignal } from '@angular/core/rxjs-interop';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly auth: Auth = inject(Auth);\n readonly user = toSignal<User | null>(authState(this.auth), { initialValue: null });\n isAuthenticated: Signal<boolean> = computed(() => !!this.user());\n\n async signOut(): Promise<void> {\n return this.auth.signOut();\n }\n\n getCurrentUser(): User | null {\n return this.auth.currentUser;\n }\n}\n","import { Component, inject, signal } from '@angular/core';\nimport { MatDialogActions, MatDialogContent, MatDialogTitle } from '@angular/material/dialog';\nimport { MatButton } from '@angular/material/button';\nimport { AuthService } from '../domain/auth.service';\nimport { NavigateBackService } from '@processpuzzle/widgets';\nimport { provideTranslocoScope, TranslocoDirective } from '@jsverse/transloco';\n\n@Component({\n selector: 'pp-logout',\n template: `\n <div class=\"logout-dialog\">\n <ng-container *transloco=\"let t\">\n <h2 mat-dialog-title>{{ t('auth.logout-dialog.title') }}</h2>\n <mat-dialog-content>{{ t('auth.logout-dialog.content') }}</mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button (click)=\"onCancel()\">{{ t('auth.logout-dialog.cancel_button') }}</button>\n <button mat-raised-button color=\"primary\" (click)=\"onLogout()\" [disabled]=\"isLoading()\">{{ t('auth.logout-dialog.logout_button') }}</button>\n </mat-dialog-actions>\n </ng-container>\n </div>\n `,\n styles: [\n `\n .logout-dialog {\n padding: 1rem;\n }\n\n mat-dialog-actions {\n gap: 0.5rem;\n }\n\n mat-dialog-content {\n margin: 1rem 0;\n }\n `,\n ],\n imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButton, TranslocoDirective],\n providers: [provideTranslocoScope('auth')],\n})\nexport class LogoutComponent {\n private readonly authService = inject(AuthService);\n private readonly navigateBackService = inject(NavigateBackService);\n protected isLoading = signal(false);\n\n onCancel() {\n this.navigateBackService.goBack();\n }\n\n async onLogout(): Promise<void> {\n try {\n this.isLoading.set(true);\n await this.authService.signOut();\n this.navigateBackService.goBack();\n } catch (error) {\n console.error('Error during logout:', error);\n } finally {\n this.isLoading.set(false);\n }\n }\n}\n","import { Routes } from '@angular/router';\nimport { LoginComponent } from './login/login.component';\nimport { MyProfileComponent } from './my-profile/my-profile.component';\nimport { RegistrationComponent } from './registration/registration.component';\nimport { LogoutComponent } from './logout/logout.component';\n\nexport const authRoutes: Routes = [\n { path: '', redirectTo: 'login', pathMatch: 'full' },\n { path: 'login', component: LoginComponent, title: 'login', data: { icon: 'login', authToggle: true } },\n { path: 'logout', component: LogoutComponent, title: 'logout', data: { icon: 'logout', authToggle: false } },\n { path: 'register', component: RegistrationComponent, title: 'register', data: { icon: 'person_add', authToggle: true } },\n { path: 'my-profile', component: MyProfileComponent, title: 'my_profile', data: { icon: 'person', authToggle: false } },\n];\n","import { Component, computed, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { RouterLink } from '@angular/router';\nimport { AuthService } from '../domain/auth.service';\nimport { authRoutes } from '../auth.routes';\nimport { SubstringPipe } from '@processpuzzle/util';\nimport { provideTranslocoScope, TranslocoDirective } from '@jsverse/transloco';\n\n@Component({\n selector: 'pp-auth-button',\n template: `\n <div class=\"auth-button\">\n <ng-container *transloco=\"let t\">\n <button mat-icon-button [matMenuTriggerFor]=\"menu\" aria-label=\"Auth Button\">\n <mat-icon>person</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n @for (item of routes; track item) {\n <ng-container *ngIf=\"(isAuthenticated() && !item.data?.['authToggle']) || (!isAuthenticated() && item.data?.['authToggle'])\">\n <button mat-menu-item [routerLink]=\"'auth/' + item.path\">\n <mat-icon>{{ item.data?.['icon'] }}</mat-icon>\n <span> {{ t('auth.button.' + item.title | substring: 0) }}</span>\n </button>\n </ng-container>\n }\n </mat-menu>\n </ng-container>\n </div>\n `,\n imports: [CommonModule, MatIconModule, MatButtonModule, MatMenu, MatMenuItem, RouterLink, MatMenuTrigger, SubstringPipe, TranslocoDirective],\n styles: [],\n providers: [provideTranslocoScope('auth')],\n})\nexport class AuthButtonComponent {\n private readonly authService = inject(AuthService);\n isAuthenticated = computed(() => this.authService.isAuthenticated());\n readonly routes = authRoutes.filter((item) => item.title !== null && item.title !== undefined);\n\n // region event handling methods\n // endregion\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"processpuzzle-auth.mjs","sources":["../../../../libs/auth/processpuzzle-auth.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;AAEG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processpuzzle/auth",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -11,30 +11,48 @@
|
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://github.com/ZsZs/processpuzzle#readme",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@angular/common": "~
|
|
15
|
-
"@angular/core": "~
|
|
16
|
-
"@angular/forms": "~
|
|
17
|
-
"@angular/router": "~
|
|
18
|
-
"@angular/material": "^
|
|
19
|
-
"@angular/cdk": "^
|
|
20
|
-
"@angular/fire": "^20.0.
|
|
14
|
+
"@angular/common": "~21.2.4",
|
|
15
|
+
"@angular/core": "~21.2.4",
|
|
16
|
+
"@angular/forms": "~21.2.4",
|
|
17
|
+
"@angular/router": "~21.2.4",
|
|
18
|
+
"@angular/material": "^21.2.2",
|
|
19
|
+
"@angular/cdk": "^21.2.2",
|
|
20
|
+
"@angular/fire": "^20.0.1",
|
|
21
|
+
"@jsverse/transloco": "8.2.1",
|
|
22
|
+
"@ngrx/component-store": "^21.0.1",
|
|
23
|
+
"@ngrx/operators": "^21.0.1",
|
|
24
|
+
"@ngrx/signals": "^21.0.1",
|
|
25
|
+
"@processpuzzle/base-entity": "^0.2.4",
|
|
21
26
|
"@processpuzzle/util": "^0.2.4",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
27
|
+
"@processpuzzle/widgets": "^0.2.4",
|
|
28
|
+
"angular-auth-oidc-client": "^21.0.1",
|
|
29
|
+
"firebase-admin": "^13.7.0",
|
|
30
|
+
"keycloak-js": "^26.2.3",
|
|
31
|
+
"ngx-logger": "^5.0.12",
|
|
32
|
+
"rxjs": "~7.8.2",
|
|
33
|
+
"uuid": "^13.0.0"
|
|
24
34
|
},
|
|
25
35
|
"dependencies": {
|
|
26
36
|
"tslib": "^2.8.1"
|
|
27
37
|
},
|
|
28
38
|
"sideEffects": false,
|
|
29
39
|
"module": "fesm2022/processpuzzle-auth.mjs",
|
|
30
|
-
"typings": "
|
|
40
|
+
"typings": "types/processpuzzle-auth.d.ts",
|
|
31
41
|
"exports": {
|
|
32
42
|
"./package.json": {
|
|
33
43
|
"default": "./package.json"
|
|
34
44
|
},
|
|
35
45
|
".": {
|
|
36
|
-
"types": "./
|
|
46
|
+
"types": "./types/processpuzzle-auth.d.ts",
|
|
37
47
|
"default": "./fesm2022/processpuzzle-auth.mjs"
|
|
48
|
+
},
|
|
49
|
+
"./domain": {
|
|
50
|
+
"types": "./types/processpuzzle-auth-domain.d.ts",
|
|
51
|
+
"default": "./fesm2022/processpuzzle-auth-domain.mjs"
|
|
52
|
+
},
|
|
53
|
+
"./feature": {
|
|
54
|
+
"types": "./types/processpuzzle-auth-feature.d.ts",
|
|
55
|
+
"default": "./fesm2022/processpuzzle-auth-feature.mjs"
|
|
38
56
|
}
|
|
39
57
|
}
|
|
40
58
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { UrlSegment } from '@angular/router';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { WritableSignal, Signal, InjectionToken, EnvironmentProviders } from '@angular/core';
|
|
4
|
+
import { BaseEntity } from '@processpuzzle/base-entity';
|
|
5
|
+
|
|
6
|
+
declare function authMatcher(segments: UrlSegment[]): {
|
|
7
|
+
consumed: UrlSegment[];
|
|
8
|
+
posParams: {};
|
|
9
|
+
} | null;
|
|
10
|
+
|
|
11
|
+
declare class User implements BaseEntity {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
private _email;
|
|
14
|
+
private _password;
|
|
15
|
+
private _firstName;
|
|
16
|
+
private _lastName;
|
|
17
|
+
private _photoUrl;
|
|
18
|
+
constructor(email?: string | null, id?: string, firstName?: string | null, lastName?: string | null, photoUrl?: string | null);
|
|
19
|
+
get email(): string | null | undefined;
|
|
20
|
+
set email(email: string);
|
|
21
|
+
get firstName(): string | undefined;
|
|
22
|
+
set firstName(firstName: string);
|
|
23
|
+
get lastName(): string | undefined;
|
|
24
|
+
set lastName(lastName: string);
|
|
25
|
+
get password(): string | null | undefined;
|
|
26
|
+
set password(password: string);
|
|
27
|
+
get photoUrl(): string | undefined;
|
|
28
|
+
set photoUrl(url: string);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare abstract class AuthService {
|
|
32
|
+
protected _user: WritableSignal<User | undefined>;
|
|
33
|
+
protected readonly user: Signal<User | undefined>;
|
|
34
|
+
isAuthenticated: Signal<boolean | undefined>;
|
|
35
|
+
abstract authenticate(): Promise<boolean>;
|
|
36
|
+
abstract login(redirectUrl?: string, email?: string, password?: string): Promise<User | undefined>;
|
|
37
|
+
abstract logout(redirectUrl?: string): Promise<void>;
|
|
38
|
+
abstract getCurrentUser(): User | undefined;
|
|
39
|
+
protected throwError(message: string): void;
|
|
40
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, never>;
|
|
41
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface KeycloakAuthConfig {
|
|
45
|
+
realm: string;
|
|
46
|
+
clientId: string;
|
|
47
|
+
authServerUrl: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface FirebaseAuthConfig {
|
|
51
|
+
readonly url?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const AUTHENTICATION_CONFIGURATION: InjectionToken<AuthenticationConfiguration>;
|
|
55
|
+
declare const AUTHENTICATION_SERVICE: InjectionToken<AuthService>;
|
|
56
|
+
interface AuthenticationConfiguration {
|
|
57
|
+
readonly AUTHENTICATION_PROVIDER?: 'local-auth' | 'firebase-auth' | 'oauth2' | 'keycloak';
|
|
58
|
+
readonly AUTHENTICATION_SERVICE_ROOT?: string;
|
|
59
|
+
readonly AUTH_SERVICE_CONFIG?: KeycloakAuthConfig | FirebaseAuthConfig;
|
|
60
|
+
}
|
|
61
|
+
declare function provideAuthenticationService(): EnvironmentProviders;
|
|
62
|
+
|
|
63
|
+
export { AUTHENTICATION_CONFIGURATION, AUTHENTICATION_SERVICE, AuthService, User, authMatcher, provideAuthenticationService };
|
|
64
|
+
export type { AuthenticationConfiguration, FirebaseAuthConfig, KeycloakAuthConfig };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as _angular_router from '@angular/router';
|
|
2
|
+
import { ActivatedRouteSnapshot, Routes } from '@angular/router';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
|
|
5
|
+
declare const authGuard: (route: ActivatedRouteSnapshot) => Promise<boolean>;
|
|
6
|
+
|
|
7
|
+
declare const authRoutes: Routes;
|
|
8
|
+
|
|
9
|
+
declare class AuthButtonComponent {
|
|
10
|
+
private readonly authService;
|
|
11
|
+
isAuthenticated: i0.Signal<boolean | undefined>;
|
|
12
|
+
readonly routes: _angular_router.Route[];
|
|
13
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthButtonComponent, never>;
|
|
14
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AuthButtonComponent, "pp-auth-button", never, {}, {}, never, never, true, never>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { AuthButtonComponent, authGuard, authRoutes };
|