Skip to content

Commit

Permalink
fix: the endpoints property will now work properly
Browse files Browse the repository at this point in the history
- Resolved an issue with enhancing a request with
  an access token while not authenticated.
  with the current Access Token.
- Login and logout requests are now deduped
  to prevent issues with state and nonce collisions.
- Updated multiple `.name` values to use `.$name`
  • Loading branch information
Nick Woodward committed May 10, 2020
1 parent 0ba27c9 commit e79d763
Show file tree
Hide file tree
Showing 14 changed files with 401 additions and 250 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Expand Up @@ -5,11 +5,12 @@ cache: npm
branches:
only:
- master
- /^ci/.*$/
script:
- npm start lint
- npm start check-types
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ]; then npm start test.ci; fi
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ]; then npm start test.smoke; fi
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm start test.ci; fi
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm start test.smoke; fi
- npm start test
- npm start build.docs
after_success:
Expand Down
9 changes: 6 additions & 3 deletions demo/index.ts
Expand Up @@ -33,6 +33,8 @@ const auth = new SalteAuth({

return null;
},

level: 'trace',
}),

new Generic.OAuth2({
Expand All @@ -48,14 +50,15 @@ const auth = new SalteAuth({
handlers: [
new Redirect({
default: true,
navigate: 'history',
})
],

level: 'trace',
});

auth.on('login', (error, data) => {
if (error) console.error(error);
else console.log(data);
if (error) console.error('[login]:', error);
else console.log('[login]:', data);
});

const loginButton = document.createElement('button');
Expand Down
16 changes: 8 additions & 8 deletions demo/redirect.ts
@@ -1,4 +1,4 @@
import { Handler, SalteAuthError, Utils, OAuth2Provider, OpenIDProvider } from '../src/salte-auth';
import { Handler, SalteAuthError, Utils } from '../src/salte-auth';

export class Redirect extends Handler {
public constructor(config?: Redirect.Config) {
Expand All @@ -17,7 +17,7 @@ export class Redirect extends Handler {
return true;
}

public connected({ action }: Handler.ConnectedOptions): OAuth2Provider.Validation | OpenIDProvider.Validation | void {
public connected({ action }: Handler.ConnectedOptions) {
if (!action) return;

const origin = this.storage.get('origin');
Expand All @@ -26,17 +26,17 @@ export class Redirect extends Handler {

this.storage.delete('origin');

const parsed = Utils.URL.parse(location);

this.navigate(origin);

if (action === 'login') {
// Does it make sense to navigate on 'logout'?
// NOTE: This order, matters since navigate modifies the location.
const parsed = Utils.URL.parse(location);
this.navigate(origin);
return parsed;
}
}

public async open({ url, timeout = this.config.timeout }: Redirect.OpenOptions): Promise<OAuth2Provider.Validation | OpenIDProvider.Validation | void> {
this.storage.set('origin', location.href.replace(location.hash, ''));
public open({ url, timeout = this.config.timeout }: Redirect.OpenOptions): Promise<void> {
this.storage.set('origin', location.href);

this.navigate(url);

Expand Down
6 changes: 4 additions & 2 deletions src/base/core/provider.ts
@@ -1,6 +1,6 @@
import { Shared } from './shared';

import { Common, Interceptors, Logger, URL } from '../../utils';
import { Common, Interceptors, Logger, URL, Dedupe } from '../../utils';
import { SalteAuthError } from './salte-auth-error';

export class Provider extends Shared {
Expand Down Expand Up @@ -48,6 +48,8 @@ export class Provider extends Shared {

protected url = URL.url;

public dedupe = Dedupe.dedupe();

/**
* Returns the logout url for the provider.
*/
Expand Down Expand Up @@ -96,7 +98,7 @@ export interface Provider {
* Invoked when an endpoint is marked as secured.
* @returns true if the endpoint is already secured, otherwise it returns a url to secure the endpoint.
*/
secure?(request?: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<string | boolean>;
secure?(request?: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<'login' | boolean>;

on(name: 'login', listener: (error?: Error, data?: any) => void): void;
on(name: 'logout', listener: (error?: Error) => void): void;
Expand Down
4 changes: 2 additions & 2 deletions src/base/provider-oauth2.ts
Expand Up @@ -17,10 +17,10 @@ export class OAuth2Provider extends Provider {
this.required('clientID', 'responseType');
}

public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<string | boolean> {
public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<'login' | boolean> {
if (this.config.responseType === 'token') {
if (this.accessToken.expired) {
return this.$login();
return 'login';
}

if (request) {
Expand Down
30 changes: 19 additions & 11 deletions src/base/provider-openid.ts
Expand Up @@ -26,22 +26,30 @@ export class OpenIDProvider extends OAuth2Provider {
this.sync();
}

public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<string | boolean> {
public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise<'login' | boolean> {
if (Common.includes(['id_token', 'id_token token', 'token'], this.config.responseType)) {
if (this.idToken.expired) {
return this.$login();
this.logger.trace('[secure]: ID Token has expired, requesting login...');

return 'login';
}

if (this.accessToken.expired) {
const parsed = await Common.iframe({
redirectUrl: this.redirectUrl('login'),
url: this.$login({
prompt: 'none',
responseType: 'token',
}),
});

this.validate(parsed);
await this.dedupe('access-token', async () => {
this.logger.info(`[secure]: Expired access token detected, retrieving...`);

const parsed = await Common.iframe({
redirectUrl: this.redirectUrl('login'),
url: this.$login({
prompt: 'none',
responseType: 'token',
}),
});

this.logger.info(`[secure]: Access token retrieved! Validating...`);

this.validate(parsed);
})
}

if (request) {
Expand Down

0 comments on commit e79d763

Please sign in to comment.