diff --git a/packages/okta-angular/src/okta/services/okta.service.ts b/packages/okta-angular/src/okta/services/okta.service.ts index 903c6a5a1..858df856e 100644 --- a/packages/okta-angular/src/okta/services/okta.service.ts +++ b/packages/okta-angular/src/okta/services/okta.service.ts @@ -88,16 +88,30 @@ export class OktaAuthService { * Returns the current accessToken in the tokenManager. */ async getAccessToken(): Promise { - const accessToken = await this.oktaAuth.tokenManager.get('accessToken'); - return accessToken ? accessToken.accessToken : undefined; + try { + const accessToken = await this.oktaAuth.tokenManager.get('accessToken'); + return accessToken.accessToken; + } catch (err) { + // The user no longer has an existing SSO session in the browser. + // (OIDC error `login_required`) + // Ask the user to authenticate again. + return undefined; + } } /** * Returns the current idToken in the tokenManager. */ async getIdToken(): Promise { - const idToken = await this.oktaAuth.tokenManager.get('idToken'); - return idToken ? idToken.idToken : undefined; + try { + const idToken = await this.oktaAuth.tokenManager.get('idToken'); + return idToken.idToken; + } catch (err) { + // The user no longer has an existing SSO session in the browser. + // (OIDC error `login_required`) + // Ask the user to authenticate again. + return undefined; + } } /** diff --git a/packages/okta-angular/test/e2e/harness/src/app/app.component.spec.ts b/packages/okta-angular/test/e2e/harness/src/app/app.component.spec.ts index c025bc4eb..530130011 100644 --- a/packages/okta-angular/test/e2e/harness/src/app/app.component.spec.ts +++ b/packages/okta-angular/test/e2e/harness/src/app/app.component.spec.ts @@ -10,6 +10,29 @@ import { OktaLoginRedirectComponent } from '@okta/okta-angular'; +const mockAccessToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXIiOj' + + 'EsImp0aSI6IkFULnJ2Ym5TNGlXdTJhRE5jYTNid1RmMEg5Z' + + 'VdjV2xsS1FlaU5ZX1ZlSW1NWkEiLCJpc3MiOiJodHRwczov' + + 'L2xib3lldHRlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p' + + '5YzhtdlZUSk8wZzciLCJhdWQiOiJodHRwczovL2xib3lldH' + + 'RlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p5YzhtdlZUS' + + 'k8wZzciLCJzdWIiOiIwMHUxcGNsYTVxWUlSRURMV0NRViIs' + + 'ImlhdCI6MTQ2ODQ2NzY0NywiZXhwIjoxNDY4NDcxMjQ3LCJ' + + 'jaWQiOiJQZjBhaWZyaFladTF2MFAxYkZGeiIsInVpZCI6Ij' + + 'AwdTFwY2xhNXFZSVJFRExXQ1FWIiwic2NwIjpbIm9wZW5pZ' + + 'CIsImVtYWlsIl19.ziKfS8IjSdOdTHCZllTDnLFdE96U9bS' + + 'IsJzI0MQ0zlnM2QiiA7nvS54k6Xy78ebnkJvmeMCctjXVKk' + + 'JOEhR6vs11qVmIgbwZ4--MqUIRU3WoFEsr0muLl039QrUa1' + + 'EQ9-Ua9rPOMaO0pFC6h2lfB_HfzGifXATKsN-wLdxk6cgA'; +const standardAccessTokenParsed = { + accessToken: mockAccessToken, + expiresAt: new Date().getTime() + 100, // ensure token is active + scopes: ['openid', 'email'], + tokenType: 'Bearer', + authorizeUrl: environment.ISSUER + '/oauth2/v1/authorize', + userinfoUrl: environment.ISSUER + '/oauth2/v1/userinfo' +}; + describe('Unit Tests', () => { let component: AppComponent; let fixture: ComponentFixture; @@ -55,28 +78,6 @@ describe('Unit Tests', () => { })); it('can retrieve an accessToken from the tokenManager', async (done) => { - const mockAccessToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXIiOj' + - 'EsImp0aSI6IkFULnJ2Ym5TNGlXdTJhRE5jYTNid1RmMEg5Z' + - 'VdjV2xsS1FlaU5ZX1ZlSW1NWkEiLCJpc3MiOiJodHRwczov' + - 'L2xib3lldHRlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p' + - '5YzhtdlZUSk8wZzciLCJhdWQiOiJodHRwczovL2xib3lldH' + - 'RlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p5YzhtdlZUS' + - 'k8wZzciLCJzdWIiOiIwMHUxcGNsYTVxWUlSRURMV0NRViIs' + - 'ImlhdCI6MTQ2ODQ2NzY0NywiZXhwIjoxNDY4NDcxMjQ3LCJ' + - 'jaWQiOiJQZjBhaWZyaFladTF2MFAxYkZGeiIsInVpZCI6Ij' + - 'AwdTFwY2xhNXFZSVJFRExXQ1FWIiwic2NwIjpbIm9wZW5pZ' + - 'CIsImVtYWlsIl19.ziKfS8IjSdOdTHCZllTDnLFdE96U9bS' + - 'IsJzI0MQ0zlnM2QiiA7nvS54k6Xy78ebnkJvmeMCctjXVKk' + - 'JOEhR6vs11qVmIgbwZ4--MqUIRU3WoFEsr0muLl039QrUa1' + - 'EQ9-Ua9rPOMaO0pFC6h2lfB_HfzGifXATKsN-wLdxk6cgA'; - const standardAccessTokenParsed = { - accessToken: mockAccessToken, - expiresAt: new Date().getTime() + 100, // ensure token is active - scopes: ['openid', 'email'], - tokenType: 'Bearer', - authorizeUrl: environment.ISSUER + '/oauth2/v1/authorize', - userinfoUrl: environment.ISSUER + '/oauth2/v1/userinfo' - }; // Store the token localStorage.setItem( 'okta-token-storage', @@ -86,4 +87,22 @@ describe('Unit Tests', () => { expect(accessToken).toBe(mockAccessToken); done(); }); + + it('isAuthenticated() returns true when the TokenManager returns an access token', async (done) => { + // Store the token + localStorage.setItem( + 'okta-token-storage', + JSON.stringify({'accessToken': standardAccessTokenParsed}), + ); + const authenticated = await component.oktaAuth.isAuthenticated(); + expect(authenticated).toBeTruthy(); + done(); + }); + + it('isAuthenticated() returns false when the TokenManager does not return an access token', async (done) => { + // Don't store the token + const authenticated = await component.oktaAuth.isAuthenticated(); + expect(authenticated).toBeFalsy(); + done(); + }); });