diff --git a/src/framework/auth/strategies/password/password-strategy-options.ts b/src/framework/auth/strategies/password/password-strategy-options.ts index ef72027305..45c97b9eba 100644 --- a/src/framework/auth/strategies/password/password-strategy-options.ts +++ b/src/framework/auth/strategies/password/password-strategy-options.ts @@ -18,6 +18,7 @@ export interface NbPasswordStrategyModule { success?: string | null; failure?: string | null; }; + failWhenNoToken?: boolean, defaultErrors?: string[]; defaultMessages?: string[]; } @@ -42,9 +43,9 @@ export class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions { baseEndpoint? = '/api/auth/'; login?: boolean | NbPasswordStrategyModule = { alwaysFail: false, - rememberMe: true, // TODO: what does that mean? endpoint: 'login', method: 'post', + failWhenNoToken: true, redirect: { success: '/', failure: null, @@ -57,6 +58,7 @@ export class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions { rememberMe: true, endpoint: 'register', method: 'post', + failWhenNoToken: true, redirect: { success: '/', failure: null, @@ -99,6 +101,7 @@ export class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions { refreshToken?: boolean | NbPasswordStrategyModule = { endpoint: 'refresh-token', method: 'post', + failWhenNoToken: true, redirect: { success: null, failure: null, diff --git a/src/framework/auth/strategies/password/password-strategy.spec.ts b/src/framework/auth/strategies/password/password-strategy.spec.ts index 6ef7afa738..c846462047 100644 --- a/src/framework/auth/strategies/password/password-strategy.spec.ts +++ b/src/framework/auth/strategies/password/password-strategy.spec.ts @@ -1416,4 +1416,127 @@ describe('password-auth-strategy', () => { }); + describe('custom failWhenNoToken', () => { + + it('authenticate fail as no token', (done: DoneFn) => { + strategy.authenticate(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(true); + expect(result.isSuccess()).toBe(false); + expect(result.getMessages()).toEqual([]); + expect(result.getErrors()[0]).toEqual('Something went wrong.'); + expect(result.getResponse()).toEqual(new Error('Could not extract token from the response.')); + + done(); + }); + + httpMock.expectOne('/api/auth/login') + .flush({}); + }); + + it('authenticate does not fail even when no token', (done: DoneFn) => { + + strategy.setOptions({ + login: { + failWhenNoToken: false, + }, + }); + + strategy.authenticate(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(false); + expect(result.isSuccess()).toBe(true); + expect(result.getMessages()[0]).toEqual('You have been successfully logged in.'); + expect(result.getErrors()).toEqual([]); + + done(); + }); + + httpMock.expectOne('/api/auth/login') + .flush({}); + }); + + it('register fail as no token', (done: DoneFn) => { + strategy.register(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(true); + expect(result.isSuccess()).toBe(false); + expect(result.getMessages()).toEqual([]); + expect(result.getErrors()[0]).toEqual('Something went wrong.'); + expect(result.getResponse()).toEqual(new Error('Could not extract token from the response.')); + + done(); + }); + + httpMock.expectOne('/api/auth/register') + .flush({}); + }); + + it('register does not fail even when no token', (done: DoneFn) => { + + strategy.setOptions({ + register: { + failWhenNoToken: false, + }, + }); + + strategy.register(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(false); + expect(result.isSuccess()).toBe(true); + expect(result.getMessages()[0]).toEqual('You have been successfully registered.'); + expect(result.getErrors()).toEqual([]); + + done(); + }); + + httpMock.expectOne('/api/auth/register') + .flush({}); + }); + + it('refreshToken fail as no token', (done: DoneFn) => { + strategy.refreshToken(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(true); + expect(result.isSuccess()).toBe(false); + expect(result.getMessages()).toEqual([]); + expect(result.getErrors()[0]).toEqual('Something went wrong.'); + expect(result.getResponse()).toEqual(new Error('Could not extract token from the response.')); + + done(); + }); + + httpMock.expectOne('/api/auth/refresh-token') + .flush({}); + }); + + it('refreshToken does not fail even when no token', (done: DoneFn) => { + + strategy.setOptions({ + refreshToken: { + failWhenNoToken: false, + }, + }); + + strategy.refreshToken(loginData) + .subscribe((result: NbAuthResult) => { + expect(result).toBeTruthy(); + expect(result.isFailure()).toBe(false); + expect(result.isSuccess()).toBe(true); + expect(result.getMessages()[0]).toEqual('Your token has been successfully refreshed.'); + expect(result.getErrors()).toEqual([]); + + done(); + }); + + httpMock.expectOne('/api/auth/refresh-token') + .flush({}); + }); + }); + }); diff --git a/src/framework/auth/strategies/password/password-strategy.ts b/src/framework/auth/strategies/password/password-strategy.ts index 394278c9c9..63bc2626c6 100644 --- a/src/framework/auth/strategies/password/password-strategy.ts +++ b/src/framework/auth/strategies/password/password-strategy.ts @@ -28,9 +28,9 @@ import { NbPasswordAuthStrategyOptions, passwordStrategyOptions } from './passwo * baseEndpoint? = '/api/auth/'; * login?: boolean | NbPasswordStrategyModule = { * alwaysFail: false, - * rememberMe: true, // TODO: what does that mean? * endpoint: 'login', * method: 'post', + * failWhenNoToken: true, * redirect: { * success: '/', * failure: null, @@ -43,6 +43,7 @@ import { NbPasswordAuthStrategyOptions, passwordStrategyOptions } from './passwo * rememberMe: true, * endpoint: 'register', * method: 'post', + * failWhenNoToken: true, * redirect: { * success: '/', * failure: null, @@ -85,6 +86,7 @@ import { NbPasswordAuthStrategyOptions, passwordStrategyOptions } from './passwo * refreshToken?: boolean | NbPasswordStrategyModule = { * endpoint: 'refresh-token', * method: 'post', + * failWhenNoToken: true, * redirect: { * success: null, * failure: null, @@ -403,14 +405,12 @@ export class NbPasswordAuthStrategy extends NbAuthStrategy { ); } - // TODO: this should be optional - // TODO: we can add token.noTokenFailure = true|false - protected validateToken (module: string): any { + protected validateToken(module: string): any { return map((res) => { const token = this.getOption('token.getter')(module, res, this.options); - if (!token) { + if (!token && this.getOption(`${module}.failWhenNoToken`)) { const key = this.getOption('token.key'); - console.warn(`NbEmailPassAuthProvider: + console.warn(`NbPasswordAuthStrategy: Token is not provided under '${key}' key with getter '${this.getOption('token.getter')}', check your auth configuration.`);