UNPKG

152 kBJavaScriptView Raw
1import * as i0 from '@angular/core';
2import { InjectionToken, Injectable, Inject, Component, ChangeDetectionStrategy, Injector, NgModule } from '@angular/core';
3import * as i4 from '@angular/common';
4import { CommonModule } from '@angular/common';
5import * as i2 from '@angular/router';
6import { RouterModule } from '@angular/router';
7import * as i5 from '@angular/forms';
8import { FormsModule } from '@angular/forms';
9import * as i3 from '@nebular/theme';
10import { NB_WINDOW, NbLayoutModule, NbCardModule, NbCheckboxModule, NbAlertModule, NbInputModule, NbButtonModule, NbIconModule } from '@nebular/theme';
11import { BehaviorSubject, of, Subject } from 'rxjs';
12import { filter, share, map, switchMap, delay, catchError, takeUntil } from 'rxjs/operators';
13import * as i1 from '@angular/common/http';
14import { HttpResponse, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
15
16const socialLinks = [];
17const defaultAuthOptions = {
18 strategies: [],
19 forms: {
20 login: {
21 redirectDelay: 500,
22 strategy: 'email',
23 rememberMe: true,
24 showMessages: {
25 success: true,
26 error: true,
27 },
28 socialLinks: socialLinks, // social links at the bottom of a page
29 },
30 register: {
31 redirectDelay: 500,
32 strategy: 'email',
33 showMessages: {
34 success: true,
35 error: true,
36 },
37 terms: true,
38 socialLinks: socialLinks,
39 },
40 requestPassword: {
41 redirectDelay: 500,
42 strategy: 'email',
43 showMessages: {
44 success: true,
45 error: true,
46 },
47 socialLinks: socialLinks,
48 },
49 resetPassword: {
50 redirectDelay: 500,
51 strategy: 'email',
52 showMessages: {
53 success: true,
54 error: true,
55 },
56 socialLinks: socialLinks,
57 },
58 logout: {
59 redirectDelay: 500,
60 strategy: 'email',
61 },
62 validation: {
63 password: {
64 required: true,
65 minLength: 4,
66 maxLength: 50,
67 },
68 email: {
69 required: true,
70 },
71 fullName: {
72 required: false,
73 minLength: 4,
74 maxLength: 50,
75 },
76 },
77 },
78};
79const NB_AUTH_OPTIONS = new InjectionToken('Nebular Auth Options');
80const NB_AUTH_USER_OPTIONS = new InjectionToken('Nebular User Auth Options');
81const NB_AUTH_STRATEGIES = new InjectionToken('Nebular Auth Strategies');
82const NB_AUTH_TOKENS = new InjectionToken('Nebular Auth Tokens');
83const NB_AUTH_INTERCEPTOR_HEADER = new InjectionToken('Nebular Simple Interceptor Header');
84const NB_AUTH_TOKEN_INTERCEPTOR_FILTER = new InjectionToken('Nebular Interceptor Filter');
85
86/**
87 * Extending object that entered in first argument.
88 *
89 * Returns extended object or false if have no target object or incorrect type.
90 *
91 * If you wish to clone source object (without modify it), just use empty new
92 * object as first argument, like this:
93 * deepExtend({}, yourObj_1, [yourObj_N]);
94 */
95const deepExtend = function (...objects) {
96 if (arguments.length < 1 || typeof arguments[0] !== 'object') {
97 return false;
98 }
99 if (arguments.length < 2) {
100 return arguments[0];
101 }
102 const target = arguments[0];
103 // convert arguments to array and cut off target object
104 const args = Array.prototype.slice.call(arguments, 1);
105 let val, src;
106 args.forEach(function (obj) {
107 // skip argument if it is array or isn't object
108 if (typeof obj !== 'object' || Array.isArray(obj)) {
109 return;
110 }
111 Object.keys(obj).forEach(function (key) {
112 src = target[key]; // source value
113 val = obj[key]; // new value
114 // recursion prevention
115 if (val === target) {
116 return;
117 /**
118 * if new value isn't object then just overwrite by new value
119 * instead of extending.
120 */
121 }
122 else if (typeof val !== 'object' || val === null) {
123 target[key] = val;
124 return;
125 // just clone arrays (and recursive clone objects inside)
126 }
127 else if (Array.isArray(val)) {
128 target[key] = deepCloneArray(val);
129 return;
130 // custom cloning and overwrite for specific objects
131 }
132 else if (isSpecificValue(val)) {
133 target[key] = cloneSpecificValue(val);
134 return;
135 // overwrite by new value if source isn't object or array
136 }
137 else if (typeof src !== 'object' || src === null || Array.isArray(src)) {
138 target[key] = deepExtend({}, val);
139 return;
140 // source value and new value is objects both, extending...
141 }
142 else {
143 target[key] = deepExtend(src, val);
144 return;
145 }
146 });
147 });
148 return target;
149};
150function isSpecificValue(val) {
151 return (val instanceof Date
152 || val instanceof RegExp) ? true : false;
153}
154function cloneSpecificValue(val) {
155 if (val instanceof Date) {
156 return new Date(val.getTime());
157 }
158 else if (val instanceof RegExp) {
159 return new RegExp(val);
160 }
161 else {
162 throw new Error('cloneSpecificValue: Unexpected situation');
163 }
164}
165/**
166 * Recursive cloning array.
167 */
168function deepCloneArray(arr) {
169 const clone = [];
170 arr.forEach(function (item, index) {
171 if (typeof item === 'object' && item !== null) {
172 if (Array.isArray(item)) {
173 clone[index] = deepCloneArray(item);
174 }
175 else if (isSpecificValue(item)) {
176 clone[index] = cloneSpecificValue(item);
177 }
178 else {
179 clone[index] = deepExtend({}, item);
180 }
181 }
182 else {
183 clone[index] = item;
184 }
185 });
186 return clone;
187}
188// getDeepFromObject({result: {data: 1}}, 'result.data', 2); // returns 1
189function getDeepFromObject(object = {}, name, defaultValue) {
190 const keys = name.split('.');
191 // clone the object
192 let level = deepExtend({}, object || {});
193 keys.forEach((k) => {
194 if (level && typeof level[k] !== 'undefined') {
195 level = level[k];
196 }
197 else {
198 level = undefined;
199 }
200 });
201 return typeof level === 'undefined' ? defaultValue : level;
202}
203function urlBase64Decode(str) {
204 let output = str.replace(/-/g, '+').replace(/_/g, '/');
205 switch (output.length % 4) {
206 case 0: {
207 break;
208 }
209 case 2: {
210 output += '==';
211 break;
212 }
213 case 3: {
214 output += '=';
215 break;
216 }
217 default: {
218 throw new Error('Illegal base64url string!');
219 }
220 }
221 return b64DecodeUnicode(output);
222}
223function b64decode(str) {
224 const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
225 let output = '';
226 str = String(str).replace(/=+$/, '');
227 if (str.length % 4 === 1) {
228 throw new Error(`'atob' failed: The string to be decoded is not correctly encoded.`);
229 }
230 for (
231 // initialize result and counters
232 let bc = 0, bs, buffer, idx = 0;
233 // get next character
234 buffer = str.charAt(idx++);
235 // character found in table? initialize bit storage and add its ascii value;
236 ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
237 // and if not first of each 4 characters,
238 // convert the first 8 bits to one ascii character
239 bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0) {
240 // try to find character in table (0-63, not found => -1)
241 buffer = chars.indexOf(buffer);
242 }
243 return output;
244}
245// https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem
246function b64DecodeUnicode(str) {
247 return decodeURIComponent(Array.prototype.map.call(b64decode(str), (c) => {
248 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
249 }).join(''));
250}
251
252class NbAuthToken {
253 constructor() {
254 this.payload = null;
255 }
256 getName() {
257 return this.constructor.NAME;
258 }
259 getPayload() {
260 return this.payload;
261 }
262}
263class NbAuthTokenNotFoundError extends Error {
264 constructor(message) {
265 super(message);
266 Object.setPrototypeOf(this, new.target.prototype);
267 }
268}
269class NbAuthIllegalTokenError extends Error {
270 constructor(message) {
271 super(message);
272 Object.setPrototypeOf(this, new.target.prototype);
273 }
274}
275class NbAuthEmptyTokenError extends NbAuthIllegalTokenError {
276 constructor(message) {
277 super(message);
278 Object.setPrototypeOf(this, new.target.prototype);
279 }
280}
281class NbAuthIllegalJWTTokenError extends NbAuthIllegalTokenError {
282 constructor(message) {
283 super(message);
284 Object.setPrototypeOf(this, new.target.prototype);
285 }
286}
287function nbAuthCreateToken(tokenClass, token, ownerStrategyName, createdAt) {
288 return new tokenClass(token, ownerStrategyName, createdAt);
289}
290function decodeJwtPayload(payload) {
291 if (payload.length === 0) {
292 throw new NbAuthEmptyTokenError('Cannot extract from an empty payload.');
293 }
294 const parts = payload.split('.');
295 if (parts.length !== 3) {
296 throw new NbAuthIllegalJWTTokenError(`The payload ${payload} is not valid JWT payload and must consist of three parts.`);
297 }
298 let decoded;
299 try {
300 decoded = urlBase64Decode(parts[1]);
301 }
302 catch (e) {
303 throw new NbAuthIllegalJWTTokenError(`The payload ${payload} is not valid JWT payload and cannot be parsed.`);
304 }
305 if (!decoded) {
306 throw new NbAuthIllegalJWTTokenError(`The payload ${payload} is not valid JWT payload and cannot be decoded.`);
307 }
308 return JSON.parse(decoded);
309}
310/**
311 * Wrapper for simple (text) token
312 */
313class NbAuthSimpleToken extends NbAuthToken {
314 constructor(token, ownerStrategyName, createdAt) {
315 super();
316 this.token = token;
317 this.ownerStrategyName = ownerStrategyName;
318 this.createdAt = createdAt;
319 try {
320 this.parsePayload();
321 }
322 catch (err) {
323 if (!(err instanceof NbAuthTokenNotFoundError)) {
324 // token is present but has got a problem, including illegal
325 throw err;
326 }
327 }
328 this.createdAt = this.prepareCreatedAt(createdAt);
329 }
330 parsePayload() {
331 this.payload = null;
332 }
333 prepareCreatedAt(date) {
334 return date ? date : new Date();
335 }
336 /**
337 * Returns the token's creation date
338 * @returns {Date}
339 */
340 getCreatedAt() {
341 return this.createdAt;
342 }
343 /**
344 * Returns the token value
345 * @returns string
346 */
347 getValue() {
348 return this.token;
349 }
350 getOwnerStrategyName() {
351 return this.ownerStrategyName;
352 }
353 /**
354 * Is non empty and valid
355 * @returns {boolean}
356 */
357 isValid() {
358 return !!this.getValue();
359 }
360 /**
361 * Validate value and convert to string, if value is not valid return empty string
362 * @returns {string}
363 */
364 toString() {
365 return !!this.token ? this.token : '';
366 }
367}
368NbAuthSimpleToken.NAME = 'nb:auth:simple:token';
369/**
370 * Wrapper for JWT token with additional methods.
371 */
372class NbAuthJWTToken extends NbAuthSimpleToken {
373 /**
374 * for JWT token, the iat (issued at) field of the token payload contains the creation Date
375 */
376 prepareCreatedAt(date) {
377 const decoded = this.getPayload();
378 return decoded && decoded.iat ? new Date(Number(decoded.iat) * 1000) : super.prepareCreatedAt(date);
379 }
380 /**
381 * Returns payload object
382 * @returns any
383 */
384 parsePayload() {
385 if (!this.token) {
386 throw new NbAuthTokenNotFoundError('Token not found. ');
387 }
388 this.payload = decodeJwtPayload(this.token);
389 }
390 /**
391 * Returns expiration date
392 * @returns Date
393 */
394 getTokenExpDate() {
395 const decoded = this.getPayload();
396 if (decoded && !decoded.hasOwnProperty('exp')) {
397 return null;
398 }
399 const date = new Date(0);
400 date.setUTCSeconds(decoded.exp); // 'cause jwt token are set in seconds
401 return date;
402 }
403 /**
404 * Is data expired
405 * @returns {boolean}
406 */
407 isValid() {
408 return super.isValid() && (!this.getTokenExpDate() || new Date() < this.getTokenExpDate());
409 }
410}
411NbAuthJWTToken.NAME = 'nb:auth:jwt:token';
412const prepareOAuth2Token = (data) => {
413 if (typeof data === 'string') {
414 try {
415 return JSON.parse(data);
416 }
417 catch (e) { }
418 }
419 return data;
420};
421/**
422 * Wrapper for OAuth2 token whose access_token is a JWT Token
423 */
424class NbAuthOAuth2Token extends NbAuthSimpleToken {
425 constructor(data = {}, ownerStrategyName, createdAt) {
426 // we may get it as string when retrieving from a storage
427 super(prepareOAuth2Token(data), ownerStrategyName, createdAt);
428 }
429 /**
430 * Returns the token value
431 * @returns string
432 */
433 getValue() {
434 return this.token.access_token;
435 }
436 /**
437 * Returns the refresh token
438 * @returns string
439 */
440 getRefreshToken() {
441 return this.token.refresh_token;
442 }
443 /**
444 * put refreshToken in the token payload
445 * @param refreshToken
446 */
447 setRefreshToken(refreshToken) {
448 this.token.refresh_token = refreshToken;
449 }
450 /**
451 * Parses token payload
452 * @returns any
453 */
454 parsePayload() {
455 if (!this.token) {
456 throw new NbAuthTokenNotFoundError('Token not found.');
457 }
458 else {
459 if (!Object.keys(this.token).length) {
460 throw new NbAuthEmptyTokenError('Cannot extract payload from an empty token.');
461 }
462 }
463 this.payload = this.token;
464 }
465 /**
466 * Returns the token type
467 * @returns string
468 */
469 getType() {
470 return this.token.token_type;
471 }
472 /**
473 * Is data expired
474 * @returns {boolean}
475 */
476 isValid() {
477 return super.isValid() && (!this.getTokenExpDate() || new Date() < this.getTokenExpDate());
478 }
479 /**
480 * Returns expiration date
481 * @returns Date
482 */
483 getTokenExpDate() {
484 if (!this.token.hasOwnProperty('expires_in')) {
485 return null;
486 }
487 return new Date(this.createdAt.getTime() + Number(this.token.expires_in) * 1000);
488 }
489 /**
490 * Convert to string
491 * @returns {string}
492 */
493 toString() {
494 return JSON.stringify(this.token);
495 }
496}
497NbAuthOAuth2Token.NAME = 'nb:auth:oauth2:token';
498/**
499 * Wrapper for OAuth2 token embedding JWT tokens
500 */
501class NbAuthOAuth2JWTToken extends NbAuthOAuth2Token {
502 parsePayload() {
503 super.parsePayload();
504 this.parseAccessTokenPayload();
505 }
506 parseAccessTokenPayload() {
507 const accessToken = this.getValue();
508 if (!accessToken) {
509 throw new NbAuthTokenNotFoundError('access_token key not found.');
510 }
511 this.accessTokenPayload = decodeJwtPayload(accessToken);
512 }
513 /**
514 * Returns access token payload
515 * @returns any
516 */
517 getAccessTokenPayload() {
518 return this.accessTokenPayload;
519 }
520 /**
521 * for Oauth2 JWT token, the iat (issued at) field of the access_token payload
522 */
523 prepareCreatedAt(date) {
524 const payload = this.accessTokenPayload;
525 return payload && payload.iat ? new Date(Number(payload.iat) * 1000) : super.prepareCreatedAt(date);
526 }
527 /**
528 * Is token valid
529 * @returns {boolean}
530 */
531 isValid() {
532 return this.accessTokenPayload && super.isValid();
533 }
534 /**
535 * Returns expiration date :
536 * - exp if set,
537 * - super.getExpDate() otherwise
538 * @returns Date
539 */
540 getTokenExpDate() {
541 if (this.accessTokenPayload && this.accessTokenPayload.hasOwnProperty('exp')) {
542 const date = new Date(0);
543 date.setUTCSeconds(this.accessTokenPayload.exp);
544 return date;
545 }
546 else {
547 return super.getTokenExpDate();
548 }
549 }
550}
551NbAuthOAuth2JWTToken.NAME = 'nb:auth:oauth2:jwt:token';
552
553const NB_AUTH_FALLBACK_TOKEN = new InjectionToken('Nebular Auth Options');
554/**
555 * Creates a token parcel which could be stored/restored
556 */
557class NbAuthTokenParceler {
558 constructor(fallbackClass, tokenClasses) {
559 this.fallbackClass = fallbackClass;
560 this.tokenClasses = tokenClasses;
561 }
562 wrap(token) {
563 return JSON.stringify({
564 name: token.getName(),
565 ownerStrategyName: token.getOwnerStrategyName(),
566 createdAt: token.getCreatedAt().getTime(),
567 value: token.toString(),
568 });
569 }
570 unwrap(value) {
571 let tokenClass = this.fallbackClass;
572 let tokenValue = '';
573 let tokenOwnerStrategyName = '';
574 let tokenCreatedAt = null;
575 const tokenPack = this.parseTokenPack(value);
576 if (tokenPack) {
577 tokenClass = this.getClassByName(tokenPack.name) || this.fallbackClass;
578 tokenValue = tokenPack.value;
579 tokenOwnerStrategyName = tokenPack.ownerStrategyName;
580 tokenCreatedAt = new Date(Number(tokenPack.createdAt));
581 }
582 return nbAuthCreateToken(tokenClass, tokenValue, tokenOwnerStrategyName, tokenCreatedAt);
583 }
584 // TODO: this could be moved to a separate token registry
585 getClassByName(name) {
586 return this.tokenClasses.find((tokenClass) => tokenClass.NAME === name);
587 }
588 parseTokenPack(value) {
589 try {
590 return JSON.parse(value);
591 }
592 catch (e) { }
593 return null;
594 }
595}
596NbAuthTokenParceler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthTokenParceler, deps: [{ token: NB_AUTH_FALLBACK_TOKEN }, { token: NB_AUTH_TOKENS }], target: i0.ɵɵFactoryTarget.Injectable });
597NbAuthTokenParceler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthTokenParceler });
598i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthTokenParceler, decorators: [{
599 type: Injectable
600 }], ctorParameters: function () { return [{ type: undefined, decorators: [{
601 type: Inject,
602 args: [NB_AUTH_FALLBACK_TOKEN]
603 }] }, { type: undefined, decorators: [{
604 type: Inject,
605 args: [NB_AUTH_TOKENS]
606 }] }]; } });
607
608class NbTokenStorage {
609}
610/**
611 * Service that uses browser localStorage as a storage.
612 *
613 * The token storage is provided into auth module the following way:
614 * ```ts
615 * { provide: NbTokenStorage, useClass: NbTokenLocalStorage },
616 * ```
617 *
618 * If you need to change the storage behaviour or provide your own - just extend your class from basic `NbTokenStorage`
619 * or `NbTokenLocalStorage` and provide in your `app.module`:
620 * ```ts
621 * { provide: NbTokenStorage, useClass: NbTokenCustomStorage },
622 * ```
623 *
624 */
625class NbTokenLocalStorage extends NbTokenStorage {
626 constructor(parceler) {
627 super();
628 this.parceler = parceler;
629 this.key = 'auth_app_token';
630 }
631 /**
632 * Returns token from localStorage
633 * @returns {NbAuthToken}
634 */
635 get() {
636 const raw = localStorage.getItem(this.key);
637 return this.parceler.unwrap(raw);
638 }
639 /**
640 * Sets token to localStorage
641 * @param {NbAuthToken} token
642 */
643 set(token) {
644 const raw = this.parceler.wrap(token);
645 localStorage.setItem(this.key, raw);
646 }
647 /**
648 * Clears token from localStorage
649 */
650 clear() {
651 localStorage.removeItem(this.key);
652 }
653}
654NbTokenLocalStorage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenLocalStorage, deps: [{ token: NbAuthTokenParceler }], target: i0.ɵɵFactoryTarget.Injectable });
655NbTokenLocalStorage.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenLocalStorage });
656i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenLocalStorage, decorators: [{
657 type: Injectable
658 }], ctorParameters: function () { return [{ type: NbAuthTokenParceler }]; } });
659
660/**
661 * Service that allows you to manage authentication token - get, set, clear and also listen to token changes over time.
662 */
663class NbTokenService {
664 constructor(tokenStorage) {
665 this.tokenStorage = tokenStorage;
666 this.token$ = new BehaviorSubject(null);
667 this.publishStoredToken();
668 }
669 /**
670 * Publishes token when it changes.
671 * @returns {Observable<NbAuthToken>}
672 */
673 tokenChange() {
674 return this.token$
675 .pipe(filter(value => !!value), share());
676 }
677 /**
678 * Sets a token into the storage. This method is used by the NbAuthService automatically.
679 *
680 * @param {NbAuthToken} token
681 * @returns {Observable<any>}
682 */
683 set(token) {
684 this.tokenStorage.set(token);
685 this.publishStoredToken();
686 return of(null);
687 }
688 /**
689 * Returns observable of current token
690 * @returns {Observable<NbAuthToken>}
691 */
692 get() {
693 const token = this.tokenStorage.get();
694 return of(token);
695 }
696 /**
697 * Removes the token and published token value
698 *
699 * @returns {Observable<any>}
700 */
701 clear() {
702 this.tokenStorage.clear();
703 this.publishStoredToken();
704 return of(null);
705 }
706 publishStoredToken() {
707 this.token$.next(this.tokenStorage.get());
708 }
709}
710NbTokenService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenService, deps: [{ token: NbTokenStorage }], target: i0.ɵɵFactoryTarget.Injectable });
711NbTokenService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenService });
712i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbTokenService, decorators: [{
713 type: Injectable
714 }], ctorParameters: function () { return [{ type: NbTokenStorage }]; } });
715
716/**
717 * @license
718 * Copyright Akveo. All Rights Reserved.
719 * Licensed under the MIT License. See License.txt in the project root for license information.
720 */
721/**
722 * Common authentication service.
723 * Should be used to as an interlayer between UI Components and Auth Strategy.
724 */
725class NbAuthService {
726 constructor(tokenService, strategies) {
727 this.tokenService = tokenService;
728 this.strategies = strategies;
729 }
730 /**
731 * Retrieves current authenticated token stored
732 * @returns {Observable<any>}
733 */
734 getToken() {
735 return this.tokenService.get();
736 }
737 /**
738 * Returns true if auth token is present in the token storage
739 * @returns {Observable<boolean>}
740 */
741 isAuthenticated() {
742 return this.getToken()
743 .pipe(map((token) => token.isValid()));
744 }
745 /**
746 * Returns true if valid auth token is present in the token storage.
747 * If not, calls the strategy refreshToken, and returns isAuthenticated() if success, false otherwise
748 * @returns {Observable<boolean>}
749 */
750 isAuthenticatedOrRefresh() {
751 return this.getToken()
752 .pipe(switchMap(token => {
753 if (token.getValue() && !token.isValid()) {
754 return this.refreshToken(token.getOwnerStrategyName(), token)
755 .pipe(switchMap(res => {
756 if (res.isSuccess()) {
757 return this.isAuthenticated();
758 }
759 else {
760 return of(false);
761 }
762 }));
763 }
764 else {
765 return of(token.isValid());
766 }
767 }));
768 }
769 /**
770 * Returns tokens stream
771 * @returns {Observable<NbAuthSimpleToken>}
772 */
773 onTokenChange() {
774 return this.tokenService.tokenChange();
775 }
776 /**
777 * Returns authentication status stream
778 * @returns {Observable<boolean>}
779 */
780 onAuthenticationChange() {
781 return this.onTokenChange()
782 .pipe(map((token) => token.isValid()));
783 }
784 /**
785 * Authenticates with the selected strategy
786 * Stores received token in the token storage
787 *
788 * Example:
789 * authenticate('email', {email: 'email@example.com', password: 'test'})
790 *
791 * @param strategyName
792 * @param data
793 * @returns {Observable<NbAuthResult>}
794 */
795 authenticate(strategyName, data) {
796 return this.getStrategy(strategyName).authenticate(data)
797 .pipe(switchMap((result) => {
798 return this.processResultToken(result);
799 }));
800 }
801 /**
802 * Registers with the selected strategy
803 * Stores received token in the token storage
804 *
805 * Example:
806 * register('email', {email: 'email@example.com', name: 'Some Name', password: 'test'})
807 *
808 * @param strategyName
809 * @param data
810 * @returns {Observable<NbAuthResult>}
811 */
812 register(strategyName, data) {
813 return this.getStrategy(strategyName).register(data)
814 .pipe(switchMap((result) => {
815 return this.processResultToken(result);
816 }));
817 }
818 /**
819 * Sign outs with the selected strategy
820 * Removes token from the token storage
821 *
822 * Example:
823 * logout('email')
824 *
825 * @param strategyName
826 * @returns {Observable<NbAuthResult>}
827 */
828 logout(strategyName) {
829 return this.getStrategy(strategyName).logout()
830 .pipe(switchMap((result) => {
831 if (result.isSuccess()) {
832 this.tokenService.clear()
833 .pipe(map(() => result));
834 }
835 return of(result);
836 }));
837 }
838 /**
839 * Sends forgot password request to the selected strategy
840 *
841 * Example:
842 * requestPassword('email', {email: 'email@example.com'})
843 *
844 * @param strategyName
845 * @param data
846 * @returns {Observable<NbAuthResult>}
847 */
848 requestPassword(strategyName, data) {
849 return this.getStrategy(strategyName).requestPassword(data);
850 }
851 /**
852 * Tries to reset password with the selected strategy
853 *
854 * Example:
855 * resetPassword('email', {newPassword: 'test'})
856 *
857 * @param strategyName
858 * @param data
859 * @returns {Observable<NbAuthResult>}
860 */
861 resetPassword(strategyName, data) {
862 return this.getStrategy(strategyName).resetPassword(data);
863 }
864 /**
865 * Sends a refresh token request
866 * Stores received token in the token storage
867 *
868 * Example:
869 * refreshToken('email', {token: token})
870 *
871 * @param {string} strategyName
872 * @param data
873 * @returns {Observable<NbAuthResult>}
874 */
875 refreshToken(strategyName, data) {
876 return this.getStrategy(strategyName).refreshToken(data)
877 .pipe(switchMap((result) => {
878 return this.processResultToken(result);
879 }));
880 }
881 /**
882 * Get registered strategy by name
883 *
884 * Example:
885 * getStrategy('email')
886 *
887 * @param {string} provider
888 * @returns {NbAbstractAuthProvider}
889 */
890 getStrategy(strategyName) {
891 const found = this.strategies.find((strategy) => strategy.getName() === strategyName);
892 if (!found) {
893 throw new TypeError(`There is no Auth Strategy registered under '${strategyName}' name`);
894 }
895 return found;
896 }
897 processResultToken(result) {
898 if (result.isSuccess() && result.getToken()) {
899 return this.tokenService.set(result.getToken())
900 .pipe(map((token) => {
901 return result;
902 }));
903 }
904 return of(result);
905 }
906}
907NbAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthService, deps: [{ token: NbTokenService }, { token: NB_AUTH_STRATEGIES }], target: i0.ɵɵFactoryTarget.Injectable });
908NbAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthService });
909i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthService, decorators: [{
910 type: Injectable
911 }], ctorParameters: function () { return [{ type: NbTokenService }, { type: undefined, decorators: [{
912 type: Inject,
913 args: [NB_AUTH_STRATEGIES]
914 }] }]; } });
915
916class NbAuthStrategy {
917 // we should keep this any and validation should be done in `register` method instead
918 // otherwise it won't be possible to pass an empty object
919 setOptions(options) {
920 this.options = deepExtend({}, this.defaultOptions, options);
921 }
922 getOption(key) {
923 return getDeepFromObject(this.options, key, null);
924 }
925 createToken(value, failWhenInvalidToken) {
926 const token = nbAuthCreateToken(this.getOption('token.class'), value, this.getName());
927 // At this point, nbAuthCreateToken failed with NbAuthIllegalTokenError which MUST be intercepted by strategies
928 // Or token is created. It MAY be created even if backend did not return any token, in this case it is !Valid
929 if (failWhenInvalidToken && !token.isValid()) {
930 // If we require a valid token (i.e. isValid), then we MUST throw NbAuthIllegalTokenError so that the strategies
931 // intercept it
932 throw new NbAuthIllegalTokenError('Token is empty or invalid.');
933 }
934 return token;
935 }
936 getName() {
937 return this.getOption('name');
938 }
939 createFailResponse(data) {
940 return new HttpResponse({ body: {}, status: 401 });
941 }
942 createSuccessResponse(data) {
943 return new HttpResponse({ body: {}, status: 200 });
944 }
945 getActionEndpoint(action) {
946 const actionEndpoint = this.getOption(`${action}.endpoint`);
947 const baseEndpoint = this.getOption('baseEndpoint');
948 return actionEndpoint ? baseEndpoint + actionEndpoint : '';
949 }
950 getHeaders() {
951 const customHeaders = this.getOption('headers') ?? {};
952 if (customHeaders instanceof HttpHeaders) {
953 return customHeaders;
954 }
955 let headers = new HttpHeaders();
956 Object.entries(customHeaders).forEach(([key, value]) => {
957 headers = headers.append(key, value);
958 });
959 return headers;
960 }
961}
962
963class NbAuthResult {
964 // TODO: better pass object
965 constructor(success, response, redirect, errors, messages, token = null) {
966 this.success = success;
967 this.response = response;
968 this.redirect = redirect;
969 this.errors = [];
970 this.messages = [];
971 this.errors = this.errors.concat([errors]);
972 if (errors instanceof Array) {
973 this.errors = errors;
974 }
975 this.messages = this.messages.concat([messages]);
976 if (messages instanceof Array) {
977 this.messages = messages;
978 }
979 this.token = token;
980 }
981 getResponse() {
982 return this.response;
983 }
984 getToken() {
985 return this.token;
986 }
987 getRedirect() {
988 return this.redirect;
989 }
990 getErrors() {
991 return this.errors.filter(val => !!val);
992 }
993 getMessages() {
994 return this.messages.filter(val => !!val);
995 }
996 isSuccess() {
997 return this.success;
998 }
999 isFailure() {
1000 return !this.success;
1001 }
1002}
1003
1004class NbAuthStrategyOptions {
1005}
1006
1007/**
1008 * @license
1009 * Copyright Akveo. All Rights Reserved.
1010 * Licensed under the MIT License. See License.txt in the project root for license information.
1011 */
1012class NbDummyAuthStrategyOptions extends NbAuthStrategyOptions {
1013 constructor() {
1014 super(...arguments);
1015 this.token = {
1016 class: NbAuthSimpleToken,
1017 };
1018 this.delay = 1000;
1019 this.alwaysFail = false;
1020 }
1021}
1022const dummyStrategyOptions = new NbDummyAuthStrategyOptions();
1023
1024/**
1025 * Dummy auth strategy. Could be useful for auth setup when backend is not available yet.
1026 *
1027 *
1028 * Strategy settings.
1029 *
1030 * ```ts
1031 * export class NbDummyAuthStrategyOptions extends NbAuthStrategyOptions {
1032 * name = 'dummy';
1033 * token = {
1034 * class: NbAuthSimpleToken,
1035 * };
1036 * delay? = 1000;
1037 * alwaysFail? = false;
1038 * }
1039 * ```
1040 */
1041class NbDummyAuthStrategy extends NbAuthStrategy {
1042 constructor() {
1043 super(...arguments);
1044 this.defaultOptions = dummyStrategyOptions;
1045 }
1046 static setup(options) {
1047 return [NbDummyAuthStrategy, options];
1048 }
1049 authenticate(data) {
1050 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1051 }
1052 register(data) {
1053 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1054 }
1055 requestPassword(data) {
1056 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1057 }
1058 resetPassword(data) {
1059 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1060 }
1061 logout(data) {
1062 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1063 }
1064 refreshToken(data) {
1065 return of(this.createDummyResult(data)).pipe(delay(this.getOption('delay')));
1066 }
1067 createDummyResult(data) {
1068 if (this.getOption('alwaysFail')) {
1069 return new NbAuthResult(false, this.createFailResponse(data), null, ['Something went wrong.']);
1070 }
1071 try {
1072 const token = this.createToken('test token', true);
1073 return new NbAuthResult(true, this.createSuccessResponse(data), '/', [], ['Successfully logged in.'], token);
1074 }
1075 catch (err) {
1076 return new NbAuthResult(false, this.createFailResponse(data), null, [err.message]);
1077 }
1078 }
1079}
1080NbDummyAuthStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbDummyAuthStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1081NbDummyAuthStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbDummyAuthStrategy });
1082i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbDummyAuthStrategy, decorators: [{
1083 type: Injectable
1084 }] });
1085
1086/**
1087 * @license
1088 * Copyright Akveo. All Rights Reserved.
1089 * Licensed under the MIT License. See License.txt in the project root for license information.
1090 */
1091var NbOAuth2ResponseType;
1092(function (NbOAuth2ResponseType) {
1093 NbOAuth2ResponseType["CODE"] = "code";
1094 NbOAuth2ResponseType["TOKEN"] = "token";
1095})(NbOAuth2ResponseType || (NbOAuth2ResponseType = {}));
1096// TODO: client_credentials
1097var NbOAuth2GrantType;
1098(function (NbOAuth2GrantType) {
1099 NbOAuth2GrantType["AUTHORIZATION_CODE"] = "authorization_code";
1100 NbOAuth2GrantType["PASSWORD"] = "password";
1101 NbOAuth2GrantType["REFRESH_TOKEN"] = "refresh_token";
1102})(NbOAuth2GrantType || (NbOAuth2GrantType = {}));
1103var NbOAuth2ClientAuthMethod;
1104(function (NbOAuth2ClientAuthMethod) {
1105 NbOAuth2ClientAuthMethod["NONE"] = "none";
1106 NbOAuth2ClientAuthMethod["BASIC"] = "basic";
1107 NbOAuth2ClientAuthMethod["REQUEST_BODY"] = "request-body";
1108})(NbOAuth2ClientAuthMethod || (NbOAuth2ClientAuthMethod = {}));
1109class NbOAuth2AuthStrategyOptions extends NbAuthStrategyOptions {
1110 constructor() {
1111 super(...arguments);
1112 this.baseEndpoint = '';
1113 this.clientId = '';
1114 this.clientSecret = '';
1115 this.clientAuthMethod = NbOAuth2ClientAuthMethod.NONE;
1116 this.redirect = {
1117 success: '/',
1118 failure: null,
1119 };
1120 this.defaultErrors = ['Something went wrong, please try again.'];
1121 this.defaultMessages = ['You have been successfully authenticated.'];
1122 this.authorize = {
1123 endpoint: 'authorize',
1124 responseType: NbOAuth2ResponseType.CODE,
1125 requireValidToken: true,
1126 };
1127 this.token = {
1128 endpoint: 'token',
1129 grantType: NbOAuth2GrantType.AUTHORIZATION_CODE,
1130 requireValidToken: true,
1131 class: NbAuthOAuth2Token,
1132 };
1133 this.refresh = {
1134 endpoint: 'token',
1135 grantType: NbOAuth2GrantType.REFRESH_TOKEN,
1136 requireValidToken: true,
1137 };
1138 }
1139}
1140const auth2StrategyOptions = new NbOAuth2AuthStrategyOptions();
1141
1142/**
1143 * @license
1144 * Copyright Akveo. All Rights Reserved.
1145 * Licensed under the MIT License. See License.txt in the project root for license information.
1146 */
1147/**
1148 * OAuth2 authentication strategy.
1149 *
1150 * Strategy settings:
1151 *
1152 * ```ts
1153 * export enum NbOAuth2ResponseType {
1154 * CODE = 'code',
1155 * TOKEN = 'token',
1156 * }
1157 *
1158 * export enum NbOAuth2GrantType {
1159 * AUTHORIZATION_CODE = 'authorization_code',
1160 * PASSWORD = 'password',
1161 * REFRESH_TOKEN = 'refresh_token',
1162 * }
1163 *
1164 * export class NbOAuth2AuthStrategyOptions {
1165 * name: string;
1166 * baseEndpoint?: string = '';
1167 * clientId: string = '';
1168 * clientSecret: string = '';
1169 * clientAuthMethod: string = NbOAuth2ClientAuthMethod.NONE;
1170 * redirect?: { success?: string; failure?: string } = {
1171 * success: '/',
1172 * failure: null,
1173 * };
1174 * defaultErrors?: any[] = ['Something went wrong, please try again.'];
1175 * defaultMessages?: any[] = ['You have been successfully authenticated.'];
1176 * authorize?: {
1177 * endpoint?: string;
1178 * redirectUri?: string;
1179 * responseType?: string;
1180 * requireValidToken: true,
1181 * scope?: string;
1182 * state?: string;
1183 * params?: { [key: string]: string };
1184 * } = {
1185 * endpoint: 'authorize',
1186 * responseType: NbOAuth2ResponseType.CODE,
1187 * };
1188 * token?: {
1189 * endpoint?: string;
1190 * grantType?: string;
1191 * requireValidToken: true,
1192 * redirectUri?: string;
1193 * scope?: string;
1194 * class: NbAuthTokenClass,
1195 * } = {
1196 * endpoint: 'token',
1197 * grantType: NbOAuth2GrantType.AUTHORIZATION_CODE,
1198 * class: NbAuthOAuth2Token,
1199 * };
1200 * refresh?: {
1201 * endpoint?: string;
1202 * grantType?: string;
1203 * scope?: string;
1204 * requireValidToken: true,
1205 * } = {
1206 * endpoint: 'token',
1207 * grantType: NbOAuth2GrantType.REFRESH_TOKEN,
1208 * };
1209 * }
1210 * ```
1211 *
1212 */
1213class NbOAuth2AuthStrategy extends NbAuthStrategy {
1214 constructor(http, route, window) {
1215 super();
1216 this.http = http;
1217 this.route = route;
1218 this.window = window;
1219 this.redirectResultHandlers = {
1220 [NbOAuth2ResponseType.CODE]: () => {
1221 return of(this.route.snapshot.queryParams).pipe(switchMap((params) => {
1222 if (params.code) {
1223 return this.requestToken(params.code);
1224 }
1225 return of(new NbAuthResult(false, params, this.getOption('redirect.failure'), this.getOption('defaultErrors'), []));
1226 }));
1227 },
1228 [NbOAuth2ResponseType.TOKEN]: () => {
1229 const module = 'authorize';
1230 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1231 return of(this.route.snapshot.fragment).pipe(map((fragment) => this.parseHashAsQueryParams(fragment)), map((params) => {
1232 if (!params.error) {
1233 return new NbAuthResult(true, params, this.getOption('redirect.success'), [], this.getOption('defaultMessages'), this.createToken(params, requireValidToken));
1234 }
1235 return new NbAuthResult(false, params, this.getOption('redirect.failure'), this.getOption('defaultErrors'), []);
1236 }), catchError((err) => {
1237 const errors = [];
1238 if (err instanceof NbAuthIllegalTokenError) {
1239 errors.push(err.message);
1240 }
1241 else {
1242 errors.push('Something went wrong.');
1243 }
1244 return of(new NbAuthResult(false, err, this.getOption('redirect.failure'), errors));
1245 }));
1246 },
1247 };
1248 this.redirectResults = {
1249 [NbOAuth2ResponseType.CODE]: () => {
1250 return of(this.route.snapshot.queryParams).pipe(map((params) => !!(params && (params.code || params.error))));
1251 },
1252 [NbOAuth2ResponseType.TOKEN]: () => {
1253 return of(this.route.snapshot.fragment).pipe(map((fragment) => this.parseHashAsQueryParams(fragment)), map((params) => !!(params && (params.access_token || params.error))));
1254 },
1255 };
1256 this.defaultOptions = auth2StrategyOptions;
1257 }
1258 static setup(options) {
1259 return [NbOAuth2AuthStrategy, options];
1260 }
1261 get responseType() {
1262 return this.getOption('authorize.responseType');
1263 }
1264 get clientAuthMethod() {
1265 return this.getOption('clientAuthMethod');
1266 }
1267 authenticate(data) {
1268 if (this.getOption('token.grantType') === NbOAuth2GrantType.PASSWORD) {
1269 return this.passwordToken(data.email, data.password);
1270 }
1271 else {
1272 return this.isRedirectResult().pipe(switchMap((result) => {
1273 if (!result) {
1274 this.authorizeRedirect();
1275 return of(new NbAuthResult(true));
1276 }
1277 return this.getAuthorizationResult();
1278 }));
1279 }
1280 }
1281 getAuthorizationResult() {
1282 const redirectResultHandler = this.redirectResultHandlers[this.responseType];
1283 if (redirectResultHandler) {
1284 return redirectResultHandler.call(this);
1285 }
1286 throw new Error(`'${this.responseType}' responseType is not supported,
1287 only 'token' and 'code' are supported now`);
1288 }
1289 refreshToken(token) {
1290 const module = 'refresh';
1291 const url = this.getActionEndpoint(module);
1292 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1293 return this.http.post(url, this.buildRefreshRequestData(token), { headers: this.getHeaders() }).pipe(map((res) => {
1294 return new NbAuthResult(true, res, this.getOption('redirect.success'), [], this.getOption('defaultMessages'), this.createRefreshedToken(res, token, requireValidToken));
1295 }), catchError((res) => this.handleResponseError(res)));
1296 }
1297 passwordToken(username, password) {
1298 const module = 'token';
1299 const url = this.getActionEndpoint(module);
1300 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1301 return this.http.post(url, this.buildPasswordRequestData(username, password), { headers: this.getHeaders() }).pipe(map((res) => {
1302 return new NbAuthResult(true, res, this.getOption('redirect.success'), [], this.getOption('defaultMessages'), this.createToken(res, requireValidToken));
1303 }), catchError((res) => this.handleResponseError(res)));
1304 }
1305 authorizeRedirect() {
1306 this.window.location.href = this.buildRedirectUrl();
1307 }
1308 isRedirectResult() {
1309 return this.redirectResults[this.responseType].call(this);
1310 }
1311 requestToken(code) {
1312 const module = 'token';
1313 const url = this.getActionEndpoint(module);
1314 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1315 return this.http.post(url, this.buildCodeRequestData(code), { headers: this.getHeaders() }).pipe(map((res) => {
1316 return new NbAuthResult(true, res, this.getOption('redirect.success'), [], this.getOption('defaultMessages'), this.createToken(res, requireValidToken));
1317 }), catchError((res) => this.handleResponseError(res)));
1318 }
1319 buildCodeRequestData(code) {
1320 const params = {
1321 grant_type: this.getOption('token.grantType'),
1322 code: code,
1323 redirect_uri: this.getOption('token.redirectUri'),
1324 client_id: this.getOption('clientId'),
1325 };
1326 return this.urlEncodeParameters(this.cleanParams(this.addCredentialsToParams(params)));
1327 }
1328 buildRefreshRequestData(token) {
1329 const params = {
1330 grant_type: this.getOption('refresh.grantType'),
1331 refresh_token: token.getRefreshToken(),
1332 scope: this.getOption('refresh.scope'),
1333 client_id: this.getOption('clientId'),
1334 };
1335 return this.urlEncodeParameters(this.cleanParams(this.addCredentialsToParams(params)));
1336 }
1337 buildPasswordRequestData(username, password) {
1338 const params = {
1339 grant_type: this.getOption('token.grantType'),
1340 username: username,
1341 password: password,
1342 scope: this.getOption('token.scope'),
1343 };
1344 return this.urlEncodeParameters(this.cleanParams(this.addCredentialsToParams(params)));
1345 }
1346 buildAuthHeader() {
1347 if (this.clientAuthMethod === NbOAuth2ClientAuthMethod.BASIC) {
1348 if (this.getOption('clientId') && this.getOption('clientSecret')) {
1349 return new HttpHeaders({
1350 Authorization: 'Basic ' + btoa(this.getOption('clientId') + ':' + this.getOption('clientSecret')),
1351 });
1352 }
1353 else {
1354 throw Error('For basic client authentication method, please provide both clientId & clientSecret.');
1355 }
1356 }
1357 return undefined;
1358 }
1359 getHeaders() {
1360 let headers = super.getHeaders();
1361 headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
1362 const authHeaders = this.buildAuthHeader();
1363 if (authHeaders === undefined) {
1364 return headers;
1365 }
1366 for (const headerKey of authHeaders.keys()) {
1367 for (const headerValue of authHeaders.getAll(headerKey)) {
1368 headers = headers.append(headerKey, headerValue);
1369 }
1370 }
1371 return headers;
1372 }
1373 cleanParams(params) {
1374 Object.entries(params).forEach(([key, val]) => !val && delete params[key]);
1375 return params;
1376 }
1377 addCredentialsToParams(params) {
1378 if (this.clientAuthMethod === NbOAuth2ClientAuthMethod.REQUEST_BODY) {
1379 if (this.getOption('clientId') && this.getOption('clientSecret')) {
1380 return {
1381 ...params,
1382 client_id: this.getOption('clientId'),
1383 client_secret: this.getOption('clientSecret'),
1384 };
1385 }
1386 else {
1387 throw Error('For request body client authentication method, please provide both clientId & clientSecret.');
1388 }
1389 }
1390 return params;
1391 }
1392 handleResponseError(res) {
1393 let errors = [];
1394 if (res instanceof HttpErrorResponse) {
1395 if (res.error.error_description) {
1396 errors.push(res.error.error_description);
1397 }
1398 else {
1399 errors = this.getOption('defaultErrors');
1400 }
1401 }
1402 else if (res instanceof NbAuthIllegalTokenError) {
1403 errors.push(res.message);
1404 }
1405 else {
1406 errors.push('Something went wrong.');
1407 }
1408 return of(new NbAuthResult(false, res, this.getOption('redirect.failure'), errors, []));
1409 }
1410 buildRedirectUrl() {
1411 const params = {
1412 response_type: this.getOption('authorize.responseType'),
1413 client_id: this.getOption('clientId'),
1414 redirect_uri: this.getOption('authorize.redirectUri'),
1415 scope: this.getOption('authorize.scope'),
1416 state: this.getOption('authorize.state'),
1417 ...this.getOption('authorize.params'),
1418 };
1419 const endpoint = this.getActionEndpoint('authorize');
1420 const query = this.urlEncodeParameters(this.cleanParams(params));
1421 return `${endpoint}?${query}`;
1422 }
1423 parseHashAsQueryParams(hash) {
1424 return hash
1425 ? hash.split('&').reduce((acc, part) => {
1426 const item = part.split('=');
1427 acc[item[0]] = decodeURIComponent(item[1]);
1428 return acc;
1429 }, {})
1430 : {};
1431 }
1432 urlEncodeParameters(params) {
1433 return Object.keys(params)
1434 .map((k) => {
1435 return `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`;
1436 })
1437 .join('&');
1438 }
1439 createRefreshedToken(res, existingToken, requireValidToken) {
1440 const refreshedToken = this.createToken(res, requireValidToken);
1441 if (!refreshedToken.getRefreshToken() && existingToken.getRefreshToken()) {
1442 refreshedToken.setRefreshToken(existingToken.getRefreshToken());
1443 }
1444 return refreshedToken;
1445 }
1446 register(data) {
1447 throw new Error('`register` is not supported by `NbOAuth2AuthStrategy`, use `authenticate`.');
1448 }
1449 requestPassword(data) {
1450 throw new Error('`requestPassword` is not supported by `NbOAuth2AuthStrategy`, use `authenticate`.');
1451 }
1452 resetPassword(data = {}) {
1453 throw new Error('`resetPassword` is not supported by `NbOAuth2AuthStrategy`, use `authenticate`.');
1454 }
1455 logout() {
1456 return of(new NbAuthResult(true));
1457 }
1458}
1459NbOAuth2AuthStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbOAuth2AuthStrategy, deps: [{ token: i1.HttpClient }, { token: i2.ActivatedRoute }, { token: NB_WINDOW }], target: i0.ɵɵFactoryTarget.Injectable });
1460NbOAuth2AuthStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbOAuth2AuthStrategy });
1461i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbOAuth2AuthStrategy, decorators: [{
1462 type: Injectable
1463 }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ActivatedRoute }, { type: undefined, decorators: [{
1464 type: Inject,
1465 args: [NB_WINDOW]
1466 }] }]; } });
1467
1468/**
1469 * @license
1470 * Copyright Akveo. All Rights Reserved.
1471 * Licensed under the MIT License. See License.txt in the project root for license information.
1472 */
1473class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions {
1474 constructor() {
1475 super(...arguments);
1476 this.baseEndpoint = '/api/auth/';
1477 this.login = {
1478 alwaysFail: false,
1479 endpoint: 'login',
1480 method: 'post',
1481 requireValidToken: true,
1482 redirect: {
1483 success: '/',
1484 failure: null,
1485 },
1486 defaultErrors: ['Login/Email combination is not correct, please try again.'],
1487 defaultMessages: ['You have been successfully logged in.'],
1488 };
1489 this.register = {
1490 alwaysFail: false,
1491 endpoint: 'register',
1492 method: 'post',
1493 requireValidToken: true,
1494 redirect: {
1495 success: '/',
1496 failure: null,
1497 },
1498 defaultErrors: ['Something went wrong, please try again.'],
1499 defaultMessages: ['You have been successfully registered.'],
1500 };
1501 this.requestPass = {
1502 endpoint: 'request-pass',
1503 method: 'post',
1504 redirect: {
1505 success: '/',
1506 failure: null,
1507 },
1508 defaultErrors: ['Something went wrong, please try again.'],
1509 defaultMessages: ['Reset password instructions have been sent to your email.'],
1510 };
1511 this.resetPass = {
1512 endpoint: 'reset-pass',
1513 method: 'put',
1514 redirect: {
1515 success: '/',
1516 failure: null,
1517 },
1518 resetPasswordTokenKey: 'reset_password_token',
1519 defaultErrors: ['Something went wrong, please try again.'],
1520 defaultMessages: ['Your password has been successfully changed.'],
1521 };
1522 this.logout = {
1523 alwaysFail: false,
1524 endpoint: 'logout',
1525 method: 'delete',
1526 redirect: {
1527 success: '/',
1528 failure: null,
1529 },
1530 defaultErrors: ['Something went wrong, please try again.'],
1531 defaultMessages: ['You have been successfully logged out.'],
1532 };
1533 this.refreshToken = {
1534 endpoint: 'refresh-token',
1535 method: 'post',
1536 requireValidToken: true,
1537 redirect: {
1538 success: null,
1539 failure: null,
1540 },
1541 defaultErrors: ['Something went wrong, please try again.'],
1542 defaultMessages: ['Your token has been successfully refreshed.'],
1543 };
1544 this.token = {
1545 class: NbAuthSimpleToken,
1546 key: 'data.token',
1547 getter: (module, res, options) => getDeepFromObject(res.body, options.token.key),
1548 };
1549 this.errors = {
1550 key: 'data.errors',
1551 getter: (module, res, options) => getDeepFromObject(res.error, options.errors.key, options[module].defaultErrors),
1552 };
1553 this.messages = {
1554 key: 'data.messages',
1555 getter: (module, res, options) => getDeepFromObject(res.body, options.messages.key, options[module].defaultMessages),
1556 };
1557 }
1558}
1559const passwordStrategyOptions = new NbPasswordAuthStrategyOptions();
1560
1561/**
1562 * @license
1563 * Copyright Akveo. All Rights Reserved.
1564 * Licensed under the MIT License. See License.txt in the project root for license information.
1565 */
1566/**
1567 * The most common authentication provider for email/password strategy.
1568 *
1569 * Strategy settings. Note, there is no need to copy over the whole object to change the settings you need.
1570 * Also, this.getOption call won't work outside of the default options declaration
1571 * (which is inside of the `NbPasswordAuthStrategy` class), so you have to replace it with a custom helper function
1572 * if you need it.
1573 *
1574 * ```ts
1575 *export class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions {
1576 * name: string;
1577 * baseEndpoint? = '/api/auth/';
1578 * login?: boolean | NbPasswordStrategyModule = {
1579 * alwaysFail: false,
1580 * endpoint: 'login',
1581 * method: 'post',
1582 * requireValidToken: true,
1583 * redirect: {
1584 * success: '/',
1585 * failure: null,
1586 * },
1587 * defaultErrors: ['Login/Email combination is not correct, please try again.'],
1588 * defaultMessages: ['You have been successfully logged in.'],
1589 * };
1590 * register?: boolean | NbPasswordStrategyModule = {
1591 * alwaysFail: false,
1592 * endpoint: 'register',
1593 * method: 'post',
1594 * requireValidToken: true,
1595 * redirect: {
1596 * success: '/',
1597 * failure: null,
1598 * },
1599 * defaultErrors: ['Something went wrong, please try again.'],
1600 * defaultMessages: ['You have been successfully registered.'],
1601 * };
1602 * requestPass?: boolean | NbPasswordStrategyModule = {
1603 * endpoint: 'request-pass',
1604 * method: 'post',
1605 * redirect: {
1606 * success: '/',
1607 * failure: null,
1608 * },
1609 * defaultErrors: ['Something went wrong, please try again.'],
1610 * defaultMessages: ['Reset password instructions have been sent to your email.'],
1611 * };
1612 * resetPass?: boolean | NbPasswordStrategyReset = {
1613 * endpoint: 'reset-pass',
1614 * method: 'put',
1615 * redirect: {
1616 * success: '/',
1617 * failure: null,
1618 * },
1619 * resetPasswordTokenKey: 'reset_password_token',
1620 * defaultErrors: ['Something went wrong, please try again.'],
1621 * defaultMessages: ['Your password has been successfully changed.'],
1622 * };
1623 * logout?: boolean | NbPasswordStrategyReset = {
1624 * alwaysFail: false,
1625 * endpoint: 'logout',
1626 * method: 'delete',
1627 * redirect: {
1628 * success: '/',
1629 * failure: null,
1630 * },
1631 * defaultErrors: ['Something went wrong, please try again.'],
1632 * defaultMessages: ['You have been successfully logged out.'],
1633 * };
1634 * refreshToken?: boolean | NbPasswordStrategyModule = {
1635 * endpoint: 'refresh-token',
1636 * method: 'post',
1637 * requireValidToken: true,
1638 * redirect: {
1639 * success: null,
1640 * failure: null,
1641 * },
1642 * defaultErrors: ['Something went wrong, please try again.'],
1643 * defaultMessages: ['Your token has been successfully refreshed.'],
1644 * };
1645 * token?: NbPasswordStrategyToken = {
1646 * class: NbAuthSimpleToken,
1647 * key: 'data.token',
1648 * getter: (module: string, res: HttpResponse<Object>, options: NbPasswordAuthStrategyOptions) => getDeepFromObject(
1649 * res.body,
1650 * options.token.key,
1651 * ),
1652 * };
1653 * errors?: NbPasswordStrategyMessage = {
1654 * key: 'data.errors',
1655 * getter: (module: string, res: HttpErrorResponse, options: NbPasswordAuthStrategyOptions) => getDeepFromObject(
1656 * res.error,
1657 * options.errors.key,
1658 * options[module].defaultErrors,
1659 * ),
1660 * };
1661 * messages?: NbPasswordStrategyMessage = {
1662 * key: 'data.messages',
1663 * getter: (module: string, res: HttpResponse<Object>, options: NbPasswordAuthStrategyOptions) => getDeepFromObject(
1664 * res.body,
1665 * options.messages.key,
1666 * options[module].defaultMessages,
1667 * ),
1668 * };
1669 * validation?: {
1670 * password?: {
1671 * required?: boolean;
1672 * minLength?: number | null;
1673 * maxLength?: number | null;
1674 * regexp?: string | null;
1675 * };
1676 * email?: {
1677 * required?: boolean;
1678 * regexp?: string | null;
1679 * };
1680 * fullName?: {
1681 * required?: boolean;
1682 * minLength?: number | null;
1683 * maxLength?: number | null;
1684 * regexp?: string | null;
1685 * };
1686 * };
1687 *}
1688 * ```
1689 */
1690class NbPasswordAuthStrategy extends NbAuthStrategy {
1691 constructor(http, route) {
1692 super();
1693 this.http = http;
1694 this.route = route;
1695 this.defaultOptions = passwordStrategyOptions;
1696 }
1697 static setup(options) {
1698 return [NbPasswordAuthStrategy, options];
1699 }
1700 authenticate(data) {
1701 const module = 'login';
1702 const method = this.getOption(`${module}.method`);
1703 const url = this.getActionEndpoint(module);
1704 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1705 return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => {
1706 if (this.getOption(`${module}.alwaysFail`)) {
1707 throw this.createFailResponse(data);
1708 }
1709 return res;
1710 }), map((res) => {
1711 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')(module, res, this.options), requireValidToken));
1712 }), catchError((res) => {
1713 return this.handleResponseError(res, module);
1714 }));
1715 }
1716 register(data) {
1717 const module = 'register';
1718 const method = this.getOption(`${module}.method`);
1719 const url = this.getActionEndpoint(module);
1720 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1721 return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => {
1722 if (this.getOption(`${module}.alwaysFail`)) {
1723 throw this.createFailResponse(data);
1724 }
1725 return res;
1726 }), map((res) => {
1727 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')('login', res, this.options), requireValidToken));
1728 }), catchError((res) => {
1729 return this.handleResponseError(res, module);
1730 }));
1731 }
1732 requestPassword(data) {
1733 const module = 'requestPass';
1734 const method = this.getOption(`${module}.method`);
1735 const url = this.getActionEndpoint(module);
1736 return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => {
1737 if (this.getOption(`${module}.alwaysFail`)) {
1738 throw this.createFailResponse();
1739 }
1740 return res;
1741 }), map((res) => {
1742 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
1743 }), catchError((res) => {
1744 return this.handleResponseError(res, module);
1745 }));
1746 }
1747 resetPassword(data = {}) {
1748 const module = 'resetPass';
1749 const method = this.getOption(`${module}.method`);
1750 const url = this.getActionEndpoint(module);
1751 const tokenKey = this.getOption(`${module}.resetPasswordTokenKey`);
1752 data[tokenKey] = this.route.snapshot.queryParams[tokenKey];
1753 return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => {
1754 if (this.getOption(`${module}.alwaysFail`)) {
1755 throw this.createFailResponse();
1756 }
1757 return res;
1758 }), map((res) => {
1759 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
1760 }), catchError((res) => {
1761 return this.handleResponseError(res, module);
1762 }));
1763 }
1764 logout() {
1765 const module = 'logout';
1766 const method = this.getOption(`${module}.method`);
1767 const url = this.getActionEndpoint(module);
1768 return of({}).pipe(switchMap((res) => {
1769 if (!url) {
1770 return of(res);
1771 }
1772 return this.http.request(method, url, { observe: 'response', headers: this.getHeaders() });
1773 }), map((res) => {
1774 if (this.getOption(`${module}.alwaysFail`)) {
1775 throw this.createFailResponse();
1776 }
1777 return res;
1778 }), map((res) => {
1779 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
1780 }), catchError((res) => {
1781 return this.handleResponseError(res, module);
1782 }));
1783 }
1784 refreshToken(data) {
1785 const module = 'refreshToken';
1786 const method = this.getOption(`${module}.method`);
1787 const url = this.getActionEndpoint(module);
1788 const requireValidToken = this.getOption(`${module}.requireValidToken`);
1789 return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => {
1790 if (this.getOption(`${module}.alwaysFail`)) {
1791 throw this.createFailResponse(data);
1792 }
1793 return res;
1794 }), map((res) => {
1795 return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')(module, res, this.options), requireValidToken));
1796 }), catchError((res) => {
1797 return this.handleResponseError(res, module);
1798 }));
1799 }
1800 handleResponseError(res, module) {
1801 let errors = [];
1802 if (res instanceof HttpErrorResponse) {
1803 errors = this.getOption('errors.getter')(module, res, this.options);
1804 }
1805 else if (res instanceof NbAuthIllegalTokenError) {
1806 errors.push(res.message);
1807 }
1808 else {
1809 errors.push('Something went wrong.');
1810 }
1811 return of(new NbAuthResult(false, res, this.getOption(`${module}.redirect.failure`), errors));
1812 }
1813}
1814NbPasswordAuthStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy, deps: [{ token: i1.HttpClient }, { token: i2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable });
1815NbPasswordAuthStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy });
1816i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy, decorators: [{
1817 type: Injectable
1818 }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ActivatedRoute }]; } });
1819
1820/**
1821 * @license
1822 * Copyright Akveo. All Rights Reserved.
1823 * Licensed under the MIT License. See License.txt in the project root for license information.
1824 */
1825class NbAuthBlockComponent {
1826}
1827NbAuthBlockComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1828NbAuthBlockComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbAuthBlockComponent, selector: "nb-auth-block", ngImport: i0, template: `
1829 <ng-content></ng-content>
1830 `, isInline: true, styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host{display:block;width:100%;max-width:35rem}:host ::ng-deep form{width:100%}:host ::ng-deep .label{display:block;margin-bottom:.5rem}:host ::ng-deep .forgot-password{text-decoration:none;margin-bottom:.5rem}:host ::ng-deep .caption{margin-top:.5rem}:host ::ng-deep .alert{text-align:center}:host ::ng-deep .title{margin-top:0;margin-bottom:.75rem;text-align:center}:host ::ng-deep .sub-title{margin-bottom:2rem;text-align:center}:host ::ng-deep .form-control-group{margin-bottom:2rem}:host ::ng-deep .form-control-group.accept-group{display:flex;justify-content:space-between;margin:2rem 0}:host ::ng-deep .label-with-link{display:flex;justify-content:space-between}:host ::ng-deep .links{text-align:center;margin-top:1.75rem}:host ::ng-deep .links .socials{margin-top:1.5rem}:host ::ng-deep .links .socials a{margin:0 1rem;text-decoration:none;vertical-align:middle}:host ::ng-deep .links .socials a.with-icon{font-size:2rem}:host ::ng-deep .another-action{margin-top:2rem;text-align:center}:host ::ng-deep .sign-in-or-up{margin-top:2rem;display:flex;justify-content:space-between}:host ::ng-deep nb-alert .alert-title,:host ::ng-deep nb-alert .alert-message{margin:0 0 .5rem}:host ::ng-deep nb-alert .alert-message-list{list-style-type:none;padding:0;margin:0}\n"] });
1831i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthBlockComponent, decorators: [{
1832 type: Component,
1833 args: [{ selector: 'nb-auth-block', template: `
1834 <ng-content></ng-content>
1835 `, styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host{display:block;width:100%;max-width:35rem}:host ::ng-deep form{width:100%}:host ::ng-deep .label{display:block;margin-bottom:.5rem}:host ::ng-deep .forgot-password{text-decoration:none;margin-bottom:.5rem}:host ::ng-deep .caption{margin-top:.5rem}:host ::ng-deep .alert{text-align:center}:host ::ng-deep .title{margin-top:0;margin-bottom:.75rem;text-align:center}:host ::ng-deep .sub-title{margin-bottom:2rem;text-align:center}:host ::ng-deep .form-control-group{margin-bottom:2rem}:host ::ng-deep .form-control-group.accept-group{display:flex;justify-content:space-between;margin:2rem 0}:host ::ng-deep .label-with-link{display:flex;justify-content:space-between}:host ::ng-deep .links{text-align:center;margin-top:1.75rem}:host ::ng-deep .links .socials{margin-top:1.5rem}:host ::ng-deep .links .socials a{margin:0 1rem;text-decoration:none;vertical-align:middle}:host ::ng-deep .links .socials a.with-icon{font-size:2rem}:host ::ng-deep .another-action{margin-top:2rem;text-align:center}:host ::ng-deep .sign-in-or-up{margin-top:2rem;display:flex;justify-content:space-between}:host ::ng-deep nb-alert .alert-title,:host ::ng-deep nb-alert .alert-message{margin:0 0 .5rem}:host ::ng-deep nb-alert .alert-message-list{list-style-type:none;padding:0;margin:0}\n"] }]
1836 }] });
1837
1838/**
1839 * @license
1840 * Copyright Akveo. All Rights Reserved.
1841 * Licensed under the MIT License. See License.txt in the project root for license information.
1842 */
1843class NbAuthComponent {
1844 // showcase of how to use the onAuthenticationChange method
1845 constructor(auth, location) {
1846 this.auth = auth;
1847 this.location = location;
1848 this.destroy$ = new Subject();
1849 this.authenticated = false;
1850 this.token = '';
1851 this.subscription = auth.onAuthenticationChange()
1852 .pipe(takeUntil(this.destroy$))
1853 .subscribe((authenticated) => {
1854 this.authenticated = authenticated;
1855 });
1856 }
1857 back() {
1858 this.location.back();
1859 return false;
1860 }
1861 ngOnDestroy() {
1862 this.destroy$.next();
1863 this.destroy$.complete();
1864 }
1865}
1866NbAuthComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthComponent, deps: [{ token: NbAuthService }, { token: i4.Location }], target: i0.ɵɵFactoryTarget.Component });
1867NbAuthComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbAuthComponent, selector: "nb-auth", ngImport: i0, template: `
1868 <nb-layout>
1869 <nb-layout-column>
1870 <nb-card>
1871 <nb-card-header>
1872 <nav class="navigation">
1873 <a href="#" (click)="back()" class="link back-link" aria-label="Back">
1874 <nb-icon icon="arrow-back"></nb-icon>
1875 </a>
1876 </nav>
1877 </nb-card-header>
1878 <nb-card-body>
1879 <nb-auth-block>
1880 <router-outlet></router-outlet>
1881 </nb-auth-block>
1882 </nb-card-body>
1883 </nb-card>
1884 </nb-layout-column>
1885 </nb-layout>
1886 `, isInline: true, styles: ["/*!\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */.visually-hidden{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.nb-global-scrollblock{position:static;width:auto;overflow:hidden}/*\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *//*!\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}html,body{margin:0;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template,[hidden]{display:none}/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host nb-card{margin:0;height:calc(100vh - 5rem)}:host .navigation .link{display:inline-block;text-decoration:none}:host .navigation .link nb-icon{font-size:2rem;vertical-align:middle}:host .links nb-icon{font-size:2.5rem}:host nb-card-body{display:flex;width:100%}:host nb-auth-block{margin:auto}@media (max-width: 767.98px){:host nb-card{border-radius:0;height:100vh}}:host ::ng-deep nb-layout .layout .layout-container .content .columns nb-layout-column{padding:2.5rem}@media (max-width: 767.98px){:host ::ng-deep nb-layout .layout .layout-container .content .columns nb-layout-column{padding:0}}\n"], components: [{ type: i3.NbLayoutComponent, selector: "nb-layout", inputs: ["center", "windowMode", "withScroll", "restoreScrollTop"] }, { type: i3.NbLayoutColumnComponent, selector: "nb-layout-column", inputs: ["left", "start"] }, { type: i3.NbCardComponent, selector: "nb-card", inputs: ["size", "status", "accent"] }, { type: i3.NbCardHeaderComponent, selector: "nb-card-header" }, { type: i3.NbIconComponent, selector: "nb-icon", inputs: ["icon", "pack", "options", "status", "config"] }, { type: i3.NbCardBodyComponent, selector: "nb-card-body" }, { type: NbAuthBlockComponent, selector: "nb-auth-block" }], directives: [{ type: i2.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
1887i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthComponent, decorators: [{
1888 type: Component,
1889 args: [{ selector: 'nb-auth', template: `
1890 <nb-layout>
1891 <nb-layout-column>
1892 <nb-card>
1893 <nb-card-header>
1894 <nav class="navigation">
1895 <a href="#" (click)="back()" class="link back-link" aria-label="Back">
1896 <nb-icon icon="arrow-back"></nb-icon>
1897 </a>
1898 </nav>
1899 </nb-card-header>
1900 <nb-card-body>
1901 <nb-auth-block>
1902 <router-outlet></router-outlet>
1903 </nb-auth-block>
1904 </nb-card-body>
1905 </nb-card>
1906 </nb-layout-column>
1907 </nb-layout>
1908 `, styles: ["/*!\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */.visually-hidden{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.nb-global-scrollblock{position:static;width:auto;overflow:hidden}/*\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *//*!\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}html,body{margin:0;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template,[hidden]{display:none}/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host nb-card{margin:0;height:calc(100vh - 5rem)}:host .navigation .link{display:inline-block;text-decoration:none}:host .navigation .link nb-icon{font-size:2rem;vertical-align:middle}:host .links nb-icon{font-size:2.5rem}:host nb-card-body{display:flex;width:100%}:host nb-auth-block{margin:auto}@media (max-width: 767.98px){:host nb-card{border-radius:0;height:100vh}}:host ::ng-deep nb-layout .layout .layout-container .content .columns nb-layout-column{padding:2.5rem}@media (max-width: 767.98px){:host ::ng-deep nb-layout .layout .layout-container .content .columns nb-layout-column{padding:0}}\n"] }]
1909 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: i4.Location }]; } });
1910
1911/**
1912 * @license
1913 * Copyright Akveo. All Rights Reserved.
1914 * Licensed under the MIT License. See License.txt in the project root for license information.
1915 */
1916class NbLoginComponent {
1917 constructor(service, options = {}, cd, router) {
1918 this.service = service;
1919 this.options = options;
1920 this.cd = cd;
1921 this.router = router;
1922 this.redirectDelay = 0;
1923 this.showMessages = {};
1924 this.strategy = '';
1925 this.errors = [];
1926 this.messages = [];
1927 this.user = {};
1928 this.submitted = false;
1929 this.socialLinks = [];
1930 this.rememberMe = false;
1931 this.redirectDelay = this.getConfigValue('forms.login.redirectDelay');
1932 this.showMessages = this.getConfigValue('forms.login.showMessages');
1933 this.strategy = this.getConfigValue('forms.login.strategy');
1934 this.socialLinks = this.getConfigValue('forms.login.socialLinks');
1935 this.rememberMe = this.getConfigValue('forms.login.rememberMe');
1936 }
1937 login() {
1938 this.errors = [];
1939 this.messages = [];
1940 this.submitted = true;
1941 this.service.authenticate(this.strategy, this.user).subscribe((result) => {
1942 this.submitted = false;
1943 if (result.isSuccess()) {
1944 this.messages = result.getMessages();
1945 }
1946 else {
1947 this.errors = result.getErrors();
1948 }
1949 const redirect = result.getRedirect();
1950 if (redirect) {
1951 setTimeout(() => {
1952 return this.router.navigateByUrl(redirect);
1953 }, this.redirectDelay);
1954 }
1955 this.cd.detectChanges();
1956 });
1957 }
1958 getConfigValue(key) {
1959 return getDeepFromObject(this.options, key, null);
1960 }
1961}
1962NbLoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbLoginComponent, deps: [{ token: NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i0.ChangeDetectorRef }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
1963NbLoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbLoginComponent, selector: "nb-login", ngImport: i0, template: "<h1 id=\"title\" class=\"title\">Login</h1>\n<p class=\"sub-title\">Hello! Log in with your email.</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"login()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n name=\"email\"\n id=\"input-email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n fieldSize=\"large\"\n autofocus\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <span class=\"label-with-link\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <a class=\"forgot-password caption-2\" routerLink=\"../request-password\">Forgot Password?</a>\n </span>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n name=\"password\"\n type=\"password\"\n id=\"input-password\"\n placeholder=\"Password\"\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched \">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\">\n <nb-checkbox name=\"rememberMe\" [(ngModel)]=\"user.rememberMe\" *ngIf=\"rememberMe\">Remember me</nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Log In\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Register\">\n Don't have an account? <a class=\"text-link\" routerLink=\"../register\">Register</a>\n</section>\n", components: [{ type: i3.NbAlertComponent, selector: "nb-alert", inputs: ["size", "status", "accent", "outline", "closable"], outputs: ["close"] }, { type: i3.NbCheckboxComponent, selector: "nb-checkbox", inputs: ["checked", "disabled", "status", "indeterminate"], outputs: ["checkedChange"] }, { type: i3.NbButtonComponent, selector: "button[nbButton],a[nbButton],input[type=\"button\"][nbButton],input[type=\"submit\"][nbButton]", inputs: ["hero"] }, { type: i3.NbIconComponent, selector: "nb-icon", inputs: ["icon", "pack", "options", "status", "config"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.NbInputDirective, selector: "input[nbInput],textarea[nbInput]", inputs: ["fieldSize", "status", "shape", "fullWidth"] }, { type: i5.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: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i5.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1964i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbLoginComponent, decorators: [{
1965 type: Component,
1966 args: [{ selector: 'nb-login', changeDetection: ChangeDetectionStrategy.OnPush, template: "<h1 id=\"title\" class=\"title\">Login</h1>\n<p class=\"sub-title\">Hello! Log in with your email.</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"login()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n name=\"email\"\n id=\"input-email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n fieldSize=\"large\"\n autofocus\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <span class=\"label-with-link\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <a class=\"forgot-password caption-2\" routerLink=\"../request-password\">Forgot Password?</a>\n </span>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n name=\"password\"\n type=\"password\"\n id=\"input-password\"\n placeholder=\"Password\"\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched \">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\">\n <nb-checkbox name=\"rememberMe\" [(ngModel)]=\"user.rememberMe\" *ngIf=\"rememberMe\">Remember me</nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Log In\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Register\">\n Don't have an account? <a class=\"text-link\" routerLink=\"../register\">Register</a>\n</section>\n" }]
1967 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: undefined, decorators: [{
1968 type: Inject,
1969 args: [NB_AUTH_OPTIONS]
1970 }] }, { type: i0.ChangeDetectorRef }, { type: i2.Router }]; } });
1971
1972/**
1973 * @license
1974 * Copyright Akveo. All Rights Reserved.
1975 * Licensed under the MIT License. See License.txt in the project root for license information.
1976 */
1977class NbRegisterComponent {
1978 constructor(service, options = {}, cd, router) {
1979 this.service = service;
1980 this.options = options;
1981 this.cd = cd;
1982 this.router = router;
1983 this.redirectDelay = 0;
1984 this.showMessages = {};
1985 this.strategy = '';
1986 this.submitted = false;
1987 this.errors = [];
1988 this.messages = [];
1989 this.user = {};
1990 this.socialLinks = [];
1991 this.redirectDelay = this.getConfigValue('forms.register.redirectDelay');
1992 this.showMessages = this.getConfigValue('forms.register.showMessages');
1993 this.strategy = this.getConfigValue('forms.register.strategy');
1994 this.socialLinks = this.getConfigValue('forms.login.socialLinks');
1995 }
1996 register() {
1997 this.errors = this.messages = [];
1998 this.submitted = true;
1999 this.service.register(this.strategy, this.user).subscribe((result) => {
2000 this.submitted = false;
2001 if (result.isSuccess()) {
2002 this.messages = result.getMessages();
2003 }
2004 else {
2005 this.errors = result.getErrors();
2006 }
2007 const redirect = result.getRedirect();
2008 if (redirect) {
2009 setTimeout(() => {
2010 return this.router.navigateByUrl(redirect);
2011 }, this.redirectDelay);
2012 }
2013 this.cd.detectChanges();
2014 });
2015 }
2016 getConfigValue(key) {
2017 return getDeepFromObject(this.options, key, null);
2018 }
2019}
2020NbRegisterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbRegisterComponent, deps: [{ token: NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i0.ChangeDetectorRef }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
2021NbRegisterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbRegisterComponent, selector: "nb-register", ngImport: i0, template: "<h1 id=\"title\" class=\"title\">Register</h1>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"register()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-name\">Full name:</label>\n <input nbInput\n [(ngModel)]=\"user.fullName\"\n #fullName=\"ngModel\"\n id=\"input-name\"\n name=\"fullName\"\n placeholder=\"Full name\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"fullName.dirty ? (fullName.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.fullName.required')\"\n [minlength]=\"getConfigValue('forms.validation.fullName.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.fullName.maxLength')\"\n [attr.aria-invalid]=\"fullName.invalid && fullName.touched ? true : null\">\n <ng-container *ngIf=\"fullName.invalid && fullName.touched\">\n <p class=\"caption status-danger\" *ngIf=\"fullName.errors?.required\">\n Full name is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"fullName.errors?.minlength || fullName.errors?.maxlength\">\n Full name should contains\n from {{getConfigValue('forms.validation.fullName.minLength')}}\n to {{getConfigValue('forms.validation.fullName.maxLength')}}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n id=\"input-email\"\n name=\"email\"\n pattern=\".+@.+..+\"\n placeholder=\"Email address\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <input nbInput\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n type=\"password\"\n id=\"input-password\"\n name=\"password\"\n placeholder=\"Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched\">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-re-password\">Repeat password:</label>\n <input nbInput\n [(ngModel)]=\"user.confirmPassword\"\n #rePass=\"ngModel\"\n type=\"password\"\n id=\"input-re-password\"\n name=\"rePass\"\n placeholder=\"Confirm Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"rePass.dirty ? (rePass.invalid || password.value != rePass.value ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [attr.aria-invalid]=\"rePass.invalid && rePass.touched ? true : null\">\n <ng-container *ngIf=\"rePass.invalid && rePass.touched\">\n <p class=\"caption status-danger\" *ngIf=\"rePass.errors?.required\">\n Password confirmation is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.value != rePass.value && !rePass.errors?.required\">\n Password does not match the confirm password.\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\" *ngIf=\"getConfigValue('forms.register.terms')\">\n <nb-checkbox name=\"terms\" [(ngModel)]=\"user.terms\" [required]=\"getConfigValue('forms.register.terms')\">\n Agree to <a href=\"#\" target=\"_blank\"><strong>Terms & Conditions</strong></a>\n </nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Register\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Sign in\">\n Already have an account? <a class=\"text-link\" routerLink=\"../login\">Log in</a>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .title{margin-bottom:2rem}\n"], components: [{ type: i3.NbAlertComponent, selector: "nb-alert", inputs: ["size", "status", "accent", "outline", "closable"], outputs: ["close"] }, { type: i3.NbCheckboxComponent, selector: "nb-checkbox", inputs: ["checked", "disabled", "status", "indeterminate"], outputs: ["checkedChange"] }, { type: i3.NbButtonComponent, selector: "button[nbButton],a[nbButton],input[type=\"button\"][nbButton],input[type=\"submit\"][nbButton]", inputs: ["hero"] }, { type: i3.NbIconComponent, selector: "nb-icon", inputs: ["icon", "pack", "options", "status", "config"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.NbInputDirective, selector: "input[nbInput],textarea[nbInput]", inputs: ["fieldSize", "status", "shape", "fullWidth"] }, { type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i5.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2022i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbRegisterComponent, decorators: [{
2023 type: Component,
2024 args: [{ selector: 'nb-register', changeDetection: ChangeDetectionStrategy.OnPush, template: "<h1 id=\"title\" class=\"title\">Register</h1>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"register()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-name\">Full name:</label>\n <input nbInput\n [(ngModel)]=\"user.fullName\"\n #fullName=\"ngModel\"\n id=\"input-name\"\n name=\"fullName\"\n placeholder=\"Full name\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"fullName.dirty ? (fullName.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.fullName.required')\"\n [minlength]=\"getConfigValue('forms.validation.fullName.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.fullName.maxLength')\"\n [attr.aria-invalid]=\"fullName.invalid && fullName.touched ? true : null\">\n <ng-container *ngIf=\"fullName.invalid && fullName.touched\">\n <p class=\"caption status-danger\" *ngIf=\"fullName.errors?.required\">\n Full name is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"fullName.errors?.minlength || fullName.errors?.maxlength\">\n Full name should contains\n from {{getConfigValue('forms.validation.fullName.minLength')}}\n to {{getConfigValue('forms.validation.fullName.maxLength')}}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n id=\"input-email\"\n name=\"email\"\n pattern=\".+@.+..+\"\n placeholder=\"Email address\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <input nbInput\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n type=\"password\"\n id=\"input-password\"\n name=\"password\"\n placeholder=\"Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched\">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-re-password\">Repeat password:</label>\n <input nbInput\n [(ngModel)]=\"user.confirmPassword\"\n #rePass=\"ngModel\"\n type=\"password\"\n id=\"input-re-password\"\n name=\"rePass\"\n placeholder=\"Confirm Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"rePass.dirty ? (rePass.invalid || password.value != rePass.value ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [attr.aria-invalid]=\"rePass.invalid && rePass.touched ? true : null\">\n <ng-container *ngIf=\"rePass.invalid && rePass.touched\">\n <p class=\"caption status-danger\" *ngIf=\"rePass.errors?.required\">\n Password confirmation is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.value != rePass.value && !rePass.errors?.required\">\n Password does not match the confirm password.\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\" *ngIf=\"getConfigValue('forms.register.terms')\">\n <nb-checkbox name=\"terms\" [(ngModel)]=\"user.terms\" [required]=\"getConfigValue('forms.register.terms')\">\n Agree to <a href=\"#\" target=\"_blank\"><strong>Terms & Conditions</strong></a>\n </nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Register\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Sign in\">\n Already have an account? <a class=\"text-link\" routerLink=\"../login\">Log in</a>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .title{margin-bottom:2rem}\n"] }]
2025 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: undefined, decorators: [{
2026 type: Inject,
2027 args: [NB_AUTH_OPTIONS]
2028 }] }, { type: i0.ChangeDetectorRef }, { type: i2.Router }]; } });
2029
2030/**
2031 * @license
2032 * Copyright Akveo. All Rights Reserved.
2033 * Licensed under the MIT License. See License.txt in the project root for license information.
2034 */
2035class NbLogoutComponent {
2036 constructor(service, options = {}, router) {
2037 this.service = service;
2038 this.options = options;
2039 this.router = router;
2040 this.redirectDelay = 0;
2041 this.strategy = '';
2042 this.redirectDelay = this.getConfigValue('forms.logout.redirectDelay');
2043 this.strategy = this.getConfigValue('forms.logout.strategy');
2044 }
2045 ngOnInit() {
2046 this.logout(this.strategy);
2047 }
2048 logout(strategy) {
2049 this.service.logout(strategy).subscribe((result) => {
2050 const redirect = result.getRedirect();
2051 if (redirect) {
2052 setTimeout(() => {
2053 return this.router.navigateByUrl(redirect);
2054 }, this.redirectDelay);
2055 }
2056 });
2057 }
2058 getConfigValue(key) {
2059 return getDeepFromObject(this.options, key, null);
2060 }
2061}
2062NbLogoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbLogoutComponent, deps: [{ token: NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
2063NbLogoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbLogoutComponent, selector: "nb-logout", ngImport: i0, template: "<div>Logging out, please wait...</div>\n" });
2064i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbLogoutComponent, decorators: [{
2065 type: Component,
2066 args: [{ selector: 'nb-logout', template: "<div>Logging out, please wait...</div>\n" }]
2067 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: undefined, decorators: [{
2068 type: Inject,
2069 args: [NB_AUTH_OPTIONS]
2070 }] }, { type: i2.Router }]; } });
2071
2072/**
2073 * @license
2074 * Copyright Akveo. All Rights Reserved.
2075 * Licensed under the MIT License. See License.txt in the project root for license information.
2076 */
2077class NbRequestPasswordComponent {
2078 constructor(service, options = {}, cd, router) {
2079 this.service = service;
2080 this.options = options;
2081 this.cd = cd;
2082 this.router = router;
2083 this.redirectDelay = 0;
2084 this.showMessages = {};
2085 this.strategy = '';
2086 this.submitted = false;
2087 this.errors = [];
2088 this.messages = [];
2089 this.user = {};
2090 this.redirectDelay = this.getConfigValue('forms.requestPassword.redirectDelay');
2091 this.showMessages = this.getConfigValue('forms.requestPassword.showMessages');
2092 this.strategy = this.getConfigValue('forms.requestPassword.strategy');
2093 }
2094 requestPass() {
2095 this.errors = this.messages = [];
2096 this.submitted = true;
2097 this.service.requestPassword(this.strategy, this.user).subscribe((result) => {
2098 this.submitted = false;
2099 if (result.isSuccess()) {
2100 this.messages = result.getMessages();
2101 }
2102 else {
2103 this.errors = result.getErrors();
2104 }
2105 const redirect = result.getRedirect();
2106 if (redirect) {
2107 setTimeout(() => {
2108 return this.router.navigateByUrl(redirect);
2109 }, this.redirectDelay);
2110 }
2111 this.cd.detectChanges();
2112 });
2113 }
2114 getConfigValue(key) {
2115 return getDeepFromObject(this.options, key, null);
2116 }
2117}
2118NbRequestPasswordComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbRequestPasswordComponent, deps: [{ token: NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i0.ChangeDetectorRef }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
2119NbRequestPasswordComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbRequestPasswordComponent, selector: "nb-request-password-page", ngImport: i0, template: "<h1 id=\"title\" class=\"title\">Forgot Password</h1>\n<p class=\"sub-title\">Enter your email address and we\u2019ll send a link to reset your password</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"requestPass()\" #requestPassForm=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Enter your email address:</label>\n <input nbInput\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n id=\"input-email\"\n name=\"email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !requestPassForm.valid\"\n [class.btn-pulse]=\"submitted\">\n Request password\n </button>\n</form>\n\n<section class=\"sign-in-or-up\" aria-label=\"Sign in or sign up\">\n <p><a class=\"text-link\" routerLink=\"../login\">Back to Log In</a></p>\n <p><a routerLink=\"../register\" class=\"text-link\">Register</a></p>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .form-group:last-of-type{margin-bottom:3rem}\n"], components: [{ type: i3.NbAlertComponent, selector: "nb-alert", inputs: ["size", "status", "accent", "outline", "closable"], outputs: ["close"] }, { type: i3.NbButtonComponent, selector: "button[nbButton],a[nbButton],input[type=\"button\"][nbButton],input[type=\"submit\"][nbButton]", inputs: ["hero"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.NbInputDirective, selector: "input[nbInput],textarea[nbInput]", inputs: ["fieldSize", "status", "shape", "fullWidth"] }, { type: i5.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: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2120i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbRequestPasswordComponent, decorators: [{
2121 type: Component,
2122 args: [{ selector: 'nb-request-password-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<h1 id=\"title\" class=\"title\">Forgot Password</h1>\n<p class=\"sub-title\">Enter your email address and we\u2019ll send a link to reset your password</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"requestPass()\" #requestPassForm=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Enter your email address:</label>\n <input nbInput\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n id=\"input-email\"\n name=\"email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !requestPassForm.valid\"\n [class.btn-pulse]=\"submitted\">\n Request password\n </button>\n</form>\n\n<section class=\"sign-in-or-up\" aria-label=\"Sign in or sign up\">\n <p><a class=\"text-link\" routerLink=\"../login\">Back to Log In</a></p>\n <p><a routerLink=\"../register\" class=\"text-link\">Register</a></p>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .form-group:last-of-type{margin-bottom:3rem}\n"] }]
2123 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: undefined, decorators: [{
2124 type: Inject,
2125 args: [NB_AUTH_OPTIONS]
2126 }] }, { type: i0.ChangeDetectorRef }, { type: i2.Router }]; } });
2127
2128/**
2129 * @license
2130 * Copyright Akveo. All Rights Reserved.
2131 * Licensed under the MIT License. See License.txt in the project root for license information.
2132 */
2133class NbResetPasswordComponent {
2134 constructor(service, options = {}, cd, router) {
2135 this.service = service;
2136 this.options = options;
2137 this.cd = cd;
2138 this.router = router;
2139 this.redirectDelay = 0;
2140 this.showMessages = {};
2141 this.strategy = '';
2142 this.submitted = false;
2143 this.errors = [];
2144 this.messages = [];
2145 this.user = {};
2146 this.redirectDelay = this.getConfigValue('forms.resetPassword.redirectDelay');
2147 this.showMessages = this.getConfigValue('forms.resetPassword.showMessages');
2148 this.strategy = this.getConfigValue('forms.resetPassword.strategy');
2149 }
2150 resetPass() {
2151 this.errors = this.messages = [];
2152 this.submitted = true;
2153 this.service.resetPassword(this.strategy, this.user).subscribe((result) => {
2154 this.submitted = false;
2155 if (result.isSuccess()) {
2156 this.messages = result.getMessages();
2157 }
2158 else {
2159 this.errors = result.getErrors();
2160 }
2161 const redirect = result.getRedirect();
2162 if (redirect) {
2163 setTimeout(() => {
2164 return this.router.navigateByUrl(redirect);
2165 }, this.redirectDelay);
2166 }
2167 this.cd.detectChanges();
2168 });
2169 }
2170 getConfigValue(key) {
2171 return getDeepFromObject(this.options, key, null);
2172 }
2173}
2174NbResetPasswordComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbResetPasswordComponent, deps: [{ token: NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i0.ChangeDetectorRef }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
2175NbResetPasswordComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.0", type: NbResetPasswordComponent, selector: "nb-reset-password-page", ngImport: i0, template: "<h1 id=\"title\" class=\"title\">Change password</h1>\n<p class=\"sub-title\">Please set a new password</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"resetPass()\" #resetPassForm=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-password\">New Password:</label>\n <input nbInput\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n type=\"password\"\n id=\"input-password\"\n name=\"password\"\n class=\"first\"\n placeholder=\"New Password\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched\">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contains\n from {{getConfigValue('forms.validation.password.minLength')}}\n to {{getConfigValue('forms.validation.password.maxLength')}}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-group\">\n <label class=\"label\" for=\"input-re-password\">Confirm Password:</label>\n <input nbInput\n [(ngModel)]=\"user.confirmPassword\"\n #rePass=\"ngModel\"\n id=\"input-re-password\"\n name=\"rePass\"\n type=\"password\"\n class=\"last\"\n placeholder=\"Confirm Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"rePass.touched\n ? (rePass.invalid || password.value != rePass.value ? 'danger' : 'success')\n : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [attr.aria-invalid]=\"rePass.invalid && rePass.touched ? true : null\">\n <ng-container *ngIf=\"rePass.touched\">\n <p class=\"caption status-danger\" *ngIf=\"rePass.invalid && rePass.errors?.required\">\n Password confirmation is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.value != rePass.value && !rePass.errors?.required\">\n Password does not match the confirm password.\n </p>\n </ng-container>\n </div>\n\n <button nbButton\n status=\"primary\"\n fullWidth\n size=\"large\"\n [disabled]=\"submitted || !resetPassForm.valid\"\n [class.btn-pulse]=\"submitted\">\n Change password\n </button>\n</form>\n\n<section class=\"sign-in-or-up\" aria-label=\"Sign in or sign up\">\n <p><a class=\"text-link\" routerLink=\"../login\">Back to Log In</a></p>\n <p><a class=\"text-link\" routerLink=\"../register\">Register</a></p>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .form-group:last-of-type{margin-bottom:3rem}\n"], components: [{ type: i3.NbAlertComponent, selector: "nb-alert", inputs: ["size", "status", "accent", "outline", "closable"], outputs: ["close"] }, { type: i3.NbButtonComponent, selector: "button[nbButton],a[nbButton],input[type=\"button\"][nbButton],input[type=\"submit\"][nbButton]", inputs: ["hero"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.NbInputDirective, selector: "input[nbInput],textarea[nbInput]", inputs: ["fieldSize", "status", "shape", "fullWidth"] }, { type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i5.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2176i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbResetPasswordComponent, decorators: [{
2177 type: Component,
2178 args: [{ selector: 'nb-reset-password-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<h1 id=\"title\" class=\"title\">Change password</h1>\n<p class=\"sub-title\">Please set a new password</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"resetPass()\" #resetPassForm=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-password\">New Password:</label>\n <input nbInput\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n type=\"password\"\n id=\"input-password\"\n name=\"password\"\n class=\"first\"\n placeholder=\"New Password\"\n autofocus\n fullWidth\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched\">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contains\n from {{getConfigValue('forms.validation.password.minLength')}}\n to {{getConfigValue('forms.validation.password.maxLength')}}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-group\">\n <label class=\"label\" for=\"input-re-password\">Confirm Password:</label>\n <input nbInput\n [(ngModel)]=\"user.confirmPassword\"\n #rePass=\"ngModel\"\n id=\"input-re-password\"\n name=\"rePass\"\n type=\"password\"\n class=\"last\"\n placeholder=\"Confirm Password\"\n fullWidth\n fieldSize=\"large\"\n [status]=\"rePass.touched\n ? (rePass.invalid || password.value != rePass.value ? 'danger' : 'success')\n : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [attr.aria-invalid]=\"rePass.invalid && rePass.touched ? true : null\">\n <ng-container *ngIf=\"rePass.touched\">\n <p class=\"caption status-danger\" *ngIf=\"rePass.invalid && rePass.errors?.required\">\n Password confirmation is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.value != rePass.value && !rePass.errors?.required\">\n Password does not match the confirm password.\n </p>\n </ng-container>\n </div>\n\n <button nbButton\n status=\"primary\"\n fullWidth\n size=\"large\"\n [disabled]=\"submitted || !resetPassForm.valid\"\n [class.btn-pulse]=\"submitted\">\n Change password\n </button>\n</form>\n\n<section class=\"sign-in-or-up\" aria-label=\"Sign in or sign up\">\n <p><a class=\"text-link\" routerLink=\"../login\">Back to Log In</a></p>\n <p><a class=\"text-link\" routerLink=\"../register\">Register</a></p>\n</section>\n", styles: ["/**\n * @license\n * Copyright Akveo. All Rights Reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n */:host .form-group:last-of-type{margin-bottom:3rem}\n"] }]
2179 }], ctorParameters: function () { return [{ type: NbAuthService }, { type: undefined, decorators: [{
2180 type: Inject,
2181 args: [NB_AUTH_OPTIONS]
2182 }] }, { type: i0.ChangeDetectorRef }, { type: i2.Router }]; } });
2183
2184function nbStrategiesFactory(options, injector) {
2185 const strategies = [];
2186 options.strategies
2187 .forEach(([strategyClass, strategyOptions]) => {
2188 const strategy = injector.get(strategyClass);
2189 strategy.setOptions(strategyOptions);
2190 strategies.push(strategy);
2191 });
2192 return strategies;
2193}
2194function nbTokensFactory(strategies) {
2195 const tokens = [];
2196 strategies
2197 .forEach((strategy) => {
2198 tokens.push(strategy.getOption('token.class'));
2199 });
2200 return tokens;
2201}
2202function nbOptionsFactory(options) {
2203 return deepExtend(defaultAuthOptions, options);
2204}
2205function nbNoOpInterceptorFilter(req) {
2206 return true;
2207}
2208class NbAuthModule {
2209 static forRoot(nbAuthOptions) {
2210 return {
2211 ngModule: NbAuthModule,
2212 providers: [
2213 { provide: NB_AUTH_USER_OPTIONS, useValue: nbAuthOptions },
2214 { provide: NB_AUTH_OPTIONS, useFactory: nbOptionsFactory, deps: [NB_AUTH_USER_OPTIONS] },
2215 { provide: NB_AUTH_STRATEGIES, useFactory: nbStrategiesFactory, deps: [NB_AUTH_OPTIONS, Injector] },
2216 { provide: NB_AUTH_TOKENS, useFactory: nbTokensFactory, deps: [NB_AUTH_STRATEGIES] },
2217 { provide: NB_AUTH_FALLBACK_TOKEN, useValue: NbAuthSimpleToken },
2218 { provide: NB_AUTH_INTERCEPTOR_HEADER, useValue: 'Authorization' },
2219 { provide: NB_AUTH_TOKEN_INTERCEPTOR_FILTER, useValue: nbNoOpInterceptorFilter },
2220 { provide: NbTokenStorage, useClass: NbTokenLocalStorage },
2221 NbAuthTokenParceler,
2222 NbAuthService,
2223 NbTokenService,
2224 NbDummyAuthStrategy,
2225 NbPasswordAuthStrategy,
2226 NbOAuth2AuthStrategy,
2227 ],
2228 };
2229 }
2230}
2231NbAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2232NbAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthModule, declarations: [NbAuthComponent,
2233 NbAuthBlockComponent,
2234 NbLoginComponent,
2235 NbRegisterComponent,
2236 NbRequestPasswordComponent,
2237 NbResetPasswordComponent,
2238 NbLogoutComponent], imports: [CommonModule,
2239 NbLayoutModule,
2240 NbCardModule,
2241 NbCheckboxModule,
2242 NbAlertModule,
2243 NbInputModule,
2244 NbButtonModule,
2245 RouterModule,
2246 FormsModule,
2247 NbIconModule], exports: [NbAuthComponent,
2248 NbAuthBlockComponent,
2249 NbLoginComponent,
2250 NbRegisterComponent,
2251 NbRequestPasswordComponent,
2252 NbResetPasswordComponent,
2253 NbLogoutComponent] });
2254NbAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthModule, imports: [[
2255 CommonModule,
2256 NbLayoutModule,
2257 NbCardModule,
2258 NbCheckboxModule,
2259 NbAlertModule,
2260 NbInputModule,
2261 NbButtonModule,
2262 RouterModule,
2263 FormsModule,
2264 NbIconModule,
2265 ]] });
2266i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthModule, decorators: [{
2267 type: NgModule,
2268 args: [{
2269 imports: [
2270 CommonModule,
2271 NbLayoutModule,
2272 NbCardModule,
2273 NbCheckboxModule,
2274 NbAlertModule,
2275 NbInputModule,
2276 NbButtonModule,
2277 RouterModule,
2278 FormsModule,
2279 NbIconModule,
2280 ],
2281 declarations: [
2282 NbAuthComponent,
2283 NbAuthBlockComponent,
2284 NbLoginComponent,
2285 NbRegisterComponent,
2286 NbRequestPasswordComponent,
2287 NbResetPasswordComponent,
2288 NbLogoutComponent,
2289 ],
2290 exports: [
2291 NbAuthComponent,
2292 NbAuthBlockComponent,
2293 NbLoginComponent,
2294 NbRegisterComponent,
2295 NbRequestPasswordComponent,
2296 NbResetPasswordComponent,
2297 NbLogoutComponent,
2298 ],
2299 }]
2300 }] });
2301
2302const routes = [
2303 {
2304 path: 'auth',
2305 component: NbAuthComponent,
2306 children: [
2307 {
2308 path: '',
2309 component: NbLoginComponent,
2310 },
2311 {
2312 path: 'login',
2313 component: NbLoginComponent,
2314 },
2315 {
2316 path: 'register',
2317 component: NbRegisterComponent,
2318 },
2319 {
2320 path: 'logout',
2321 component: NbLogoutComponent,
2322 },
2323 {
2324 path: 'request-password',
2325 component: NbRequestPasswordComponent,
2326 },
2327 {
2328 path: 'reset-password',
2329 component: NbResetPasswordComponent,
2330 },
2331 ],
2332 },
2333];
2334
2335class NbAuthJWTInterceptor {
2336 constructor(injector, filter) {
2337 this.injector = injector;
2338 this.filter = filter;
2339 }
2340 intercept(req, next) {
2341 // do not intercept request whose urls are filtered by the injected filter
2342 if (!this.filter(req)) {
2343 return this.authService.isAuthenticatedOrRefresh()
2344 .pipe(switchMap(authenticated => {
2345 if (authenticated) {
2346 return this.authService.getToken().pipe(switchMap((token) => {
2347 const JWT = `Bearer ${token.getValue()}`;
2348 req = req.clone({
2349 setHeaders: {
2350 Authorization: JWT,
2351 },
2352 });
2353 return next.handle(req);
2354 }));
2355 }
2356 else {
2357 // Request is sent to server without authentication so that the client code
2358 // receives the 401/403 error and can act as desired ('session expired', redirect to login, aso)
2359 return next.handle(req);
2360 }
2361 }));
2362 }
2363 else {
2364 return next.handle(req);
2365 }
2366 }
2367 get authService() {
2368 return this.injector.get(NbAuthService);
2369 }
2370}
2371NbAuthJWTInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthJWTInterceptor, deps: [{ token: i0.Injector }, { token: NB_AUTH_TOKEN_INTERCEPTOR_FILTER }], target: i0.ɵɵFactoryTarget.Injectable });
2372NbAuthJWTInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthJWTInterceptor });
2373i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthJWTInterceptor, decorators: [{
2374 type: Injectable
2375 }], ctorParameters: function () { return [{ type: i0.Injector }, { type: undefined, decorators: [{
2376 type: Inject,
2377 args: [NB_AUTH_TOKEN_INTERCEPTOR_FILTER]
2378 }] }]; } });
2379
2380class NbAuthSimpleInterceptor {
2381 constructor(injector, headerName = 'Authorization') {
2382 this.injector = injector;
2383 this.headerName = headerName;
2384 }
2385 intercept(req, next) {
2386 return this.authService.getToken().pipe(switchMap((token) => {
2387 if (token && token.getValue()) {
2388 req = req.clone({
2389 setHeaders: {
2390 [this.headerName]: token.getValue(),
2391 },
2392 });
2393 }
2394 return next.handle(req);
2395 }));
2396 }
2397 get authService() {
2398 return this.injector.get(NbAuthService);
2399 }
2400}
2401NbAuthSimpleInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthSimpleInterceptor, deps: [{ token: i0.Injector }, { token: NB_AUTH_INTERCEPTOR_HEADER }], target: i0.ɵɵFactoryTarget.Injectable });
2402NbAuthSimpleInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthSimpleInterceptor });
2403i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbAuthSimpleInterceptor, decorators: [{
2404 type: Injectable
2405 }], ctorParameters: function () { return [{ type: i0.Injector }, { type: undefined, decorators: [{
2406 type: Inject,
2407 args: [NB_AUTH_INTERCEPTOR_HEADER]
2408 }] }]; } });
2409
2410class NbUser {
2411 constructor(id, email, password, rememberMe, terms, confirmPassword, fullName) {
2412 this.id = id;
2413 this.email = email;
2414 this.password = password;
2415 this.rememberMe = rememberMe;
2416 this.terms = terms;
2417 this.confirmPassword = confirmPassword;
2418 this.fullName = fullName;
2419 }
2420}
2421
2422/**
2423 * @license
2424 * Copyright Akveo. All Rights Reserved.
2425 * Licensed under the MIT License. See License.txt in the project root for license information.
2426 */
2427
2428/**
2429 * Generated bundle index. Do not edit.
2430 */
2431
2432export { NB_AUTH_FALLBACK_TOKEN, NB_AUTH_INTERCEPTOR_HEADER, NB_AUTH_OPTIONS, NB_AUTH_STRATEGIES, NB_AUTH_TOKENS, NB_AUTH_TOKEN_INTERCEPTOR_FILTER, NB_AUTH_USER_OPTIONS, NbAuthBlockComponent, NbAuthComponent, NbAuthEmptyTokenError, NbAuthIllegalJWTTokenError, NbAuthIllegalTokenError, NbAuthJWTInterceptor, NbAuthJWTToken, NbAuthModule, NbAuthOAuth2JWTToken, NbAuthOAuth2Token, NbAuthResult, NbAuthService, NbAuthSimpleInterceptor, NbAuthSimpleToken, NbAuthStrategy, NbAuthStrategyOptions, NbAuthToken, NbAuthTokenNotFoundError, NbAuthTokenParceler, NbDummyAuthStrategy, NbDummyAuthStrategyOptions, NbLoginComponent, NbLogoutComponent, NbOAuth2AuthStrategy, NbOAuth2AuthStrategyOptions, NbOAuth2ClientAuthMethod, NbOAuth2GrantType, NbOAuth2ResponseType, NbPasswordAuthStrategy, NbPasswordAuthStrategyOptions, NbRegisterComponent, NbRequestPasswordComponent, NbResetPasswordComponent, NbTokenLocalStorage, NbTokenService, NbTokenStorage, NbUser, auth2StrategyOptions, b64DecodeUnicode, b64decode, decodeJwtPayload, deepExtend, defaultAuthOptions, dummyStrategyOptions, getDeepFromObject, nbAuthCreateToken, nbNoOpInterceptorFilter, nbOptionsFactory, nbStrategiesFactory, nbTokensFactory, passwordStrategyOptions, routes, urlBase64Decode };