@dbg-riskit/angular-login 9999.9999.9999-rc.63199 → 9999.9999.9999-rc.6692537

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/docs/README.md CHANGED
@@ -1,13 +1,12 @@
1
- ![CI](https://github.deutsche-boerse.de/dev/risk-angular-common/workflows/CI/badge.svg?event=push)
2
- ![lint-bash](https://github.deutsche-boerse.de/dev/risk-angular-common/workflows/lint-bash/badge.svg?event=push)
3
- ![lint-docker](https://github.deutsche-boerse.de/dev/risk-angular-common/workflows/lint-docker/badge.svg?event=push)
1
+ ![CI](https://github.deutsche-boerse.de/RiskIT/risk-angular-common/workflows/CI/badge.svg?event=push)
2
+ ![lint-bash](https://github.deutsche-boerse.de/RiskIT/risk-angular-common/workflows/lint-bash/badge.svg?event=push)
3
+ ![lint-docker](https://github.deutsche-boerse.de/RiskIT/risk-angular-common/workflows/lint-docker/badge.svg?event=push)
4
4
 
5
5
  # risk-angular-common (Angular 13 and @angular/material based library for RiskIT applications)
6
6
 
7
7
  Used by:
8
- - [dev/DAVe-UI](https://github.deutsche-boerse.de/dev/DAVe-UI)
9
- - [dev/DAVe-MarginEstimator-UI](https://github.deutsche-boerse.de/dev/DAVe-MarginEstimator-UI)
10
- - [dev/MDH-UI](https://github.deutsche-boerse.de/dev/MDH-UI)
8
+ - [RiskIT/CPME-UI](https://github.deutsche-boerse.de/RiskIT/CPME-UI)
9
+ - [RiskIT/MDH-UI](https://github.deutsche-boerse.de/RiskIT/MDH-UI)
11
10
  - [RiskIT/openid-k8s-token-generator](https://github.deutsche-boerse.de/RiskIT/openid-k8s-token-generator)
12
11
 
13
12
  ## Packages
@@ -0,0 +1,151 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, ChangeDetectionStrategy, Component, Directive, input } from '@angular/core';
3
+ import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import * as i1 from '@angular/forms';
5
+ import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
6
+ import { MatButton } from '@angular/material/button';
7
+ import { MatCard, MatCardActions, MatCardContent, MatCardHeader, MatCardTitle } from '@angular/material/card';
8
+ import { MatFormField } from '@angular/material/form-field';
9
+ import { MatIcon } from '@angular/material/icon';
10
+ import { MatInput } from '@angular/material/input';
11
+ import { MatProgressSpinner } from '@angular/material/progress-spinner';
12
+ import { AuthRoutingFlowService } from '@dbg-riskit/angular-auth';
13
+ import { AUTH_PROVIDER, SECONDARY_LOGO } from '@dbg-riskit/angular-common';
14
+ import { toErrorMessage } from '@dbg-riskit/angular-error';
15
+ import { RiskFlexComponent, RiskFlexSpacerComponent, RiskMessageComponent } from '@dbg-riskit/angular-view';
16
+ import { switchMap, first } from 'rxjs/operators';
17
+ import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
18
+
19
+ class RiskLoginComponent {
20
+ get isDirectFlow() {
21
+ return this.authRoutingFlowService.directFlow;
22
+ }
23
+ get logo() {
24
+ return this.secondaryLogo;
25
+ }
26
+ constructor() {
27
+ this.authProvider = inject(AUTH_PROVIDER);
28
+ this.authRoutingFlowService = inject(AuthRoutingFlowService);
29
+ this.secondaryLogo = inject(SECONDARY_LOGO);
30
+ this.errorMessage = signal(undefined, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
31
+ this.loggingIn = signal(false, ...(ngDevMode ? [{ debugName: "loggingIn" }] : []));
32
+ this.loginForm = new FormGroup({
33
+ username: new FormControl(''),
34
+ password: new FormControl('')
35
+ });
36
+ this.authStatus = toSignal(this.authProvider.loggedInStream);
37
+ this.userProfile = signal(undefined, ...(ngDevMode ? [{ debugName: "userProfile" }] : []));
38
+ this.authRoutingFlowService.loginViaService().pipe(takeUntilDestroyed()).subscribe({
39
+ error: (err) => {
40
+ this.errorMessage.set(toErrorMessage(err).message);
41
+ }
42
+ });
43
+ this.authProvider.loggedInStream.pipe(takeUntilDestroyed(), switchMap(() => this.authProvider.userProfile)).subscribe({
44
+ next: (profile) => {
45
+ this.userProfile.set(profile);
46
+ }
47
+ });
48
+ }
49
+ login() {
50
+ this.loggingIn.set(true);
51
+ const username = this.loginForm.get('username')?.value ?? undefined;
52
+ const password = this.loginForm.get('password')?.value ?? undefined;
53
+ this.authRoutingFlowService.login(username, password).pipe(first()).subscribe({
54
+ next: (res) => {
55
+ if (!res) {
56
+ this.errorMessage.set('Authentication failed. Server did not generate a token.');
57
+ }
58
+ this.loggingIn.set(false);
59
+ },
60
+ error: () => {
61
+ this.loggingIn.set(false);
62
+ this.errorMessage.set('Authentication failed. Is the username and password correct?');
63
+ }
64
+ });
65
+ }
66
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
67
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskLoginComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class.risk-login-form": "true" } }, ngImport: i0, template: "<risk-flex>\n <risk-flex-spacer/>\n\n @if (isDirectFlow) {\n <div>\n @if (authStatus()) {\n @if (userProfile(); as user) {\n @if (user?.name) {\n <risk-good [message]=\"'Successfully logged in as ' + user.name + '.'\"/>\n } @else {\n <risk-good [message]=\"'Successfully logged in!'\"/>\n }\n }\n } @else {\n @if (errorMessage()) {\n <risk-error [message]=\"errorMessage()!\"/>\n }\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"login()\" role=\"form\">\n <mat-card>\n <mat-card-header>\n <mat-card-title>Please Sign In</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"username\"\n autofocus\n matInput\n name=\"username\"\n placeholder=\"Username\"\n type=\"text\">\n </mat-form-field>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"password\"\n matInput\n name=\"password\"\n placeholder=\"Password\"\n type=\"password\">\n </mat-form-field>\n </mat-card-content>\n <mat-card-actions>\n @if (!loggingIn()) {\n <button\n color=\"primary\"\n mat-raised-button\n type=\"submit\">\n Sign in\n </button>\n }\n @if (loggingIn()) {\n <mat-spinner [diameter]=\"36\"/>\n }\n <risk-flex-spacer/>\n <img [src]=\"logo\" alt=\"Company logo\">\n </mat-card-actions>\n </mat-card>\n </form>\n }\n </div>\n } @else {\n <div>\n @if (!errorMessage()) {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-spinner/>\n <div></div>\n </div>\n <h3>Contacting authentication server...</h3>\n } @else {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-icon class=\"risk-login-form-error\" color=\"warn\">error_outline</mat-icon>\n <div></div>\n </div>\n <h3>Failed to authenticate user: {{ errorMessage() }}</h3>\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <button (click)=\"login()\"\n color=\"primary\"\n mat-button\n type=\"button\">\n <mat-icon>autorenew</mat-icon>\n Retry\n </button>\n <div></div>\n </div>\n }\n </div>\n }\n\n <risk-flex-spacer/>\n</risk-flex>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-flex>div{width:400px;max-width:97vw;max-height:70vh;margin-top:40px}.mat-mdc-card-actions img{margin:3px 0;height:30px}.risk-login-form-flex-wrapper{display:flex}.risk-login-form-flex-wrapper>div{flex:1}.risk-login-form-error{font-size:100px;height:100px;width:100px}h3{text-align:center}input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px white inset}\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: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { 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: "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: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: RiskFlexComponent, selector: "risk-flex", inputs: ["wrapContent"] }, { kind: "component", type: RiskFlexSpacerComponent, selector: "risk-flex-spacer" }, { kind: "component", type: RiskMessageComponent, selector: "risk-error, risk-good, risk-info, risk-message, risk-warn, risk-initial-load, risk-no-data, risk-update-failed", inputs: ["message"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginComponent, decorators: [{
70
+ type: Component,
71
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, host: {
72
+ '[class.risk-login-form]': 'true'
73
+ }, imports: [
74
+ MatButton,
75
+ MatCard,
76
+ MatCardActions,
77
+ MatCardContent,
78
+ MatCardHeader,
79
+ MatCardTitle,
80
+ MatFormField,
81
+ MatIcon,
82
+ MatInput,
83
+ MatProgressSpinner,
84
+ ReactiveFormsModule,
85
+ RiskFlexComponent,
86
+ RiskFlexSpacerComponent,
87
+ RiskMessageComponent
88
+ ], template: "<risk-flex>\n <risk-flex-spacer/>\n\n @if (isDirectFlow) {\n <div>\n @if (authStatus()) {\n @if (userProfile(); as user) {\n @if (user?.name) {\n <risk-good [message]=\"'Successfully logged in as ' + user.name + '.'\"/>\n } @else {\n <risk-good [message]=\"'Successfully logged in!'\"/>\n }\n }\n } @else {\n @if (errorMessage()) {\n <risk-error [message]=\"errorMessage()!\"/>\n }\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"login()\" role=\"form\">\n <mat-card>\n <mat-card-header>\n <mat-card-title>Please Sign In</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"username\"\n autofocus\n matInput\n name=\"username\"\n placeholder=\"Username\"\n type=\"text\">\n </mat-form-field>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"password\"\n matInput\n name=\"password\"\n placeholder=\"Password\"\n type=\"password\">\n </mat-form-field>\n </mat-card-content>\n <mat-card-actions>\n @if (!loggingIn()) {\n <button\n color=\"primary\"\n mat-raised-button\n type=\"submit\">\n Sign in\n </button>\n }\n @if (loggingIn()) {\n <mat-spinner [diameter]=\"36\"/>\n }\n <risk-flex-spacer/>\n <img [src]=\"logo\" alt=\"Company logo\">\n </mat-card-actions>\n </mat-card>\n </form>\n }\n </div>\n } @else {\n <div>\n @if (!errorMessage()) {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-spinner/>\n <div></div>\n </div>\n <h3>Contacting authentication server...</h3>\n } @else {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-icon class=\"risk-login-form-error\" color=\"warn\">error_outline</mat-icon>\n <div></div>\n </div>\n <h3>Failed to authenticate user: {{ errorMessage() }}</h3>\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <button (click)=\"login()\"\n color=\"primary\"\n mat-button\n type=\"button\">\n <mat-icon>autorenew</mat-icon>\n Retry\n </button>\n <div></div>\n </div>\n }\n </div>\n }\n\n <risk-flex-spacer/>\n</risk-flex>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-flex>div{width:400px;max-width:97vw;max-height:70vh;margin-top:40px}.mat-mdc-card-actions img{margin:3px 0;height:30px}.risk-login-form-flex-wrapper{display:flex}.risk-login-form-flex-wrapper>div{flex:1}.risk-login-form-error{font-size:100px;height:100px;width:100px}h3{text-align:center}input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px white inset}\n"] }]
89
+ }], ctorParameters: () => [] });
90
+
91
+ class RiskLoginMenuComponentTitleDirective {
92
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuComponentTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
93
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLoginMenuComponentTitleDirective, isStandalone: true, selector: "risk-login-menu-title-horizontal, risk-login-menu-title-vertical", host: { properties: { "class.risk-login-menu-title": "true" } }, ngImport: i0 }); }
94
+ }
95
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuComponentTitleDirective, decorators: [{
96
+ type: Directive,
97
+ args: [{
98
+ selector: 'risk-login-menu-title-horizontal, '
99
+ + 'risk-login-menu-title-vertical',
100
+ host: {
101
+ '[class.risk-login-menu-title]': 'true'
102
+ }
103
+ }]
104
+ }] });
105
+ class RiskLoginMenuItemsDirective {
106
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuItemsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
107
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLoginMenuItemsDirective, isStandalone: true, selector: "risk-login-menu-before-items-horizontal, risk-login-menu-before-items-vertical,risk-login-menu-after-items-horizontal,risk-login-menu-after-items-vertical", ngImport: i0 }); }
108
+ }
109
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuItemsDirective, decorators: [{
110
+ type: Directive,
111
+ args: [{
112
+ selector: 'risk-login-menu-before-items-horizontal,'
113
+ + ' risk-login-menu-before-items-vertical,'
114
+ + 'risk-login-menu-after-items-horizontal,'
115
+ + 'risk-login-menu-after-items-vertical'
116
+ }]
117
+ }] });
118
+ class RiskLoginMenuComponent {
119
+ constructor() {
120
+ this.authProvider = inject(AUTH_PROVIDER);
121
+ this.authRoutingFlowService = inject(AuthRoutingFlowService);
122
+ this.orientation = input('row', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
123
+ this.authStatus = toSignal(this.authProvider.loggedInStream);
124
+ }
125
+ logout() {
126
+ this.authRoutingFlowService.logout().pipe(first()).subscribe();
127
+ }
128
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
129
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskLoginMenuComponent, isStandalone: true, selector: "risk-login-menu", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.risk-login-menu": "true", "class.risk-login-menu-flex-row": "orientation() === \"row\"", "class.risk-login-menu-flex-column": "orientation() === \"column\"" } }, ngImport: i0, template: "@if (orientation() === 'row') {\n <mat-menu #loginMenu=\"matMenu\"\n [overlapTrigger]=\"false\">\n <ng-content select=\"risk-login-menu-before-items-horizontal\"/>\n @if (authStatus()) {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </button>\n } @else {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>launch</mat-icon>\n Login\n </button>\n }\n <ng-content select=\"risk-login-menu-after-items-horizontal\"/>\n </mat-menu>\n <button #menu=\"matMenuTrigger\"\n [class.risk-menu-open]=\"menu.menuOpen\"\n [matMenuTriggerFor]=\"loginMenu\"\n mat-button\n type=\"button\">\n <ng-content select=\"risk-login-menu-title-horizontal\"/>\n <mat-icon>person</mat-icon>\n </button>\n}\n@if (orientation() === 'column') {\n <ng-content select=\"risk-login-menu-title-vertical\"/>\n <ng-content select=\"risk-login-menu-before-items-vertical\"/>\n @if (authStatus()) {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </a>\n } @else {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>launch</mat-icon>\n Login\n </a>\n }\n <ng-content select=\"risk-login-menu-after-items-vertical\"/>\n}\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host{display:flex!important}:host.risk-login-menu-flex-row{flex-direction:row}:host.risk-login-menu-flex-column{flex-direction:column}:host .risk-login-menu-title{font-weight:700;margin:0 5px}\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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoginMenuComponent, decorators: [{
132
+ type: Component,
133
+ args: [{ selector: 'risk-login-menu', changeDetection: ChangeDetectionStrategy.OnPush, host: {
134
+ '[class.risk-login-menu]': 'true',
135
+ '[class.risk-login-menu-flex-row]': 'orientation() === "row"',
136
+ '[class.risk-login-menu-flex-column]': 'orientation() === "column"'
137
+ }, imports: [
138
+ MatButton,
139
+ MatIcon,
140
+ MatMenu,
141
+ MatMenuItem,
142
+ MatMenuTrigger
143
+ ], template: "@if (orientation() === 'row') {\n <mat-menu #loginMenu=\"matMenu\"\n [overlapTrigger]=\"false\">\n <ng-content select=\"risk-login-menu-before-items-horizontal\"/>\n @if (authStatus()) {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </button>\n } @else {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>launch</mat-icon>\n Login\n </button>\n }\n <ng-content select=\"risk-login-menu-after-items-horizontal\"/>\n </mat-menu>\n <button #menu=\"matMenuTrigger\"\n [class.risk-menu-open]=\"menu.menuOpen\"\n [matMenuTriggerFor]=\"loginMenu\"\n mat-button\n type=\"button\">\n <ng-content select=\"risk-login-menu-title-horizontal\"/>\n <mat-icon>person</mat-icon>\n </button>\n}\n@if (orientation() === 'column') {\n <ng-content select=\"risk-login-menu-title-vertical\"/>\n <ng-content select=\"risk-login-menu-before-items-vertical\"/>\n @if (authStatus()) {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </a>\n } @else {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>launch</mat-icon>\n Login\n </a>\n }\n <ng-content select=\"risk-login-menu-after-items-vertical\"/>\n}\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host{display:flex!important}:host.risk-login-menu-flex-row{flex-direction:row}:host.risk-login-menu-flex-column{flex-direction:column}:host .risk-login-menu-title{font-weight:700;margin:0 5px}\n"] }]
144
+ }], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
145
+
146
+ /**
147
+ * Generated bundle index. Do not edit.
148
+ */
149
+
150
+ export { RiskLoginComponent, RiskLoginMenuComponent, RiskLoginMenuComponentTitleDirective, RiskLoginMenuItemsDirective };
151
+ //# sourceMappingURL=dbg-riskit-angular-login.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbg-riskit-angular-login.mjs","sources":["../../../../pkg/dbg-riskit/angular-login/src/lib/login.component.ts","../../../../pkg/dbg-riskit/angular-login/src/lib/login.component.html","../../../../pkg/dbg-riskit/angular-login/src/lib/login.menu.component.ts","../../../../pkg/dbg-riskit/angular-login/src/lib/login.menu.component.html","../../../../pkg/dbg-riskit/angular-login/src/dbg-riskit-angular-login.ts"],"sourcesContent":["import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';\nimport {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';\nimport {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';\nimport {MatButton} from '@angular/material/button';\nimport {MatCard, MatCardActions, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';\nimport {MatFormField} from '@angular/material/form-field';\nimport {MatIcon} from '@angular/material/icon';\nimport {MatInput} from '@angular/material/input';\nimport {MatProgressSpinner} from '@angular/material/progress-spinner';\nimport {AuthRoutingFlowService} from '@dbg-riskit/angular-auth';\nimport {AUTH_PROVIDER, SECONDARY_LOGO} from '@dbg-riskit/angular-common';\nimport {ErrorTypes, toErrorMessage} from '@dbg-riskit/angular-error';\nimport {RiskFlexComponent, RiskFlexSpacerComponent, RiskMessageComponent} from '@dbg-riskit/angular-view';\nimport {AuthProvider, UserInfo} from '@dbg-riskit/common';\nimport {first, switchMap} from 'rxjs/operators';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl : 'login.component.html',\n styleUrls : [\n '../../../component.scss',\n 'login.component.scss'\n ],\n host : {\n '[class.risk-login-form]': 'true'\n },\n imports: [\n MatButton,\n MatCard,\n MatCardActions,\n MatCardContent,\n MatCardHeader,\n MatCardTitle,\n MatFormField,\n MatIcon,\n MatInput,\n MatProgressSpinner,\n ReactiveFormsModule,\n RiskFlexComponent,\n RiskFlexSpacerComponent,\n RiskMessageComponent\n ]\n})\nexport class RiskLoginComponent {\n private readonly authProvider = inject<AuthProvider>(AUTH_PROVIDER);\n private readonly authRoutingFlowService = inject(AuthRoutingFlowService);\n private readonly secondaryLogo = inject(SECONDARY_LOGO);\n\n public readonly errorMessage = signal<string | undefined>(undefined);\n public readonly loggingIn = signal(false);\n\n public readonly loginForm = new FormGroup({\n username: new FormControl(''),\n password: new FormControl('')\n });\n\n public readonly authStatus = toSignal(this.authProvider.loggedInStream);\n public readonly userProfile = signal<UserInfo | undefined>(undefined);\n\n public get isDirectFlow(): boolean {\n return this.authRoutingFlowService.directFlow;\n }\n\n public get logo(): string {\n return this.secondaryLogo;\n }\n\n public constructor() {\n this.authRoutingFlowService.loginViaService().pipe(\n takeUntilDestroyed()\n ).subscribe({\n error: (err: ErrorTypes) => {\n this.errorMessage.set(toErrorMessage(err).message);\n }\n });\n\n this.authProvider.loggedInStream.pipe(\n takeUntilDestroyed(),\n switchMap(() => this.authProvider.userProfile)\n ).subscribe({\n next: (profile) => {\n this.userProfile.set(profile);\n }\n });\n }\n\n public login(): void {\n this.loggingIn.set(true);\n const username = this.loginForm.get('username')?.value ?? undefined;\n const password = this.loginForm.get('password')?.value ?? undefined;\n this.authRoutingFlowService.login(username, password).pipe(\n first()\n ).subscribe({\n next : (res: boolean) => {\n if (!res) {\n this.errorMessage.set('Authentication failed. Server did not generate a token.');\n }\n this.loggingIn.set(false);\n },\n error: () => {\n this.loggingIn.set(false);\n this.errorMessage.set('Authentication failed. Is the username and password correct?');\n }\n });\n }\n}\n","<risk-flex>\n <risk-flex-spacer/>\n\n @if (isDirectFlow) {\n <div>\n @if (authStatus()) {\n @if (userProfile(); as user) {\n @if (user?.name) {\n <risk-good [message]=\"'Successfully logged in as ' + user.name + '.'\"/>\n } @else {\n <risk-good [message]=\"'Successfully logged in!'\"/>\n }\n }\n } @else {\n @if (errorMessage()) {\n <risk-error [message]=\"errorMessage()!\"/>\n }\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"login()\" role=\"form\">\n <mat-card>\n <mat-card-header>\n <mat-card-title>Please Sign In</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"username\"\n autofocus\n matInput\n name=\"username\"\n placeholder=\"Username\"\n type=\"text\">\n </mat-form-field>\n <mat-form-field class=\"risk-full-width\">\n <input formControlName=\"password\"\n matInput\n name=\"password\"\n placeholder=\"Password\"\n type=\"password\">\n </mat-form-field>\n </mat-card-content>\n <mat-card-actions>\n @if (!loggingIn()) {\n <button\n color=\"primary\"\n mat-raised-button\n type=\"submit\">\n Sign in\n </button>\n }\n @if (loggingIn()) {\n <mat-spinner [diameter]=\"36\"/>\n }\n <risk-flex-spacer/>\n <img [src]=\"logo\" alt=\"Company logo\">\n </mat-card-actions>\n </mat-card>\n </form>\n }\n </div>\n } @else {\n <div>\n @if (!errorMessage()) {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-spinner/>\n <div></div>\n </div>\n <h3>Contacting authentication server...</h3>\n } @else {\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-icon class=\"risk-login-form-error\" color=\"warn\">error_outline</mat-icon>\n <div></div>\n </div>\n <h3>Failed to authenticate user: {{ errorMessage() }}</h3>\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <button (click)=\"login()\"\n color=\"primary\"\n mat-button\n type=\"button\">\n <mat-icon>autorenew</mat-icon>\n Retry\n </button>\n <div></div>\n </div>\n }\n </div>\n }\n\n <risk-flex-spacer/>\n</risk-flex>\n","import {ChangeDetectionStrategy, Component, Directive, inject, input} from '@angular/core';\nimport {toSignal} from '@angular/core/rxjs-interop';\nimport {MatButton} from '@angular/material/button';\nimport {MatIcon} from '@angular/material/icon';\nimport {MatMenu, MatMenuItem, MatMenuTrigger} from '@angular/material/menu';\nimport {AuthRoutingFlowService} from '@dbg-riskit/angular-auth';\nimport {AUTH_PROVIDER} from '@dbg-riskit/angular-common';\nimport {AuthProvider} from '@dbg-riskit/common';\nimport {first} from 'rxjs/operators';\n\n@Directive({\n selector: 'risk-login-menu-title-horizontal, '\n + 'risk-login-menu-title-vertical',\n host : {\n '[class.risk-login-menu-title]': 'true'\n }\n})\nexport class RiskLoginMenuComponentTitleDirective {\n}\n\n@Directive({\n selector: 'risk-login-menu-before-items-horizontal,'\n + ' risk-login-menu-before-items-vertical,'\n + 'risk-login-menu-after-items-horizontal,'\n + 'risk-login-menu-after-items-vertical'\n})\nexport class RiskLoginMenuItemsDirective {\n}\n\n@Component({\n selector : 'risk-login-menu',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl : 'login.menu.component.html',\n styleUrls : [\n '../../../component.scss',\n 'login.menu.component.scss'\n ],\n host : {\n '[class.risk-login-menu]' : 'true',\n '[class.risk-login-menu-flex-row]' : 'orientation() === \"row\"',\n '[class.risk-login-menu-flex-column]': 'orientation() === \"column\"'\n },\n imports : [\n MatButton,\n MatIcon,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger\n ]\n})\nexport class RiskLoginMenuComponent {\n private readonly authProvider = inject<AuthProvider>(AUTH_PROVIDER);\n private readonly authRoutingFlowService = inject(AuthRoutingFlowService);\n\n public readonly orientation = input<'row' | 'column'>('row');\n public readonly authStatus = toSignal(this.authProvider.loggedInStream);\n\n public logout(): void {\n this.authRoutingFlowService.logout().pipe(\n first()\n ).subscribe();\n }\n}\n","@if (orientation() === 'row') {\n <mat-menu #loginMenu=\"matMenu\"\n [overlapTrigger]=\"false\">\n <ng-content select=\"risk-login-menu-before-items-horizontal\"/>\n @if (authStatus()) {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </button>\n } @else {\n <button (click)=\"logout()\"\n mat-menu-item\n type=\"button\">\n <mat-icon>launch</mat-icon>\n Login\n </button>\n }\n <ng-content select=\"risk-login-menu-after-items-horizontal\"/>\n </mat-menu>\n <button #menu=\"matMenuTrigger\"\n [class.risk-menu-open]=\"menu.menuOpen\"\n [matMenuTriggerFor]=\"loginMenu\"\n mat-button\n type=\"button\">\n <ng-content select=\"risk-login-menu-title-horizontal\"/>\n <mat-icon>person</mat-icon>\n </button>\n}\n@if (orientation() === 'column') {\n <ng-content select=\"risk-login-menu-title-vertical\"/>\n <ng-content select=\"risk-login-menu-before-items-vertical\"/>\n @if (authStatus()) {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>exit_to_app</mat-icon>\n Logout\n </a>\n } @else {\n <a (click)=\"logout()\"\n mat-button>\n <mat-icon>launch</mat-icon>\n Login\n </a>\n }\n <ng-content select=\"risk-login-menu-after-items-vertical\"/>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ import * as i0 from '@angular/core';
2
+ import { FormGroup, FormControl } from '@angular/forms';
3
+ import { UserInfo } from '@dbg-riskit/common';
4
+
5
+ declare class RiskLoginComponent {
6
+ private readonly authProvider;
7
+ private readonly authRoutingFlowService;
8
+ private readonly secondaryLogo;
9
+ readonly errorMessage: i0.WritableSignal<string | undefined>;
10
+ readonly loggingIn: i0.WritableSignal<boolean>;
11
+ readonly loginForm: FormGroup<{
12
+ username: FormControl<string | null>;
13
+ password: FormControl<string | null>;
14
+ }>;
15
+ readonly authStatus: i0.Signal<boolean | undefined>;
16
+ readonly userProfile: i0.WritableSignal<UserInfo | undefined>;
17
+ get isDirectFlow(): boolean;
18
+ get logo(): string;
19
+ constructor();
20
+ login(): void;
21
+ static ɵfac: i0.ɵɵFactoryDeclaration<RiskLoginComponent, never>;
22
+ static ɵcmp: i0.ɵɵComponentDeclaration<RiskLoginComponent, "ng-component", never, {}, {}, never, never, true, never>;
23
+ }
24
+
25
+ declare class RiskLoginMenuComponentTitleDirective {
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<RiskLoginMenuComponentTitleDirective, never>;
27
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RiskLoginMenuComponentTitleDirective, "risk-login-menu-title-horizontal, risk-login-menu-title-vertical", never, {}, {}, never, never, true, never>;
28
+ }
29
+ declare class RiskLoginMenuItemsDirective {
30
+ static ɵfac: i0.ɵɵFactoryDeclaration<RiskLoginMenuItemsDirective, never>;
31
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RiskLoginMenuItemsDirective, "risk-login-menu-before-items-horizontal, risk-login-menu-before-items-vertical,risk-login-menu-after-items-horizontal,risk-login-menu-after-items-vertical", never, {}, {}, never, never, true, never>;
32
+ }
33
+ declare class RiskLoginMenuComponent {
34
+ private readonly authProvider;
35
+ private readonly authRoutingFlowService;
36
+ readonly orientation: i0.InputSignal<"row" | "column">;
37
+ readonly authStatus: i0.Signal<boolean | undefined>;
38
+ logout(): void;
39
+ static ɵfac: i0.ɵɵFactoryDeclaration<RiskLoginMenuComponent, never>;
40
+ static ɵcmp: i0.ɵɵComponentDeclaration<RiskLoginMenuComponent, "risk-login-menu", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, {}, never, ["risk-login-menu-before-items-horizontal", "risk-login-menu-after-items-horizontal", "risk-login-menu-title-horizontal", "risk-login-menu-title-vertical", "risk-login-menu-before-items-vertical", "risk-login-menu-after-items-vertical"], true, never>;
41
+ }
42
+
43
+ export { RiskLoginComponent, RiskLoginMenuComponent, RiskLoginMenuComponentTitleDirective, RiskLoginMenuItemsDirective };
package/package.json CHANGED
@@ -1,39 +1,30 @@
1
1
  {
2
2
  "name": "@dbg-riskit/angular-login",
3
- "version": "9999.9999.9999-rc.63199",
3
+ "version": "9999.9999.9999-rc.6692537",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "peerDependencies": {
6
- "@angular/core": "^13.2.6",
7
- "@angular/forms": "^13.2.6",
8
- "@angular/router": "^13.2.6",
9
- "@dbg-riskit/common": "~9999.9999.9999-rc.63199",
10
- "@dbg-riskit/angular-auth": "~9999.9999.9999-rc.63199",
11
- "@dbg-riskit/angular-common": "~9999.9999.9999-rc.63199",
12
- "@dbg-riskit/angular-error": "~9999.9999.9999-rc.63199",
13
- "@dbg-riskit/angular-view": "~9999.9999.9999-rc.63199",
14
- "rxjs": "~7.5.5"
6
+ "@angular/core": "^20.3.15",
7
+ "@angular/forms": "^20.3.15",
8
+ "@angular/router": "^20.3.15",
9
+ "@dbg-riskit/common": "~9999.9999.9999-rc.6692537",
10
+ "@dbg-riskit/angular-auth": "~9999.9999.9999-rc.6692537",
11
+ "@dbg-riskit/angular-common": "~9999.9999.9999-rc.6692537",
12
+ "@dbg-riskit/angular-error": "~9999.9999.9999-rc.6692537",
13
+ "@dbg-riskit/angular-view": "~9999.9999.9999-rc.6692537",
14
+ "rxjs": "~7.8.2"
15
15
  },
16
16
  "dependencies": {
17
- "tslib": "^2.3.1"
17
+ "tslib": "^2.8.1"
18
18
  },
19
- "module": "fesm2015/dbg-riskit-angular-login.mjs",
20
- "es2020": "fesm2020/dbg-riskit-angular-login.mjs",
21
- "esm2020": "esm2020/dbg-riskit-angular-login.mjs",
22
- "fesm2020": "fesm2020/dbg-riskit-angular-login.mjs",
23
- "fesm2015": "fesm2015/dbg-riskit-angular-login.mjs",
24
- "typings": "dbg-riskit-angular-login.d.ts",
19
+ "module": "fesm2022/dbg-riskit-angular-login.mjs",
20
+ "typings": "index.d.ts",
25
21
  "exports": {
26
22
  "./package.json": {
27
23
  "default": "./package.json"
28
24
  },
29
25
  ".": {
30
- "types": "./dbg-riskit-angular-login.d.ts",
31
- "esm2020": "./esm2020/dbg-riskit-angular-login.mjs",
32
- "es2020": "./fesm2020/dbg-riskit-angular-login.mjs",
33
- "es2015": "./fesm2015/dbg-riskit-angular-login.mjs",
34
- "node": "./fesm2015/dbg-riskit-angular-login.mjs",
35
- "default": "./fesm2020/dbg-riskit-angular-login.mjs"
26
+ "types": "./index.d.ts",
27
+ "default": "./fesm2022/dbg-riskit-angular-login.mjs"
36
28
  }
37
- },
38
- "sideEffects": false
29
+ }
39
30
  }
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- /// <amd-module name="@dbg-riskit/angular-login" />
5
- export * from './public_api';
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- export * from './public_api';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGJnLXJpc2tpdC1hbmd1bGFyLWxvZ2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGtnL2RiZy1yaXNraXQvYW5ndWxhci1sb2dpbi9zcmMvZGJnLXJpc2tpdC1hbmd1bGFyLWxvZ2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljX2FwaSc7XG4iXX0=
@@ -1,80 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
2
- import { AUTH_PROVIDER, SECONDARY_LOGO } from '@dbg-riskit/angular-common';
3
- import { toErrorMessage } from '@dbg-riskit/angular-error';
4
- import { BaseComponent } from '@dbg-riskit/angular-view';
5
- import { first, takeUntil } from 'rxjs/operators';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@dbg-riskit/angular-auth";
8
- import * as i2 from "@dbg-riskit/angular-view";
9
- import * as i3 from "@angular/material/card";
10
- import * as i4 from "@angular/material/form-field";
11
- import * as i5 from "@angular/material/button";
12
- import * as i6 from "@angular/material/progress-spinner";
13
- import * as i7 from "@angular/material/icon";
14
- import * as i8 from "@angular/common";
15
- import * as i9 from "@angular/forms";
16
- import * as i10 from "@angular/material/input";
17
- export class LoginComponent extends BaseComponent {
18
- constructor(authProvider, changeDetectorRef, authRoutingFlowService, secondaryLogo) {
19
- super();
20
- this.authProvider = authProvider;
21
- this.changeDetectorRef = changeDetectorRef;
22
- this.authRoutingFlowService = authRoutingFlowService;
23
- this.secondaryLogo = secondaryLogo;
24
- /**
25
- * Control for "login button-to-spinner".
26
- */
27
- this.loggingIn = false;
28
- // Update component state on login status change
29
- this.authProvider.loggedInStream.pipe(takeUntil(this.destroyed)).subscribe(() => this.changeDetectorRef.markForCheck());
30
- }
31
- ngAfterViewInit() {
32
- this.authRoutingFlowService.loginViaService().pipe(takeUntil(this.destroyed)).subscribe(() => {
33
- this.changeDetectorRef.markForCheck();
34
- }, (err) => {
35
- this.errorMessage = toErrorMessage(err).message;
36
- this.changeDetectorRef.markForCheck();
37
- });
38
- }
39
- get isDirectFlow() {
40
- return this.authRoutingFlowService.directFlow;
41
- }
42
- get authStatus() {
43
- return this.authProvider.loggedIn;
44
- }
45
- get userProfile() {
46
- return this.authProvider.userProfile;
47
- }
48
- login() {
49
- this.loggingIn = true;
50
- this.authRoutingFlowService.login(this.username, this.password).pipe(first()).subscribe((res) => {
51
- if (!res) {
52
- this.errorMessage = 'Authentication failed. Server did not generate a token.';
53
- }
54
- this.loggingIn = false;
55
- this.changeDetectorRef.markForCheck();
56
- }, () => {
57
- this.loggingIn = false;
58
- this.errorMessage = 'Authentication failed. Is the username and password correct?';
59
- this.changeDetectorRef.markForCheck();
60
- });
61
- }
62
- get logo() {
63
- return this.secondaryLogo;
64
- }
65
- }
66
- LoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: LoginComponent, deps: [{ token: AUTH_PROVIDER }, { token: i0.ChangeDetectorRef }, { token: i1.AuthRoutingFlowService }, { token: SECONDARY_LOGO }], target: i0.ɵɵFactoryTarget.Component });
67
- LoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.6", type: LoginComponent, selector: "ng-component", host: { properties: { "class.risk-login-form": "true" } }, usesInheritance: true, ngImport: i0, template: "<risk-flex>\n <risk-flex-spacer></risk-flex-spacer>\n\n <div *ngIf=\"isDirectFlow\">\n <ng-template #loggedOut>\n <risk-error *ngIf=\"errorMessage\" [message]=\"errorMessage\"></risk-error>\n\n <form (ngSubmit)=\"login()\" role=\"form\">\n <mat-card>\n <mat-card-title-group>\n <mat-card-title>Please Sign In</mat-card-title>\n </mat-card-title-group>\n <mat-card-content>\n <mat-form-field class=\"risk-full-width\">\n <input matInput\n type=\"text\"\n placeholder=\"Username\"\n name=\"username\"\n [(ngModel)]=\"username\"\n autofocus>\n </mat-form-field>\n <mat-form-field class=\"risk-full-width\">\n <input matInput\n type=\"password\"\n placeholder=\"Password\"\n name=\"password\"\n [(ngModel)]=\"password\">\n </mat-form-field>\n </mat-card-content>\n <mat-card-actions>\n <button *ngIf=\"!loggingIn\"\n mat-raised-button\n color=\"primary\"\n type=\"submit\">\n Sign in\n </button>\n <img [src]=\"logo\" alt=\"Company logo\">\n <mat-spinner *ngIf=\"loggingIn\" [diameter]=\"36\"></mat-spinner>\n </mat-card-actions>\n </mat-card>\n </form>\n </ng-template>\n\n <ng-template [ngIf]=\"authStatus | async\" [ngIfElse]=\"loggedOut\">\n <ng-template [ngIf]=\"userProfile | async\" let-user=\"ngIf\">\n <risk-good *ngIf=\"user?.name\"\n [message]=\"'Successfully logged in as ' + user.name + '.'\"></risk-good>\n <risk-good *ngIf=\"!user && !user.name\"\n [message]=\"'Successfully logged in!'\"></risk-good>\n </ng-template>\n </ng-template>\n </div>\n\n <div *ngIf=\"!isDirectFlow\">\n <ng-template [ngIf]=\"!errorMessage\">\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-spinner></mat-spinner>\n <div></div>\n </div>\n <h3>Contacting authentication server...</h3>\n </ng-template>\n <ng-template [ngIf]=\"errorMessage\">\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-icon class=\"risk-login-form-error\" color=\"warn\">error_outline</mat-icon>\n <div></div>\n </div>\n <h3>Failed to authenticate user: {{errorMessage}}</h3>\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <button mat-button\n (click)=\"login()\"\n color=\"primary\"\n type=\"button\">\n <mat-icon>autorenew</mat-icon>\n Retry\n </button>\n <div></div>\n </div>\n </ng-template>\n </div>\n\n <risk-flex-spacer></risk-flex-spacer>\n</risk-flex>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-flex>div{width:400px;max-width:97vw;max-height:70vh;margin-top:40px}.mat-card-title-group{margin:0}.mat-card-title-group .mat-card-title{font-weight:500}.mat-card-actions{margin:0;margin-bottom:-8px!important;padding:0}.mat-card-actions img{float:right;margin:3px 0;height:30px}.risk-login-form-flex-wrapper{display:-webkit-flex;display:flex}.risk-login-form-flex-wrapper>div{-webkit-flex:1;flex:1}.risk-login-form-error{font-size:100px;height:100px;width:100px}h3{text-align:center}input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px white inset}\n"], components: [{ type: i2.FlexComponent, selector: "risk-flex", inputs: ["wrapContent"] }, { type: i2.FlexSpacerComponent, selector: "risk-flex-spacer" }, { type: i2.MessageComponent, selector: "risk-error, risk-good, risk-info, risk-message, risk-warn, risk-initial-load, risk-no-data, risk-update-failed", inputs: ["message"] }, { type: i3.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { type: i3.MatCardTitleGroup, selector: "mat-card-title-group" }, { type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i9.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i9.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { type: i3.MatCardContent, selector: "mat-card-content, [mat-card-content], [matCardContent]" }, { type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }], pipes: { "async": i8.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
68
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: LoginComponent, decorators: [{
69
- type: Component,
70
- args: [{ host: {
71
- '[class.risk-login-form]': 'true'
72
- }, changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<risk-flex>\n <risk-flex-spacer></risk-flex-spacer>\n\n <div *ngIf=\"isDirectFlow\">\n <ng-template #loggedOut>\n <risk-error *ngIf=\"errorMessage\" [message]=\"errorMessage\"></risk-error>\n\n <form (ngSubmit)=\"login()\" role=\"form\">\n <mat-card>\n <mat-card-title-group>\n <mat-card-title>Please Sign In</mat-card-title>\n </mat-card-title-group>\n <mat-card-content>\n <mat-form-field class=\"risk-full-width\">\n <input matInput\n type=\"text\"\n placeholder=\"Username\"\n name=\"username\"\n [(ngModel)]=\"username\"\n autofocus>\n </mat-form-field>\n <mat-form-field class=\"risk-full-width\">\n <input matInput\n type=\"password\"\n placeholder=\"Password\"\n name=\"password\"\n [(ngModel)]=\"password\">\n </mat-form-field>\n </mat-card-content>\n <mat-card-actions>\n <button *ngIf=\"!loggingIn\"\n mat-raised-button\n color=\"primary\"\n type=\"submit\">\n Sign in\n </button>\n <img [src]=\"logo\" alt=\"Company logo\">\n <mat-spinner *ngIf=\"loggingIn\" [diameter]=\"36\"></mat-spinner>\n </mat-card-actions>\n </mat-card>\n </form>\n </ng-template>\n\n <ng-template [ngIf]=\"authStatus | async\" [ngIfElse]=\"loggedOut\">\n <ng-template [ngIf]=\"userProfile | async\" let-user=\"ngIf\">\n <risk-good *ngIf=\"user?.name\"\n [message]=\"'Successfully logged in as ' + user.name + '.'\"></risk-good>\n <risk-good *ngIf=\"!user && !user.name\"\n [message]=\"'Successfully logged in!'\"></risk-good>\n </ng-template>\n </ng-template>\n </div>\n\n <div *ngIf=\"!isDirectFlow\">\n <ng-template [ngIf]=\"!errorMessage\">\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-spinner></mat-spinner>\n <div></div>\n </div>\n <h3>Contacting authentication server...</h3>\n </ng-template>\n <ng-template [ngIf]=\"errorMessage\">\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <mat-icon class=\"risk-login-form-error\" color=\"warn\">error_outline</mat-icon>\n <div></div>\n </div>\n <h3>Failed to authenticate user: {{errorMessage}}</h3>\n <div class=\"risk-login-form-flex-wrapper\">\n <div></div>\n <button mat-button\n (click)=\"login()\"\n color=\"primary\"\n type=\"button\">\n <mat-icon>autorenew</mat-icon>\n Retry\n </button>\n <div></div>\n </div>\n </ng-template>\n </div>\n\n <risk-flex-spacer></risk-flex-spacer>\n</risk-flex>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-flex>div{width:400px;max-width:97vw;max-height:70vh;margin-top:40px}.mat-card-title-group{margin:0}.mat-card-title-group .mat-card-title{font-weight:500}.mat-card-actions{margin:0;margin-bottom:-8px!important;padding:0}.mat-card-actions img{float:right;margin:3px 0;height:30px}.risk-login-form-flex-wrapper{display:-webkit-flex;display:flex}.risk-login-form-flex-wrapper>div{-webkit-flex:1;flex:1}.risk-login-form-error{font-size:100px;height:100px;width:100px}h3{text-align:center}input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px white inset}\n"] }]
73
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
74
- type: Inject,
75
- args: [AUTH_PROVIDER]
76
- }] }, { type: i0.ChangeDetectorRef }, { type: i1.AuthRoutingFlowService }, { type: undefined, decorators: [{
77
- type: Inject,
78
- args: [SECONDARY_LOGO]
79
- }] }]; } });
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naW4uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGtnL2RiZy1yaXNraXQvYW5ndWxhci1sb2dpbi9zcmMvbGliL2xvZ2luLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3BrZy9kYmctcmlza2l0L2FuZ3VsYXItbG9naW4vc3JjL2xpYi9sb2dpbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdCLHVCQUF1QixFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzNHLE9BQU8sRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDekUsT0FBTyxFQUFhLGNBQWMsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUl2RCxPQUFPLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7Ozs7QUFjaEQsTUFBTSxPQUFPLGNBQWUsU0FBUSxhQUFhO0lBc0I3QyxZQUEyRCxZQUEwQixFQUNqRCxpQkFBb0MsRUFDcEMsc0JBQThDLEVBQ3RCLGFBQXFCO1FBQzdFLEtBQUssRUFBRSxDQUFDO1FBSitDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQ2pELHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBUTtRQVJqRjs7V0FFRztRQUNJLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFPckIsZ0RBQWdEO1FBQ2hELElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLElBQUksQ0FDakMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDNUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVNLGVBQWU7UUFDbEIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FDOUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDNUIsQ0FBQyxTQUFTLENBQ1AsR0FBRyxFQUFFO1lBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFDLENBQUMsRUFDRCxDQUFDLEdBQWUsRUFBRSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNoRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUMsQ0FBQyxDQUNKLENBQUM7SUFDTixDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ25CLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQztJQUNsRCxDQUFDO0lBRUQsSUFBVyxVQUFVO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQVcsV0FBVztRQUNsQixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO0lBQ3pDLENBQUM7SUFFTSxLQUFLO1FBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQ2hFLEtBQUssRUFBRSxDQUNWLENBQUMsU0FBUyxDQUNQLENBQUMsR0FBWSxFQUFFLEVBQUU7WUFDYixJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUNOLElBQUksQ0FBQyxZQUFZLEdBQUcseURBQXlELENBQUM7YUFDakY7WUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUMsQ0FBQyxFQUNELEdBQUcsRUFBRTtZQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsOERBQThELENBQUM7WUFDbkYsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFDLENBQUMsQ0FDSixDQUFDO0lBQ04sQ0FBQztJQUVELElBQVcsSUFBSTtRQUNYLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM5QixDQUFDOzsyR0FqRlEsY0FBYyxrQkFzQkksYUFBYSxvRkFHYixjQUFjOytGQXpCaEMsY0FBYyxzSUN2QjNCLGlsSEFxRkE7MkZEOURhLGNBQWM7a0JBWjFCLFNBQVM7MkJBTWU7d0JBQ2pCLHlCQUF5QixFQUFFLE1BQU07cUJBQ3BDLG1CQUNvQix1QkFBdUIsQ0FBQyxNQUFNLHVCQUM5QixLQUFLOzswQkF3Qk4sTUFBTTsyQkFBQyxhQUFhOzswQkFHcEIsTUFBTTsyQkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5qZWN0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtBdXRoUm91dGluZ0Zsb3dTZXJ2aWNlfSBmcm9tICdAZGJnLXJpc2tpdC9hbmd1bGFyLWF1dGgnO1xuaW1wb3J0IHtBVVRIX1BST1ZJREVSLCBTRUNPTkRBUllfTE9HT30gZnJvbSAnQGRiZy1yaXNraXQvYW5ndWxhci1jb21tb24nO1xuaW1wb3J0IHtFcnJvclR5cGVzLCB0b0Vycm9yTWVzc2FnZX0gZnJvbSAnQGRiZy1yaXNraXQvYW5ndWxhci1lcnJvcic7XG5pbXBvcnQge0Jhc2VDb21wb25lbnR9IGZyb20gJ0BkYmctcmlza2l0L2FuZ3VsYXItdmlldyc7XG5pbXBvcnQge0F1dGhQcm92aWRlciwgVXNlckluZm99IGZyb20gJ0BkYmctcmlza2l0L2NvbW1vbic7XG5cbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2ZpcnN0LCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQENvbXBvbmVudCh7XG4gICAgdGVtcGxhdGVVcmwgICAgICAgIDogJ2xvZ2luLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHMgICAgICAgICAgOiBbXG4gICAgICAgICcuLi8uLi8uLi9jb21wb25lbnQuc2NzcycsXG4gICAgICAgICdsb2dpbi5jb21wb25lbnQuc2NzcydcbiAgICBdLFxuICAgIGhvc3QgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgJ1tjbGFzcy5yaXNrLWxvZ2luLWZvcm1dJzogJ3RydWUnXG4gICAgfSxcbiAgICBjaGFuZ2VEZXRlY3Rpb24gICAgOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2Vcbn0pXG5leHBvcnQgY2xhc3MgTG9naW5Db21wb25lbnQgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgICAvKipcbiAgICAgKiBFcnJvciBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZXJyb3JNZXNzYWdlPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVXNlciBuYW1lIGJpbmRpbmcuXG4gICAgICovXG4gICAgcHVibGljIHVzZXJuYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUGFzc3dvcmQgYmluZGluZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgcGFzc3dvcmQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDb250cm9sIGZvciBcImxvZ2luIGJ1dHRvbi10by1zcGlubmVyXCIuXG4gICAgICovXG4gICAgcHVibGljIGxvZ2dpbmdJbiA9IGZhbHNlO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKEBJbmplY3QoQVVUSF9QUk9WSURFUikgcHJpdmF0ZSByZWFkb25seSBhdXRoUHJvdmlkZXI6IEF1dGhQcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSByZWFkb25seSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgYXV0aFJvdXRpbmdGbG93U2VydmljZTogQXV0aFJvdXRpbmdGbG93U2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgQEluamVjdChTRUNPTkRBUllfTE9HTykgcHJpdmF0ZSByZWFkb25seSBzZWNvbmRhcnlMb2dvOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLy8gVXBkYXRlIGNvbXBvbmVudCBzdGF0ZSBvbiBsb2dpbiBzdGF0dXMgY2hhbmdlXG4gICAgICAgIHRoaXMuYXV0aFByb3ZpZGVyLmxvZ2dlZEluU3RyZWFtLnBpcGUoXG4gICAgICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpXG4gICAgICAgICkuc3Vic2NyaWJlKCgpID0+IHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYXV0aFJvdXRpbmdGbG93U2VydmljZS5sb2dpblZpYVNlcnZpY2UoKS5waXBlKFxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKVxuICAgICAgICApLnN1YnNjcmliZShcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnI6IEVycm9yVHlwZXMpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IHRvRXJyb3JNZXNzYWdlKGVycikubWVzc2FnZTtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgaXNEaXJlY3RGbG93KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoUm91dGluZ0Zsb3dTZXJ2aWNlLmRpcmVjdEZsb3c7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhdXRoU3RhdHVzKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoUHJvdmlkZXIubG9nZ2VkSW47XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB1c2VyUHJvZmlsZSgpOiBPYnNlcnZhYmxlPFVzZXJJbmZvIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhQcm92aWRlci51c2VyUHJvZmlsZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbG9naW4oKTogdm9pZCB7XG4gICAgICAgIHRoaXMubG9nZ2luZ0luID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5hdXRoUm91dGluZ0Zsb3dTZXJ2aWNlLmxvZ2luKHRoaXMudXNlcm5hbWUsIHRoaXMucGFzc3dvcmQpLnBpcGUoXG4gICAgICAgICAgICBmaXJzdCgpXG4gICAgICAgICkuc3Vic2NyaWJlKFxuICAgICAgICAgICAgKHJlczogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghcmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZC4gU2VydmVyIGRpZCBub3QgZ2VuZXJhdGUgYSB0b2tlbi4nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dpbmdJbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2luZ0luID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnQXV0aGVudGljYXRpb24gZmFpbGVkLiBJcyB0aGUgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGNvcnJlY3Q/JztcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbG9nbygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWNvbmRhcnlMb2dvO1xuICAgIH1cbn1cbiIsIjxyaXNrLWZsZXg+XG4gICAgPHJpc2stZmxleC1zcGFjZXI+PC9yaXNrLWZsZXgtc3BhY2VyPlxuXG4gICAgPGRpdiAqbmdJZj1cImlzRGlyZWN0Rmxvd1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2xvZ2dlZE91dD5cbiAgICAgICAgICAgIDxyaXNrLWVycm9yICpuZ0lmPVwiZXJyb3JNZXNzYWdlXCIgW21lc3NhZ2VdPVwiZXJyb3JNZXNzYWdlXCI+PC9yaXNrLWVycm9yPlxuXG4gICAgICAgICAgICA8Zm9ybSAobmdTdWJtaXQpPVwibG9naW4oKVwiIHJvbGU9XCJmb3JtXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1jYXJkPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNhcmQtdGl0bGUtZ3JvdXA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhcmQtdGl0bGU+UGxlYXNlIFNpZ24gSW48L21hdC1jYXJkLXRpdGxlPlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1jYXJkLXRpdGxlLWdyb3VwPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNhcmQtY29udGVudD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInJpc2stZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiVXNlcm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidXNlcm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInVzZXJuYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b2ZvY3VzPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInJpc2stZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwicGFzc3dvcmRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlBhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYXNzd29yZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2FyZC1jb250ZW50PlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNhcmQtYWN0aW9ucz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCIhbG9nZ2luZ0luXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0LXJhaXNlZC1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInN1Ym1pdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpZ24gaW5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBbc3JjXT1cImxvZ29cIiBhbHQ9XCJDb21wYW55IGxvZ29cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciAqbmdJZj1cImxvZ2dpbmdJblwiIFtkaWFtZXRlcl09XCIzNlwiPjwvbWF0LXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNhcmQtYWN0aW9ucz5cbiAgICAgICAgICAgICAgICA8L21hdC1jYXJkPlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJhdXRoU3RhdHVzIHwgYXN5bmNcIiBbbmdJZkVsc2VdPVwibG9nZ2VkT3V0XCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwidXNlclByb2ZpbGUgfCBhc3luY1wiIGxldC11c2VyPVwibmdJZlwiPlxuICAgICAgICAgICAgICAgIDxyaXNrLWdvb2QgKm5nSWY9XCJ1c2VyPy5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFttZXNzYWdlXT1cIidTdWNjZXNzZnVsbHkgbG9nZ2VkIGluIGFzICcgKyB1c2VyLm5hbWUgKyAnLidcIj48L3Jpc2stZ29vZD5cbiAgICAgICAgICAgICAgICA8cmlzay1nb29kICpuZ0lmPVwiIXVzZXIgJiYgIXVzZXIubmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbWVzc2FnZV09XCInU3VjY2Vzc2Z1bGx5IGxvZ2dlZCBpbiEnXCI+PC9yaXNrLWdvb2Q+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cIiFpc0RpcmVjdEZsb3dcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFlcnJvck1lc3NhZ2VcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyaXNrLWxvZ2luLWZvcm0tZmxleC13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aDM+Q29udGFjdGluZyBhdXRoZW50aWNhdGlvbiBzZXJ2ZXIuLi48L2gzPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZXJyb3JNZXNzYWdlXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmlzay1sb2dpbi1mb3JtLWZsZXgtd3JhcHBlclwiPlxuICAgICAgICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwicmlzay1sb2dpbi1mb3JtLWVycm9yXCIgY29sb3I9XCJ3YXJuXCI+ZXJyb3Jfb3V0bGluZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGgzPkZhaWxlZCB0byBhdXRoZW50aWNhdGUgdXNlcjoge3tlcnJvck1lc3NhZ2V9fTwvaDM+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmlzay1sb2dpbi1mb3JtLWZsZXgtd3JhcHBlclwiPlxuICAgICAgICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwibG9naW4oKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YXV0b3JlbmV3PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgUmV0cnlcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG5cbiAgICA8cmlzay1mbGV4LXNwYWNlcj48L3Jpc2stZmxleC1zcGFjZXI+XG48L3Jpc2stZmxleD5cbiJdfQ==