Skip to content

Commit

Permalink
fix: login and logout events wouldn't fire prior to redirecting (#…
Browse files Browse the repository at this point in the history
…339)

- fixed various issues with the demo

closes #338
  • Loading branch information
Nick Woodward committed Mar 20, 2019
1 parent 6223e22 commit da02b5c
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 40 deletions.
13 changes: 9 additions & 4 deletions index.js
@@ -1,3 +1,4 @@
require('@babel/polyfill');
require('@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js');
require('@webcomponents/webcomponentsjs');
const moment = require('moment');
Expand All @@ -21,9 +22,9 @@ const elements = {

const configs = {
auth0: {
providerUrl: 'https://salte-alpha.auth0.com',
providerUrl: 'https://salte.auth0.com',
responseType: 'id_token token',
clientId: 'mM6h2LHJikwdbkvdoiyE8kHhL7gcV8Wb'
clientId: '6HXbmGnu4145AE0jLZO1Q01WX53cLI48'
},

azure: {
Expand Down Expand Up @@ -54,7 +55,7 @@ const queryParams = Object.assign({
'login-type': 'redirect',
'redirect-url': 'single',
'storage-type': localStorage.getItem('salte.demo.storage-type') || 'session',
'secured': 'not-secured'
'secured': localStorage.getItem('salte.demo.secured') || 'not-secured'
}, location.search.replace(/^\?/, '').split('&').reduce((r, a) => {
const match = a.match(/([^=]+)(?:=([^&]+))?/);
const key = match && match[1] || null;
Expand Down Expand Up @@ -114,7 +115,7 @@ elements.redirectUrl.addEventListener('change', updateParamsOnChange);
elements.storageType.addEventListener('change', updateParamsOnChange);
elements.secured.addEventListener('change', updateParamsOnChange);

const config = Object.assign(configs[queryParams.provider], {
let config = Object.assign(configs[queryParams.provider], {
redirectUrl: queryParams['redirect-url'] === 'single' ? location.protocol + '//' + location.host : {
loginUrl: location.protocol + '//' + location.host,
logoutUrl: location.protocol + '//' + location.host
Expand Down Expand Up @@ -150,6 +151,10 @@ if (queryParams['storage-type'] !== localStorage.getItem('salte.demo.storage-typ
localStorage.setItem('salte.demo.storage-type', queryParams['storage-type']);
}

if (queryParams['secured'] !== localStorage.getItem('salte.demo.secured')) {
localStorage.setItem('salte.demo.secured', queryParams['secured']);
}

const auth = new SalteAuth(config);

if (!auth.profile.idTokenExpired) refreshUserInfo();
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -38,6 +38,7 @@
"cross-env": "^5.2.0",
"debug": "^4.0.0",
"deindent": "^0.1.0",
"diff": "^4.0.1",
"esdoc": "^1.0.3",
"esdoc-importpath-plugin": "^1.0.1",
"esdoc-member-plugin": "^1.0.0",
Expand All @@ -54,7 +55,7 @@
"karma": "^4.0.0",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.0.0",
"karma-mocha": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.5",
"karma-sauce-launcher": "^2.0.0",
"karma-sinon": "^1.0.0",
Expand Down
32 changes: 17 additions & 15 deletions src/salte-auth.js
Expand Up @@ -136,33 +136,35 @@ class SalteAuth {

if (this.$utilities.$iframe) {
logger('Detected iframe, removing...');
this.profile.$hash();
this.profile.$parseParams();
parent.document.body.removeChild(this.$utilities.$iframe);
} else if (this.$utilities.$popup) {
logger('Popup detected!');
} else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) {
logger('Redirect detected!');
this.profile.$hash();
this.profile.$parseParams();
const error = this.profile.$validate();
if (error) {
this.profile.$clear();
} else {
logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);
this.$utilities.$navigate(this.profile.$redirectUrl);
this.profile.$redirectUrl = undefined;
}

// TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.
this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);

// Delay for an event loop to give users time to register a listener.
setTimeout(() => {
const action = this.profile.$actions(this.profile.$state);

if (error) {
this.profile.$clear();
} else {
logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);
this.$utilities.$navigate(this.profile.$redirectUrl);
this.profile.$redirectUrl = undefined;
}

if (action === 'login') {
this.$fire('login', error);
this.$fire('login', error || null, this.profile.userInfo);
} else if (action === 'logout') {
this.$fire('logout', error);
}

// TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.
this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);
});
} else {
logger('Setting up interceptors...');
Expand Down Expand Up @@ -467,7 +469,7 @@ class SalteAuth {
this.profile.$clear();
this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => {
this.$promises.login = null;
this.profile.$hash();
this.profile.$parseParams();
const error = this.profile.$validate();

if (error) {
Expand Down Expand Up @@ -506,7 +508,7 @@ class SalteAuth {
this.profile.$clear();
this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => {
this.$promises.login = null;
this.profile.$hash();
this.profile.$parseParams();
const error = this.profile.$validate();

if (error) {
Expand Down
12 changes: 7 additions & 5 deletions src/salte-auth.profile.js
Expand Up @@ -35,19 +35,21 @@ class SalteAuthProfile {
}

/**
* Check for a hash, parses it, and removes it.
* Checks for a hash / query params, parses it, and removes it.
*/
$hash() {
if (location.hash) {
const params = location.hash.replace(/(#!?[^#]+)?#/, '').split('&');
$parseParams() {
if (location.search || location.hash) {
const params = location.search.replace(/^\?/, '').split('&')
.concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&'));

logger(`Hash detected, parsing...`, params);
for (let i = 0; i < params.length; i++) {
const param = params[i];
const [key, value] = param.split('=');
this.$parse(key, decodeURIComponent(value));
}
logger(`Removing hash...`);
history.pushState('', document.title, location.href.split('#')[0]);
history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, ''));
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/salte-auth/salte-auth.profile.spec.js
Expand Up @@ -42,7 +42,7 @@ describe('salte-auth.profile', () => {
});
});

describe('function($hash)', () => {
describe('function($parseParams)', () => {
beforeEach(() => {
localStorage.clear();
sessionStorage.clear();
Expand All @@ -57,7 +57,7 @@ describe('salte-auth.profile', () => {
}#state=55555-55555`
);

profile.$hash();
profile.$parseParams();

expect(profile.$state).to.equal('55555-55555');
});
Expand Down
26 changes: 14 additions & 12 deletions tests/salte-auth/salte-auth.spec.js
Expand Up @@ -194,6 +194,9 @@ describe('salte-auth', () => {
});

it('should redirect to the "redirectUrl"', done => {
SalteAuthUtilities.prototype.$navigate.restore();
window.setTimeout.restore();

const url = `${location.protocol}//${location.host}${
location.pathname
}#test=test`;
Expand All @@ -211,11 +214,10 @@ describe('salte-auth', () => {
provider: 'auth0',
redirectLoginCallback: error => {
expect(error).to.deep.equal(undefined);
expect(location.href).to.equal(url);
done();
}
});

expect(location.href).to.equal(url);
});

it('should fire off a "login" event if we failed to login via a redirect', () => {
Expand Down Expand Up @@ -305,6 +307,8 @@ describe('salte-auth', () => {
});

it('should validate for errors when redirecting', done => {
window.setTimeout.restore();

sinon.stub(SalteAuthProfile.prototype, '$validate').returns({
code: 'stuff_broke',
description: 'what did you break!'
Expand All @@ -323,8 +327,6 @@ describe('salte-auth', () => {
done();
}
});

expect(location.href).to.equal(url);
});

it('should disable automatic token renewal when the screen loses visibility', () => {
Expand Down Expand Up @@ -971,17 +973,17 @@ describe('salte-auth', () => {
sinon.stub(auth, '$loginUrl').returns('');
sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve());
sinon.stub(auth.profile, '$validate');
sinon.stub(auth.profile, '$hash');
sinon.stub(auth.profile, '$parseParams');

const promise = auth.loginWithPopup();

expect(auth.profile.$clear.callCount).to.equal(1);
expect(auth.$promises.login).to.equal(promise);
expect(auth.profile.$hash.callCount).to.equal(0);
expect(auth.profile.$parseParams.callCount).to.equal(0);

return promise.then((user) => {
expect(user).to.deep.equal(auth.profile.userInfo);
expect(auth.profile.$hash.callCount).to.equal(1);
expect(auth.profile.$parseParams.callCount).to.equal(1);
expect(auth.$promises.login).to.equal(null);
});
});
Expand All @@ -999,7 +1001,7 @@ describe('salte-auth', () => {
sinon.stub(auth, '$loginUrl').returns('');
sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve());
sinon.stub(auth.profile, '$validate');
sinon.stub(auth.profile, '$hash');
sinon.stub(auth.profile, '$parseParams');

auth.loginWithPopup();

Expand Down Expand Up @@ -1081,17 +1083,17 @@ describe('salte-auth', () => {
sinon.stub(auth, '$loginUrl').returns('');
sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve());
sinon.stub(auth.profile, '$validate');
sinon.stub(auth.profile, '$hash');
sinon.stub(auth.profile, '$parseParams');

const promise = auth.loginWithNewTab();

expect(auth.profile.$clear.callCount).to.equal(1);
expect(auth.$promises.login).to.equal(promise);
expect(auth.profile.$hash.callCount).to.equal(0);
expect(auth.profile.$parseParams.callCount).to.equal(0);

return promise.then((user) => {
expect(user).to.deep.equal(auth.profile.userInfo);
expect(auth.profile.$hash.callCount).to.equal(1);
expect(auth.profile.$parseParams.callCount).to.equal(1);
expect(auth.$promises.login).to.equal(null);
});
});
Expand All @@ -1109,7 +1111,7 @@ describe('salte-auth', () => {
sinon.stub(auth, '$loginUrl').returns('');
sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve());
sinon.stub(auth.profile, '$validate');
sinon.stub(auth.profile, '$hash');
sinon.stub(auth.profile, '$parseParams');

auth.loginWithNewTab();

Expand Down
7 changes: 6 additions & 1 deletion webpack.server.config.js
@@ -1,4 +1,9 @@
const config = require('./webpack.config.js');
const common = require('./webpack.common.config.js');

const config = common({
es6: false,
minified: false
});

config.module.rules.push({
test: /\.html$/,
Expand Down

0 comments on commit da02b5c

Please sign in to comment.