@myrmidon/auth-jwt-admin 6.0.0 → 7.0.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/fesm2022/myrmidon-auth-jwt-admin.mjs +249 -269
- package/fesm2022/myrmidon-auth-jwt-admin.mjs.map +1 -1
- package/lib/components/auth-jwt-registration/auth-jwt-registration.component.d.ts +8 -9
- package/lib/components/password-strength-bar/password-strength-bar.component.d.ts +4 -5
- package/lib/components/state/user-list.repository.d.ts +2 -2
- package/lib/components/user-editor/user-editor.component.d.ts +28 -20
- package/lib/components/user-filter/user-filter.component.d.ts +15 -8
- package/lib/components/user-list/user-list.component.d.ts +7 -6
- package/lib/services/auth-jwt-account.service.d.ts +4 -3
- package/lib/validators/password.validators.d.ts +3 -0
- package/package.json +3 -3
- package/public-api.d.ts +0 -1
- package/lib/auth-jwt-admin.module.d.ts +0 -28
|
@@ -1,99 +1,47 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import * as i1
|
|
4
|
-
import {
|
|
2
|
+
import { inject, Injectable, input, output, Component, effect } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/forms';
|
|
4
|
+
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
5
|
+
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
5
6
|
import { retry, map, catchError, take } from 'rxjs/operators';
|
|
6
|
-
import * as
|
|
7
|
-
import {
|
|
8
|
-
import * as
|
|
9
|
-
import { HttpParams } from '@angular/common/http';
|
|
10
|
-
import * as i2 from '@myrmidon/ng-tools';
|
|
11
|
-
import { NgToolsModule } from '@myrmidon/ng-tools';
|
|
12
|
-
import { BehaviorSubject, tap } from 'rxjs';
|
|
13
|
-
import { PagedListStore } from '@myrmidon/paged-data-browsers';
|
|
14
|
-
import * as i5 from '@angular/material/button';
|
|
7
|
+
import * as i3 from '@angular/material/form-field';
|
|
8
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
9
|
+
import * as i2 from '@angular/material/button';
|
|
15
10
|
import { MatButtonModule } from '@angular/material/button';
|
|
16
|
-
import * as
|
|
11
|
+
import * as i4 from '@angular/material/icon';
|
|
17
12
|
import { MatIconModule } from '@angular/material/icon';
|
|
18
|
-
import * as
|
|
13
|
+
import * as i5 from '@angular/material/input';
|
|
19
14
|
import { MatInputModule } from '@angular/material/input';
|
|
20
|
-
import * as
|
|
21
|
-
import * as i9 from '@angular/material/progress-spinner';
|
|
15
|
+
import * as i6 from '@angular/material/progress-spinner';
|
|
22
16
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
23
|
-
import
|
|
17
|
+
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
18
|
+
import { ErrorService, EnvService } from '@myrmidon/ng-tools';
|
|
19
|
+
import { BehaviorSubject, tap } from 'rxjs';
|
|
20
|
+
import { PagedListStore } from '@myrmidon/paged-data-browsers';
|
|
21
|
+
import * as i7 from '@angular/material/tooltip';
|
|
24
22
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
23
|
+
import * as i5$1 from '@angular/material/paginator';
|
|
24
|
+
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
25
25
|
import '@angular/localize/init';
|
|
26
|
-
import * as
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import * as i5$1 from '@angular/material/expansion';
|
|
26
|
+
import * as i1$1 from '@angular/common';
|
|
27
|
+
import { CommonModule } from '@angular/common';
|
|
28
|
+
import * as i3$2 from '@angular/material/expansion';
|
|
30
29
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
31
|
-
import * as
|
|
32
|
-
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
33
|
-
import * as i8$1 from '@angular/material/progress-bar';
|
|
30
|
+
import * as i6$1 from '@angular/material/progress-bar';
|
|
34
31
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
35
|
-
import
|
|
32
|
+
import { AuthJwtService, GravatarService } from '@myrmidon/auth-jwt-login';
|
|
33
|
+
import { DialogService } from '@myrmidon/ngx-mat-tools';
|
|
34
|
+
import * as i3$1 from '@angular/material/checkbox';
|
|
36
35
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
37
|
-
import * as i12 from '@angular/common';
|
|
38
|
-
import { CommonModule } from '@angular/common';
|
|
39
|
-
import { RouterModule } from '@angular/router';
|
|
40
|
-
import { MatCardModule } from '@angular/material/card';
|
|
41
|
-
import { MatDialogModule } from '@angular/material/dialog';
|
|
42
|
-
|
|
43
|
-
class PasswordValidators {
|
|
44
|
-
/** "Standard" password validator for my API services. */
|
|
45
|
-
static standard() {
|
|
46
|
-
return (control) => {
|
|
47
|
-
if (!control.value) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
if (control.value.length < 8) {
|
|
51
|
-
return {
|
|
52
|
-
passwordtooshort: true,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
if (!/.*[A-Z].*/.test(control.value)) {
|
|
56
|
-
return {
|
|
57
|
-
noupperinpassword: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if (!/.*[a-z].*/.test(control.value)) {
|
|
61
|
-
return {
|
|
62
|
-
nolowerinpassword: true,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
if (!/.*[A-Z].*/.test(control.value)) {
|
|
66
|
-
return {
|
|
67
|
-
noupperinpassword: true,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
if (!/.*[-`~!@#$%^&*()_+=\[\]{};:'",.<>/?|\\].*/.test(control.value)) {
|
|
71
|
-
return {
|
|
72
|
-
nosymbolinpassword: true,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
static areEqual(controlName, otherControlName) {
|
|
79
|
-
return (control) => {
|
|
80
|
-
const g = control;
|
|
81
|
-
const a = g.controls[controlName];
|
|
82
|
-
const b = g.controls[otherControlName];
|
|
83
|
-
return a.value !== b.value
|
|
84
|
-
? {
|
|
85
|
-
areequal: true,
|
|
86
|
-
}
|
|
87
|
-
: null;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Service for managing user accounts with JWT authentication.
|
|
39
|
+
*/
|
|
92
40
|
class AuthJwtAccountService {
|
|
93
|
-
constructor(
|
|
94
|
-
this._http =
|
|
95
|
-
this._error =
|
|
96
|
-
this._env =
|
|
41
|
+
constructor() {
|
|
42
|
+
this._http = inject(HttpClient);
|
|
43
|
+
this._error = inject(ErrorService);
|
|
44
|
+
this._env = inject(EnvService);
|
|
97
45
|
}
|
|
98
46
|
/**
|
|
99
47
|
* Checks if the specified email address is registered on the server.
|
|
@@ -276,15 +224,67 @@ class AuthJwtAccountService {
|
|
|
276
224
|
.delete(this._env.get('apiUrl') + 'accounts/' + name)
|
|
277
225
|
.pipe(catchError(this._error.handleError));
|
|
278
226
|
}
|
|
279
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
280
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.
|
|
227
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: AuthJwtAccountService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
228
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: AuthJwtAccountService, providedIn: 'root' }); }
|
|
281
229
|
}
|
|
282
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: AuthJwtAccountService, decorators: [{
|
|
283
231
|
type: Injectable,
|
|
284
232
|
args: [{
|
|
285
233
|
providedIn: 'root',
|
|
286
234
|
}]
|
|
287
|
-
}]
|
|
235
|
+
}] });
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Password validators.
|
|
239
|
+
*/
|
|
240
|
+
class PasswordValidators {
|
|
241
|
+
/** "Standard" password validator for my API services. */
|
|
242
|
+
static standard() {
|
|
243
|
+
return (control) => {
|
|
244
|
+
if (!control.value) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
if (control.value.length < 8) {
|
|
248
|
+
return {
|
|
249
|
+
passwordtooshort: true,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if (!/.*[A-Z].*/.test(control.value)) {
|
|
253
|
+
return {
|
|
254
|
+
noupperinpassword: true,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (!/.*[a-z].*/.test(control.value)) {
|
|
258
|
+
return {
|
|
259
|
+
nolowerinpassword: true,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (!/.*[A-Z].*/.test(control.value)) {
|
|
263
|
+
return {
|
|
264
|
+
noupperinpassword: true,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
if (!/.*[-`~!@#$%^&*()_+=\[\]{};:'",.<>/?|\\].*/.test(control.value)) {
|
|
268
|
+
return {
|
|
269
|
+
nosymbolinpassword: true,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
static areEqual(controlName, otherControlName) {
|
|
276
|
+
return (control) => {
|
|
277
|
+
const g = control;
|
|
278
|
+
const a = g.controls[controlName];
|
|
279
|
+
const b = g.controls[otherControlName];
|
|
280
|
+
return a.value !== b.value
|
|
281
|
+
? {
|
|
282
|
+
areequal: true,
|
|
283
|
+
}
|
|
284
|
+
: null;
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
288
|
|
|
289
289
|
class UserListRepository {
|
|
290
290
|
get activeUser$() {
|
|
@@ -302,8 +302,8 @@ class UserListRepository {
|
|
|
302
302
|
get saving$() {
|
|
303
303
|
return this._saving$.asObservable();
|
|
304
304
|
}
|
|
305
|
-
constructor(
|
|
306
|
-
this._accService =
|
|
305
|
+
constructor() {
|
|
306
|
+
this._accService = inject(AuthJwtAccountService);
|
|
307
307
|
this._store = new PagedListStore(this);
|
|
308
308
|
this._activeUser$ = new BehaviorSubject(undefined);
|
|
309
309
|
this._loading$ = new BehaviorSubject(false);
|
|
@@ -399,19 +399,19 @@ class UserListRepository {
|
|
|
399
399
|
});
|
|
400
400
|
return promise;
|
|
401
401
|
}
|
|
402
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
403
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.
|
|
402
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserListRepository, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
403
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserListRepository, providedIn: 'root' }); }
|
|
404
404
|
}
|
|
405
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserListRepository, decorators: [{
|
|
406
406
|
type: Injectable,
|
|
407
407
|
args: [{ providedIn: 'root' }]
|
|
408
|
-
}], ctorParameters: () => [
|
|
408
|
+
}], ctorParameters: () => [] });
|
|
409
409
|
|
|
410
410
|
class PasswordStrengthBarComponent {
|
|
411
411
|
constructor() {
|
|
412
412
|
this._colors = ['#F00', '#F90', '#FF0', '#9F0', '#0F0'];
|
|
413
|
-
this.
|
|
414
|
-
this.strengthChange =
|
|
413
|
+
this.passwordToCheck = input();
|
|
414
|
+
this.strengthChange = output();
|
|
415
415
|
this.bars = [];
|
|
416
416
|
}
|
|
417
417
|
measureStrength(p) {
|
|
@@ -473,25 +473,34 @@ class PasswordStrengthBarComponent {
|
|
|
473
473
|
this.bars[n] = col;
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
477
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
476
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: PasswordStrengthBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
477
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.1", type: PasswordStrengthBarComponent, isStandalone: true, selector: "auth-jwt-password-strength-bar", inputs: { passwordToCheck: { classPropertyName: "passwordToCheck", publicName: "passwordToCheck", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { strengthChange: "strengthChange" }, usesOnChanges: true, ngImport: i0, template: "<div id=\"strength\">\r\n <small>strength:</small>\r\n <ul id=\"strengthBar\">\r\n <li class=\"point\" [style.background-color]=\"bars[0]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[1]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[2]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[3]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[4]\"></li>\r\n </ul>\r\n</div>\r\n", styles: ["ul#strengthBar{display:inline;list-style:none;margin:0 0 0 15px;padding:0;vertical-align:2px}li.point:last{margin:0!important}li.point{background:#ddd;border-radius:2px;display:inline-block;height:5px;margin-right:1px;width:20px}\n"] }); }
|
|
478
478
|
}
|
|
479
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
479
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: PasswordStrengthBarComponent, decorators: [{
|
|
480
480
|
type: Component,
|
|
481
|
-
args: [{ selector: 'auth-jwt-password-strength-bar',
|
|
482
|
-
}]
|
|
483
|
-
type: Input
|
|
484
|
-
}], strengthChange: [{
|
|
485
|
-
type: Output
|
|
486
|
-
}] } });
|
|
481
|
+
args: [{ selector: 'auth-jwt-password-strength-bar', template: "<div id=\"strength\">\r\n <small>strength:</small>\r\n <ul id=\"strengthBar\">\r\n <li class=\"point\" [style.background-color]=\"bars[0]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[1]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[2]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[3]\"></li>\r\n <li class=\"point\" [style.background-color]=\"bars[4]\"></li>\r\n </ul>\r\n</div>\r\n", styles: ["ul#strengthBar{display:inline;list-style:none;margin:0 0 0 15px;padding:0;vertical-align:2px}li.point:last{margin:0!important}li.point{background:#ddd;border-radius:2px;display:inline-block;height:5px;margin-right:1px;width:20px}\n"] }]
|
|
482
|
+
}] });
|
|
487
483
|
|
|
484
|
+
/**
|
|
485
|
+
* User registration form.
|
|
486
|
+
*/
|
|
488
487
|
class AuthJwtRegistrationComponent {
|
|
489
|
-
constructor(
|
|
490
|
-
this._snackbar =
|
|
491
|
-
this._accountService =
|
|
492
|
-
this._userRepository =
|
|
488
|
+
constructor() {
|
|
489
|
+
this._snackbar = inject(MatSnackBar);
|
|
490
|
+
this._accountService = inject(AuthJwtAccountService);
|
|
491
|
+
this._userRepository = inject(UserListRepository);
|
|
492
|
+
/**
|
|
493
|
+
* True if the registration should be confirmed automatically.
|
|
494
|
+
*/
|
|
495
|
+
this.autoConfirm = input();
|
|
496
|
+
/**
|
|
497
|
+
* Emitted when a user was successfully registered. Usually
|
|
498
|
+
* you should handle this to move away from the registration
|
|
499
|
+
* page.
|
|
500
|
+
*/
|
|
501
|
+
this.registered = output();
|
|
493
502
|
this.hide = true;
|
|
494
|
-
|
|
503
|
+
const formBuilder = inject(FormBuilder);
|
|
495
504
|
// form
|
|
496
505
|
this.email = formBuilder.control('', {
|
|
497
506
|
validators: [Validators.required, Validators.email],
|
|
@@ -611,7 +620,7 @@ class AuthJwtRegistrationComponent {
|
|
|
611
620
|
};
|
|
612
621
|
this.busy = true;
|
|
613
622
|
this._accountService
|
|
614
|
-
.register(model, this.autoConfirm)
|
|
623
|
+
.register(model, this.autoConfirm())
|
|
615
624
|
.pipe(take(1))
|
|
616
625
|
.subscribe({
|
|
617
626
|
next: () => {
|
|
@@ -627,37 +636,58 @@ class AuthJwtRegistrationComponent {
|
|
|
627
636
|
},
|
|
628
637
|
});
|
|
629
638
|
}
|
|
630
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
631
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: AuthJwtRegistrationComponent, isStandalone: false, selector: "auth-jwt-registration", inputs: { autoConfirm: "autoConfirm" }, outputs: { registered: "registered" }, ngImport: i0, template: "<div>\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\n <fieldset>\n <legend i18n=\"auth-jwt-admin\">registration</legend>\n <!-- email -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input\n matInput\n type=\"email\"\n id=\"email\"\n maxlength=\"256\"\n required\n autofocus\n spellcheck=\"false\"\n [formControl]=\"email\"\n />\n @if ( $any(email).errors?.required && (email.dirty || email.touched) )\n {\n <mat-error i18n=\"auth-jwt-admin\">email required</mat-error>\n } @if ($any(email).errors?.email && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid email</mat-error>\n } @if ( $any(email).errors?.uniqueEmail && (email.dirty ||\n email.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">email already registered</mat-error>\n }\n </mat-form-field>\n @if (email.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- name -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">username</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"name\"\n maxlength=\"50\"\n required\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\n spellcheck=\"false\"\n [formControl]=\"name\"\n />\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">username required</mat-error>\n } @if ($any(name).errors?.pattern && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid username</mat-error>\n } @if ( $any(name).errors?.uniqueName && (name.dirty || name.touched)\n ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >username already registered</mat-error\n >\n }\n </mat-form-field>\n @if (name.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- first name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">first name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"firstName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"firstName\"\n />\n @if ( firstName.hasError('required') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n first name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- last name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">last name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"lastName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"lastName\"\n />\n @if ( lastName.hasError('required') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n last name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- <div [formGroup]=\"passwords\"> -->\n <!-- password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"password\"\n autocomplete=\"new-password\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"password\"\n />\n <button\n type=\"button\"\n mat-icon-button\n matSuffix\n (click)=\"hide = !hide\"\n i18n-aria-label=\"auth-jwt-login\"\n aria-label=\"Hide password\"\n [attr.aria-pressed]=\"hide\"\n >\n <mat-icon>{{ hide ? \"visibility_off\" : \"visibility\" }}</mat-icon>\n </button>\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\n </auth-jwt-password-strength-bar>\n @if ( $any(password).errors?.required && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">password required</mat-error>\n } @if ( $any(password).errors?.passwordtooshort && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">at least 8 characters</mat-error>\n } @if ( $any(password).errors?.noupperinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 uppercase letter</mat-error\n >\n } @if ( $any(password).errors?.nolowerinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 lowercase letter</mat-error\n >\n } @if ( $any(password).errors?.nosymbolinpassword && (password.dirty\n || password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 punctuation/symbol</mat-error\n >\n }\n </mat-form-field>\n </div>\n\n <!-- confirm password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">confirm password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"confirmPassword\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"confirmPassword\"\n />\n </mat-form-field>\n </div>\n @if (form.errors?.areequal && confirmPassword.touched) {\n <div i18n=\"auth-jwt-admin\" style=\"color: red\">\n password differs from confirmation password\n </div>\n }\n\n <button\n i18n=\"auth-jwt-admin\"\n mat-flat-button\n type=\"submit\"\n color=\"primary\"\n class=\"mat-primary\"\n [disabled]=\"\n form.invalid || form.pristine || busy || name.pending || email.pending\n \"\n >\n register\n </button>\n @if (busy) {\n <mat-progress-spinner diameter=\"20\"></mat-progress-spinner>\n }\n </fieldset>\n </form>\n\n <details>\n <summary i18n=\"auth-jwt-admin\">Hints</summary>\n <div class=\"info\">\n <p i18n=\"auth-jwt-admin\">\n To register a new user, you must provide his email address, choose a\n password, and choose a username, which must be unique (you will be\n notified if another user has already taken that name). The username must\n include only letters/digits, start with a letter, and be no shorter than\n 3 characters, nor longer than 50.\n </p>\n <p i18n=\"auth-jwt-admin\">\n To promote a decent security level, the password must include at least 8\n characters, uppercase and lowercase letters, digits, and punctuation\n (like dashes, stops, parentheses, etc.).\n </p>\n <p i18n=\"auth-jwt-admin\">\n Once registered, if messaging is enabled on the server side the user\n will receive an email message to the email address you specified; he\n will have to click on the provided link to complete the registration\n process. Otherwise, you should edit the newly created user and confirm\n the email registration.\n </p>\n </div>\n </details>\n</div>\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}.info{column-width:600px}\n"], dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.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: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i9.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: PasswordStrengthBarComponent, selector: "auth-jwt-password-strength-bar", inputs: ["passwordToCheck"], outputs: ["strengthChange"] }] }); }
|
|
639
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: AuthJwtRegistrationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
640
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: AuthJwtRegistrationComponent, isStandalone: true, selector: "auth-jwt-registration", inputs: { autoConfirm: { classPropertyName: "autoConfirm", publicName: "autoConfirm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { registered: "registered" }, ngImport: i0, template: "<div>\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\n <fieldset>\n <legend i18n=\"auth-jwt-admin\">registration</legend>\n <!-- email -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input\n matInput\n type=\"email\"\n id=\"email\"\n maxlength=\"256\"\n required\n autofocus\n spellcheck=\"false\"\n [formControl]=\"email\"\n />\n @if ( $any(email).errors?.required && (email.dirty || email.touched) )\n {\n <mat-error i18n=\"auth-jwt-admin\">email required</mat-error>\n } @if ($any(email).errors?.email && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid email</mat-error>\n } @if ( $any(email).errors?.uniqueEmail && (email.dirty ||\n email.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">email already registered</mat-error>\n }\n </mat-form-field>\n @if (email.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- name -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">username</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"name\"\n maxlength=\"50\"\n required\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\n spellcheck=\"false\"\n [formControl]=\"name\"\n />\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">username required</mat-error>\n } @if ($any(name).errors?.pattern && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid username</mat-error>\n } @if ( $any(name).errors?.uniqueName && (name.dirty || name.touched)\n ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >username already registered</mat-error\n >\n }\n </mat-form-field>\n @if (name.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- first name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">first name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"firstName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"firstName\"\n />\n @if ( firstName.hasError('required') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n first name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- last name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">last name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"lastName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"lastName\"\n />\n @if ( lastName.hasError('required') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n last name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- <div [formGroup]=\"passwords\"> -->\n <!-- password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"password\"\n autocomplete=\"new-password\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"password\"\n />\n <button\n type=\"button\"\n mat-icon-button\n matSuffix\n (click)=\"hide = !hide\"\n i18n-aria-label=\"auth-jwt-login\"\n aria-label=\"Hide password\"\n [attr.aria-pressed]=\"hide\"\n >\n <mat-icon>{{ hide ? \"visibility_off\" : \"visibility\" }}</mat-icon>\n </button>\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\n </auth-jwt-password-strength-bar>\n @if ( $any(password).errors?.required && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">password required</mat-error>\n } @if ( $any(password).errors?.passwordtooshort && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">at least 8 characters</mat-error>\n } @if ( $any(password).errors?.noupperinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 uppercase letter</mat-error\n >\n } @if ( $any(password).errors?.nolowerinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 lowercase letter</mat-error\n >\n } @if ( $any(password).errors?.nosymbolinpassword && (password.dirty\n || password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 punctuation/symbol</mat-error\n >\n }\n </mat-form-field>\n </div>\n\n <!-- confirm password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">confirm password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"confirmPassword\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"confirmPassword\"\n />\n </mat-form-field>\n </div>\n @if (form.errors?.areequal && confirmPassword.touched) {\n <div i18n=\"auth-jwt-admin\" class=\"error\">\n password differs from confirmation password\n </div>\n }\n\n <button\n i18n=\"auth-jwt-admin\"\n mat-flat-button\n type=\"submit\"\n color=\"primary\"\n class=\"mat-primary\"\n [disabled]=\"\n form.invalid || form.pristine || busy || name.pending || email.pending\n \"\n >\n register\n </button>\n @if (busy) {\n <mat-progress-spinner diameter=\"20\"></mat-progress-spinner>\n }\n </fieldset>\n </form>\n\n <details>\n <summary i18n=\"auth-jwt-admin\">Hints</summary>\n <div class=\"info\">\n <p i18n=\"auth-jwt-admin\">\n To register a new user, you must provide his email address, choose a\n password, and choose a username, which must be unique (you will be\n notified if another user has already taken that name). The username must\n include only letters/digits, start with a letter, and be no shorter than\n 3 characters, nor longer than 50.\n </p>\n <p i18n=\"auth-jwt-admin\">\n To promote a decent security level, the password must include at least 8\n characters, uppercase and lowercase letters, digits, and punctuation\n (like dashes, stops, parentheses, etc.).\n </p>\n <p i18n=\"auth-jwt-admin\">\n Once registered, if messaging is enabled on the server side the user\n will receive an email message to the email address you specified; he\n will have to click on the provided link to complete the registration\n process. Otherwise, you should edit the newly created user and confirm\n the email registration.\n </p>\n </div>\n </details>\n</div>\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}.info{column-width:600px}.error{color:red}\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],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: PasswordStrengthBarComponent, selector: "auth-jwt-password-strength-bar", inputs: ["passwordToCheck"], outputs: ["strengthChange"] }] }); }
|
|
632
641
|
}
|
|
633
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
642
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: AuthJwtRegistrationComponent, decorators: [{
|
|
634
643
|
type: Component,
|
|
635
|
-
args: [{ selector: 'auth-jwt-registration',
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
644
|
+
args: [{ selector: 'auth-jwt-registration', imports: [
|
|
645
|
+
ReactiveFormsModule,
|
|
646
|
+
MatButtonModule,
|
|
647
|
+
MatFormFieldModule,
|
|
648
|
+
MatIconModule,
|
|
649
|
+
MatInputModule,
|
|
650
|
+
MatProgressSpinnerModule,
|
|
651
|
+
PasswordStrengthBarComponent,
|
|
652
|
+
], template: "<div>\n <form role=\"form\" [formGroup]=\"form\" (submit)=\"onSubmit()\">\n <fieldset>\n <legend i18n=\"auth-jwt-admin\">registration</legend>\n <!-- email -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n>email</mat-label>\n <input\n matInput\n type=\"email\"\n id=\"email\"\n maxlength=\"256\"\n required\n autofocus\n spellcheck=\"false\"\n [formControl]=\"email\"\n />\n @if ( $any(email).errors?.required && (email.dirty || email.touched) )\n {\n <mat-error i18n=\"auth-jwt-admin\">email required</mat-error>\n } @if ($any(email).errors?.email && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid email</mat-error>\n } @if ( $any(email).errors?.uniqueEmail && (email.dirty ||\n email.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">email already registered</mat-error>\n }\n </mat-form-field>\n @if (email.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- name -->\n <div class=\"form-row\">\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">username</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"name\"\n maxlength=\"50\"\n required\n pattern=\"^[a-zA-Z][a-zA-Z0-9]{2,49}$\"\n spellcheck=\"false\"\n [formControl]=\"name\"\n />\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">username required</mat-error>\n } @if ($any(name).errors?.pattern && (name.dirty || name.touched)) {\n <mat-error i18n=\"auth-jwt-admin\">invalid username</mat-error>\n } @if ( $any(name).errors?.uniqueName && (name.dirty || name.touched)\n ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >username already registered</mat-error\n >\n }\n </mat-form-field>\n @if (name.pending) {\n <mat-icon>hourglass</mat-icon>\n }\n </div>\n\n <!-- first name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">first name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"firstName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"firstName\"\n />\n @if ( firstName.hasError('required') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n first name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- last name -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">last name</mat-label>\n <input\n matInput\n type=\"text\"\n id=\"lastName\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"lastName\"\n />\n @if ( lastName.hasError('required') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\" class=\"text-danger small\">\n last name required\n </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- <div [formGroup]=\"passwords\"> -->\n <!-- password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"password\"\n autocomplete=\"new-password\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"password\"\n />\n <button\n type=\"button\"\n mat-icon-button\n matSuffix\n (click)=\"hide = !hide\"\n i18n-aria-label=\"auth-jwt-login\"\n aria-label=\"Hide password\"\n [attr.aria-pressed]=\"hide\"\n >\n <mat-icon>{{ hide ? \"visibility_off\" : \"visibility\" }}</mat-icon>\n </button>\n <auth-jwt-password-strength-bar [passwordToCheck]=\"password.value\">\n </auth-jwt-password-strength-bar>\n @if ( $any(password).errors?.required && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">password required</mat-error>\n } @if ( $any(password).errors?.passwordtooshort && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\">at least 8 characters</mat-error>\n } @if ( $any(password).errors?.noupperinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 uppercase letter</mat-error\n >\n } @if ( $any(password).errors?.nolowerinpassword && (password.dirty ||\n password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 lowercase letter</mat-error\n >\n } @if ( $any(password).errors?.nosymbolinpassword && (password.dirty\n || password.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"\n >at least 1 punctuation/symbol</mat-error\n >\n }\n </mat-form-field>\n </div>\n\n <!-- confirm password -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">confirm password</mat-label>\n <input\n matInput\n [type]=\"hide ? 'password' : 'text'\"\n name=\"confirmPassword\"\n maxlength=\"50\"\n required\n spellcheck=\"false\"\n [formControl]=\"confirmPassword\"\n />\n </mat-form-field>\n </div>\n @if (form.errors?.areequal && confirmPassword.touched) {\n <div i18n=\"auth-jwt-admin\" class=\"error\">\n password differs from confirmation password\n </div>\n }\n\n <button\n i18n=\"auth-jwt-admin\"\n mat-flat-button\n type=\"submit\"\n color=\"primary\"\n class=\"mat-primary\"\n [disabled]=\"\n form.invalid || form.pristine || busy || name.pending || email.pending\n \"\n >\n register\n </button>\n @if (busy) {\n <mat-progress-spinner diameter=\"20\"></mat-progress-spinner>\n }\n </fieldset>\n </form>\n\n <details>\n <summary i18n=\"auth-jwt-admin\">Hints</summary>\n <div class=\"info\">\n <p i18n=\"auth-jwt-admin\">\n To register a new user, you must provide his email address, choose a\n password, and choose a username, which must be unique (you will be\n notified if another user has already taken that name). The username must\n include only letters/digits, start with a letter, and be no shorter than\n 3 characters, nor longer than 50.\n </p>\n <p i18n=\"auth-jwt-admin\">\n To promote a decent security level, the password must include at least 8\n characters, uppercase and lowercase letters, digits, and punctuation\n (like dashes, stops, parentheses, etc.).\n </p>\n <p i18n=\"auth-jwt-admin\">\n Once registered, if messaging is enabled on the server side the user\n will receive an email message to the email address you specified; he\n will have to click on the provided link to complete the registration\n process. Otherwise, you should edit the newly created user and confirm\n the email registration.\n </p>\n </div>\n </details>\n</div>\n", styles: ["mat-form-field{width:400px}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}details{margin:8px}.info{column-width:600px}.error{color:red}\n"] }]
|
|
653
|
+
}], ctorParameters: () => [] });
|
|
641
654
|
|
|
655
|
+
/**
|
|
656
|
+
* Users filter.
|
|
657
|
+
*/
|
|
642
658
|
class UserFilterComponent {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
this.
|
|
652
|
-
|
|
653
|
-
|
|
659
|
+
constructor() {
|
|
660
|
+
/**
|
|
661
|
+
* The filter.
|
|
662
|
+
*/
|
|
663
|
+
this.filter = input();
|
|
664
|
+
/**
|
|
665
|
+
* Whether the filter is disabled.
|
|
666
|
+
*/
|
|
667
|
+
this.disabled = input();
|
|
668
|
+
/**
|
|
669
|
+
* Event emitted when the filter changes.
|
|
670
|
+
*/
|
|
671
|
+
this.filterChange = output();
|
|
672
|
+
const formBuilder = inject(FormBuilder);
|
|
654
673
|
// form
|
|
655
674
|
this.name = formBuilder.control(null);
|
|
656
675
|
this.form = formBuilder.group({
|
|
657
676
|
name: this.name,
|
|
658
677
|
});
|
|
659
|
-
//
|
|
660
|
-
|
|
678
|
+
// update form when filter changes
|
|
679
|
+
effect(() => {
|
|
680
|
+
this.updateForm(this.filter() || undefined);
|
|
681
|
+
});
|
|
682
|
+
// disable form when disabled
|
|
683
|
+
effect(() => {
|
|
684
|
+
if (this.disabled()) {
|
|
685
|
+
this.form.disable();
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
this.form.enable();
|
|
689
|
+
}
|
|
690
|
+
});
|
|
661
691
|
}
|
|
662
692
|
updateForm(filter) {
|
|
663
693
|
if (!filter) {
|
|
@@ -681,40 +711,51 @@ class UserFilterComponent {
|
|
|
681
711
|
this._filter = this.getFilter();
|
|
682
712
|
this.filterChange.emit(this._filter);
|
|
683
713
|
}
|
|
684
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
685
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
714
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
715
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.1", type: UserFilterComponent, isStandalone: true, selector: "auth-jwt-user-filter", inputs: { filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"apply()\">\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n=\"auth-jwt-admin\">name or ID</mat-label>\r\n <input matInput [formControl]=\"name\" />\r\n <button\r\n mat-icon-button\r\n matSuffix\r\n type=\"button\"\r\n (click)=\"reset()\"\r\n i18n-matTooltip=\"auth-jwt-admin\"\r\n matTooltip=\"Reset filters\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n\r\n <button\r\n id=\"apply\"\r\n type=\"submit\"\r\n mat-icon-button\r\n [disabled]=\"disabled()\"\r\n i18n-matTooltip=\"auth-jwt-admin\"\r\n matTooltip=\"Apply filters\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#apply{margin-top:-20px}\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],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
686
716
|
}
|
|
687
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
717
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserFilterComponent, decorators: [{
|
|
688
718
|
type: Component,
|
|
689
|
-
args: [{ selector: 'auth-jwt-user-filter',
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
719
|
+
args: [{ selector: 'auth-jwt-user-filter', imports: [
|
|
720
|
+
ReactiveFormsModule,
|
|
721
|
+
MatButtonModule,
|
|
722
|
+
MatFormFieldModule,
|
|
723
|
+
MatIconModule,
|
|
724
|
+
MatInputModule,
|
|
725
|
+
MatTooltipModule,
|
|
726
|
+
], template: "<form [formGroup]=\"form\" (submit)=\"apply()\">\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label i18n=\"auth-jwt-admin\">name or ID</mat-label>\r\n <input matInput [formControl]=\"name\" />\r\n <button\r\n mat-icon-button\r\n matSuffix\r\n type=\"button\"\r\n (click)=\"reset()\"\r\n i18n-matTooltip=\"auth-jwt-admin\"\r\n matTooltip=\"Reset filters\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n\r\n <button\r\n id=\"apply\"\r\n type=\"submit\"\r\n mat-icon-button\r\n [disabled]=\"disabled()\"\r\n i18n-matTooltip=\"auth-jwt-admin\"\r\n matTooltip=\"Apply filters\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#apply{margin-top:-20px}\n"] }]
|
|
727
|
+
}], ctorParameters: () => [] });
|
|
697
728
|
|
|
729
|
+
/**
|
|
730
|
+
* User editor form.
|
|
731
|
+
*/
|
|
698
732
|
class UserEditorComponent {
|
|
699
|
-
|
|
700
|
-
this.
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
733
|
+
constructor() {
|
|
734
|
+
this._authService = inject(AuthJwtService);
|
|
735
|
+
/**
|
|
736
|
+
* The user to edit.
|
|
737
|
+
*/
|
|
738
|
+
this.user = input(undefined);
|
|
739
|
+
/**
|
|
740
|
+
* Emitted when user changes.
|
|
741
|
+
*/
|
|
742
|
+
this.userChange = output();
|
|
743
|
+
/**
|
|
744
|
+
* Emitted when the user requests to close the user editor.
|
|
745
|
+
*/
|
|
746
|
+
this.editorClose = output();
|
|
747
|
+
const formBuilder = inject(FormBuilder);
|
|
711
748
|
// form
|
|
712
749
|
this.email = formBuilder.control(null, [
|
|
713
750
|
Validators.required,
|
|
714
751
|
Validators.email,
|
|
715
752
|
]);
|
|
716
|
-
this.emailConfirmed = formBuilder.control(false
|
|
717
|
-
|
|
753
|
+
this.emailConfirmed = formBuilder.control(false, {
|
|
754
|
+
nonNullable: true,
|
|
755
|
+
});
|
|
756
|
+
this.lockoutEnabled = formBuilder.control(false, {
|
|
757
|
+
nonNullable: true,
|
|
758
|
+
});
|
|
718
759
|
this.firstName = formBuilder.control(null, [
|
|
719
760
|
Validators.required,
|
|
720
761
|
Validators.maxLength(50),
|
|
@@ -732,34 +773,40 @@ class UserEditorComponent {
|
|
|
732
773
|
lastName: this.lastName,
|
|
733
774
|
roles: this.roles,
|
|
734
775
|
});
|
|
776
|
+
// update form when user changes
|
|
777
|
+
effect(() => {
|
|
778
|
+
this.updateForm(this.user() || undefined);
|
|
779
|
+
});
|
|
735
780
|
}
|
|
736
|
-
ngOnInit() { }
|
|
737
781
|
updateForm(user) {
|
|
738
782
|
if (!user) {
|
|
739
783
|
this.form.reset();
|
|
740
784
|
}
|
|
741
785
|
else {
|
|
742
786
|
this.email.setValue(user.email);
|
|
743
|
-
this.emailConfirmed.setValue(user.emailConfirmed);
|
|
744
|
-
this.lockoutEnabled.setValue(user.lockoutEnabled);
|
|
745
|
-
this.firstName.setValue(user.firstName);
|
|
746
|
-
this.lastName.setValue(user.lastName);
|
|
787
|
+
this.emailConfirmed.setValue(user.emailConfirmed || false);
|
|
788
|
+
this.lockoutEnabled.setValue(user.lockoutEnabled || false);
|
|
789
|
+
this.firstName.setValue(user.firstName || '');
|
|
790
|
+
this.lastName.setValue(user.lastName || '');
|
|
747
791
|
if (user.roles?.length > 0) {
|
|
748
792
|
this.roles.setValue(user.roles.join(' '));
|
|
749
793
|
}
|
|
750
794
|
else {
|
|
751
795
|
this.roles.setValue(null);
|
|
752
796
|
}
|
|
797
|
+
this.unlocked =
|
|
798
|
+
user.lockoutEnabled &&
|
|
799
|
+
(!user.lockoutEnd || user.lockoutEnd < this._authService.getUTCDate());
|
|
753
800
|
}
|
|
754
801
|
}
|
|
755
802
|
getUserFromForm() {
|
|
756
803
|
return {
|
|
757
|
-
userName: this.
|
|
758
|
-
email: this.email.value,
|
|
804
|
+
userName: this.user()?.userName || '',
|
|
805
|
+
email: this.email.value || '',
|
|
759
806
|
emailConfirmed: this.emailConfirmed.value,
|
|
760
807
|
lockoutEnabled: this.lockoutEnabled.value,
|
|
761
|
-
firstName: this.firstName.value,
|
|
762
|
-
lastName: this.lastName.value,
|
|
808
|
+
firstName: this.firstName.value || '',
|
|
809
|
+
lastName: this.lastName.value || '',
|
|
763
810
|
roles: this.roles.value
|
|
764
811
|
? this.roles.value.split(' ').filter((s) => s)
|
|
765
812
|
: [],
|
|
@@ -769,8 +816,9 @@ class UserEditorComponent {
|
|
|
769
816
|
if (this.unlocked) {
|
|
770
817
|
return;
|
|
771
818
|
}
|
|
772
|
-
|
|
773
|
-
|
|
819
|
+
const user = this.getUserFromForm();
|
|
820
|
+
user.lockoutEnd = this._authService.getUTCDate();
|
|
821
|
+
this.userChange.emit(user);
|
|
774
822
|
}
|
|
775
823
|
close() {
|
|
776
824
|
this.editorClose.emit();
|
|
@@ -781,25 +829,31 @@ class UserEditorComponent {
|
|
|
781
829
|
}
|
|
782
830
|
this.userChange.emit(this.getUserFromForm());
|
|
783
831
|
}
|
|
784
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
785
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.
|
|
832
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
833
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: UserEditorComponent, isStandalone: true, selector: "auth-jwt-user-editor", inputs: { user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { userChange: "userChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n @if (email.hasError('required') && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> email address required </mat-error>\n } @if (email.hasError('pattern') && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> invalid email address </mat-error>\n }\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n=\"auth-jwt-admin\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n=\"auth-jwt-admin\"\n >lockout enabled</mat-checkbox\n >\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon class=\"mat-primary\">lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n @if ( firstName.hasError('required') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> first name required </mat-error>\n } @if ( firstName.hasError('maxlength') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> first name too long </mat-error>\n }\n </mat-form-field>\n\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n @if ( lastName.hasError('required') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> last name required </mat-error>\n } @if ( lastName.hasError('maxlength') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> last name too long </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n @if (roles.hasError('maxlength') && (roles.dirty || roles.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> too long </mat-error>\n }\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Save user\"\n >\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\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],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
786
834
|
}
|
|
787
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
835
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserEditorComponent, decorators: [{
|
|
788
836
|
type: Component,
|
|
789
|
-
args: [{ selector: 'auth-jwt-user-editor',
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
837
|
+
args: [{ selector: 'auth-jwt-user-editor', imports: [
|
|
838
|
+
ReactiveFormsModule,
|
|
839
|
+
MatButtonModule,
|
|
840
|
+
MatCheckboxModule,
|
|
841
|
+
MatFormFieldModule,
|
|
842
|
+
MatIconModule,
|
|
843
|
+
MatInputModule,
|
|
844
|
+
MatTooltipModule,
|
|
845
|
+
], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div class=\"form-row\">\n <!-- email -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">email</mat-label>\n <input type=\"text\" matInput [formControl]=\"email\" />\n @if (email.hasError('required') && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> email address required </mat-error>\n } @if (email.hasError('pattern') && (email.dirty || email.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> invalid email address </mat-error>\n }\n </mat-form-field>\n\n <!-- emailConfirmed -->\n <mat-checkbox [formControl]=\"emailConfirmed\" i18n=\"auth-jwt-admin\"\n >email address confirmed</mat-checkbox\n >\n </div>\n\n <!-- lockoutEnabled -->\n <div class=\"form-row\">\n <mat-checkbox [formControl]=\"lockoutEnabled\" i18n=\"auth-jwt-admin\"\n >lockout enabled</mat-checkbox\n >\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"endLockout()\"\n [disabled]=\"unlocked\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Unlock this user if locked\"\n >\n <mat-icon class=\"mat-primary\">lock_open</mat-icon>\n </button>\n </div>\n\n <div class=\"form-row\">\n <!-- firstName -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">first name</mat-label>\n <input type=\"text\" matInput [formControl]=\"firstName\" />\n @if ( firstName.hasError('required') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> first name required </mat-error>\n } @if ( firstName.hasError('maxlength') && (firstName.dirty ||\n firstName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> first name too long </mat-error>\n }\n </mat-form-field>\n\n <!-- lastName -->\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">last name</mat-label>\n <input type=\"text\" matInput [formControl]=\"lastName\" />\n @if ( lastName.hasError('required') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> last name required </mat-error>\n } @if ( lastName.hasError('maxlength') && (lastName.dirty ||\n lastName.touched) ) {\n <mat-error i18n=\"auth-jwt-admin\"> last name too long </mat-error>\n }\n </mat-form-field>\n </div>\n\n <!-- roles -->\n <div>\n <mat-form-field>\n <mat-label i18n=\"auth-jwt-admin\">roles</mat-label>\n <input type=\"text\" matInput [formControl]=\"roles\" />\n @if (roles.hasError('maxlength') && (roles.dirty || roles.touched)) {\n <mat-error i18n=\"auth-jwt-admin\"> too long </mat-error>\n }\n <mat-hint i18n>roles (separated by space)</mat-hint>\n </mat-form-field>\n </div>\n\n <!-- buttons -->\n <br />\n <div>\n <button\n type=\"button\"\n mat-icon-button\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Close\"\n (click)=\"close()\"\n >\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\n </button>\n <button\n type=\"submit\"\n mat-icon-button\n color=\"primary\"\n [disabled]=\"form.invalid\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Save user\"\n >\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
846
|
+
}], ctorParameters: () => [] });
|
|
797
847
|
|
|
848
|
+
/**
|
|
849
|
+
* List of users.
|
|
850
|
+
*/
|
|
798
851
|
class UserListComponent {
|
|
799
|
-
constructor(
|
|
800
|
-
this._repository =
|
|
801
|
-
this._dialogService =
|
|
802
|
-
this._gravatarService =
|
|
852
|
+
constructor() {
|
|
853
|
+
this._repository = inject(UserListRepository);
|
|
854
|
+
this._dialogService = inject(DialogService);
|
|
855
|
+
this._gravatarService = inject(GravatarService);
|
|
856
|
+
const _repository = this._repository;
|
|
803
857
|
this.filter$ = _repository.filter$;
|
|
804
858
|
this.page$ = _repository.page$;
|
|
805
859
|
this.active$ = _repository.activeUser$;
|
|
@@ -830,7 +884,9 @@ class UserListComponent {
|
|
|
830
884
|
this._repository.setActiveUser(null);
|
|
831
885
|
}
|
|
832
886
|
saveActiveUser(user) {
|
|
833
|
-
|
|
887
|
+
if (user) {
|
|
888
|
+
this._repository.updateActiveUser(user);
|
|
889
|
+
}
|
|
834
890
|
this._repository.setActiveUser(null);
|
|
835
891
|
}
|
|
836
892
|
onUserEditorClose() {
|
|
@@ -839,101 +895,25 @@ class UserListComponent {
|
|
|
839
895
|
getGravatarUrl(email, options) {
|
|
840
896
|
return this._gravatarService.buildGravatarUrl(email, options);
|
|
841
897
|
}
|
|
842
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.
|
|
843
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.
|
|
898
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
899
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: UserListComponent, isStandalone: true, selector: "auth-jwt-user-list", ngImport: i0, template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter\n [filter]=\"filter$ | async\"\n (filterChange)=\"onFilterChange($event)\"\n ></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n @if (page$ | async; as page) {\n <div id=\"list\">\n @if (loading$ | async) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n=\"auth-jwt-admin\">name</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">first</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">last</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">email</th>\n <th i18n=\"auth-jwt-admin\">roles</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n @for (user of page.items; track user) {\n <tr>\n <td class=\"fit-width\">\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon class=\"mat-primary\">mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\n </button>\n </td>\n <td class=\"fit-width\">\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, { size: '32' })\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n }\n </tbody>\n </table>\n <!-- paginator -->\n <div class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip=\"auth-jwt-admin\"\n matTooltip=\"Refresh list\"\n (click)=\"reset()\"\n >\n <mat-icon class=\"mat-warn\">autorenew</mat-icon>\n </button>\n <mat-paginator\n [length]=\"page.total\"\n [pageIndex]=\"page.pageNumber - 1\"\n [pageSize]=\"page.pageSize\"\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\n (page)=\"onPageChange($event)\"\n [showFirstLastButtons]=\"true\"\n ></mat-paginator>\n </div>\n </div>\n }\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n @if (active$ | async; as active) {\n <div>\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n }\n </mat-expansion-panel>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.fit-width{width:1px;white-space:nowrap}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i3$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i5$1.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i6$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: UserEditorComponent, selector: "auth-jwt-user-editor", inputs: ["user"], outputs: ["userChange", "editorClose"] }, { kind: "component", type: UserFilterComponent, selector: "auth-jwt-user-filter", inputs: ["filter", "disabled"], outputs: ["filterChange"] }] }); }
|
|
844
900
|
}
|
|
845
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.
|
|
901
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: UserListComponent, decorators: [{
|
|
846
902
|
type: Component,
|
|
847
|
-
args: [{ selector: 'auth-jwt-user-list',
|
|
848
|
-
}], ctorParameters: () => [{ type: UserListRepository }, { type: i2$3.DialogService }, { type: i2$2.GravatarService }] });
|
|
849
|
-
|
|
850
|
-
class AuthJwtAdminModule {
|
|
851
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: AuthJwtAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
852
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: AuthJwtAdminModule, declarations: [AuthJwtRegistrationComponent,
|
|
853
|
-
PasswordStrengthBarComponent,
|
|
854
|
-
UserFilterComponent,
|
|
855
|
-
UserListComponent,
|
|
856
|
-
UserEditorComponent], imports: [CommonModule,
|
|
857
|
-
FormsModule,
|
|
858
|
-
RouterModule,
|
|
859
|
-
ReactiveFormsModule,
|
|
860
|
-
// material
|
|
861
|
-
MatButtonModule,
|
|
862
|
-
MatCardModule,
|
|
863
|
-
MatCheckboxModule,
|
|
864
|
-
MatDialogModule,
|
|
865
|
-
MatExpansionModule,
|
|
866
|
-
MatIconModule,
|
|
867
|
-
MatInputModule,
|
|
868
|
-
MatPaginatorModule,
|
|
869
|
-
MatProgressBarModule,
|
|
870
|
-
MatProgressSpinnerModule,
|
|
871
|
-
MatSnackBarModule,
|
|
872
|
-
MatTooltipModule,
|
|
873
|
-
AuthJwtLoginModule,
|
|
874
|
-
NgToolsModule], exports: [AuthJwtRegistrationComponent,
|
|
875
|
-
PasswordStrengthBarComponent,
|
|
876
|
-
UserFilterComponent,
|
|
877
|
-
UserListComponent] }); }
|
|
878
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: AuthJwtAdminModule, imports: [CommonModule,
|
|
879
|
-
FormsModule,
|
|
880
|
-
RouterModule,
|
|
881
|
-
ReactiveFormsModule,
|
|
882
|
-
// material
|
|
883
|
-
MatButtonModule,
|
|
884
|
-
MatCardModule,
|
|
885
|
-
MatCheckboxModule,
|
|
886
|
-
MatDialogModule,
|
|
887
|
-
MatExpansionModule,
|
|
888
|
-
MatIconModule,
|
|
889
|
-
MatInputModule,
|
|
890
|
-
MatPaginatorModule,
|
|
891
|
-
MatProgressBarModule,
|
|
892
|
-
MatProgressSpinnerModule,
|
|
893
|
-
MatSnackBarModule,
|
|
894
|
-
MatTooltipModule,
|
|
895
|
-
AuthJwtLoginModule,
|
|
896
|
-
NgToolsModule] }); }
|
|
897
|
-
}
|
|
898
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: AuthJwtAdminModule, decorators: [{
|
|
899
|
-
type: NgModule,
|
|
900
|
-
args: [{
|
|
901
|
-
declarations: [
|
|
902
|
-
AuthJwtRegistrationComponent,
|
|
903
|
-
PasswordStrengthBarComponent,
|
|
904
|
-
UserFilterComponent,
|
|
905
|
-
UserListComponent,
|
|
906
|
-
UserEditorComponent,
|
|
907
|
-
],
|
|
908
|
-
exports: [
|
|
909
|
-
AuthJwtRegistrationComponent,
|
|
910
|
-
PasswordStrengthBarComponent,
|
|
911
|
-
UserFilterComponent,
|
|
912
|
-
UserListComponent,
|
|
913
|
-
],
|
|
914
|
-
imports: [
|
|
903
|
+
args: [{ selector: 'auth-jwt-user-list', imports: [
|
|
915
904
|
CommonModule,
|
|
916
|
-
FormsModule,
|
|
917
|
-
RouterModule,
|
|
918
905
|
ReactiveFormsModule,
|
|
919
|
-
// material
|
|
920
906
|
MatButtonModule,
|
|
921
|
-
MatCardModule,
|
|
922
|
-
MatCheckboxModule,
|
|
923
|
-
MatDialogModule,
|
|
924
907
|
MatExpansionModule,
|
|
925
908
|
MatIconModule,
|
|
926
909
|
MatInputModule,
|
|
927
910
|
MatPaginatorModule,
|
|
928
911
|
MatProgressBarModule,
|
|
929
|
-
MatProgressSpinnerModule,
|
|
930
|
-
MatSnackBarModule,
|
|
931
912
|
MatTooltipModule,
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
],
|
|
935
|
-
|
|
936
|
-
}] });
|
|
913
|
+
UserEditorComponent,
|
|
914
|
+
UserFilterComponent,
|
|
915
|
+
], template: "<div id=\"container\">\n <div>\n <!-- filters -->\n <div id=\"filters\">\n <auth-jwt-user-filter\n [filter]=\"filter$ | async\"\n (filterChange)=\"onFilterChange($event)\"\n ></auth-jwt-user-filter>\n </div>\n\n <!-- list -->\n @if (page$ | async; as page) {\n <div id=\"list\">\n @if (loading$ | async) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n <table>\n <thead>\n <td></td>\n <td></td>\n <th i18n=\"auth-jwt-admin\">name</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">first</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">last</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">email</th>\n <th i18n=\"auth-jwt-admin\">roles</th>\n <th i18n=\"auth-jwt-admin\" class=\"noif-lt-md\">lock end</th>\n </thead>\n <tbody>\n @for (user of page.items; track user) {\n <tr>\n <td class=\"fit-width\">\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Edit this user\"\n color=\"primary\"\n (click)=\"setActiveUser(user)\"\n >\n <mat-icon class=\"mat-primary\">mode_edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n i18n-matTooltip=\"auth-jwt-admin\"\n matTooltip=\"Delete this user\"\n color=\"warn\"\n (click)=\"deleteUser(user)\"\n >\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\n </button>\n </td>\n <td class=\"fit-width\">\n <img\n alt=\"avatar\"\n [src]=\"getGravatarUrl(user.email, { size: '32' })\"\n [alt]=\"user.userName\"\n />\n </td>\n <td>{{ user.userName }}</td>\n <td class=\"noif-lt-md\">{{ user.firstName }}</td>\n <td class=\"noif-lt-md\">{{ user.lastName }}</td>\n <td class=\"noif-lt-md\">\n <a [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n </td>\n <td>{{ user.roles.join(\" \") }}</td>\n <td class=\"noif-lt-md\">{{ user.lockoutEnd }}</td>\n </tr>\n }\n </tbody>\n </table>\n <!-- paginator -->\n <div class=\"form-row\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n i18n-matmatTooltip=\"auth-jwt-admin\"\n matTooltip=\"Refresh list\"\n (click)=\"reset()\"\n >\n <mat-icon class=\"mat-warn\">autorenew</mat-icon>\n </button>\n <mat-paginator\n [length]=\"page.total\"\n [pageIndex]=\"page.pageNumber - 1\"\n [pageSize]=\"page.pageSize\"\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\n (page)=\"onPageChange($event)\"\n [showFirstLastButtons]=\"true\"\n ></mat-paginator>\n </div>\n </div>\n }\n </div>\n\n <!-- editor -->\n <mat-expansion-panel\n id=\"editor\"\n [expanded]=\"active$ | async\"\n [disabled]=\"!(active$ | async)\"\n >\n @if (active$ | async; as active) {\n <div>\n <fieldset>\n <legend>{{ active.userName }}</legend>\n <auth-jwt-user-editor\n [user]=\"active\"\n (userChange)=\"saveActiveUser($event)\"\n (editorClose)=\"resetActiveUser()\"\n ></auth-jwt-user-editor>\n </fieldset>\n </div>\n }\n </mat-expansion-panel>\n</div>\n", styles: ["tr:nth-child(odd){background-color:#f8f8f8}th{padding:0 8px;text-align:left;color:silver;font-weight:400}td{padding:0 8px}td.fit-width{width:1px;white-space:nowrap}table{width:100%;border-collapse:collapse}fieldset{border:1px solid silver;border-radius:8px;padding:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}div#filters{grid-area:filters}div#list{grid-area:list}div#editor{grid-area:editor}div#container{display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:1fr;grid-template-areas:\"filters\" \"list\" \"editor\";gap:8px}@media only screen and (max-width: 959px){.noif-lt-md{display:none}}@media only screen and (min-width: 1920px){div#container{grid-template-rows:auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"filters filters\" \"list editor\"}}\n"] }]
|
|
916
|
+
}], ctorParameters: () => [] });
|
|
937
917
|
|
|
938
918
|
/*
|
|
939
919
|
* Public API Surface of auth-jwt-admin
|
|
@@ -943,5 +923,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
|
|
|
943
923
|
* Generated bundle index. Do not edit.
|
|
944
924
|
*/
|
|
945
925
|
|
|
946
|
-
export { AuthJwtAccountService,
|
|
926
|
+
export { AuthJwtAccountService, AuthJwtRegistrationComponent, PasswordStrengthBarComponent, PasswordValidators, UserFilterComponent, UserListComponent, UserListRepository };
|
|
947
927
|
//# sourceMappingURL=myrmidon-auth-jwt-admin.mjs.map
|