diff --git a/core/examples/luigi-sample-angular/e2e/tests/login-flow.spec.js b/core/examples/luigi-sample-angular/e2e/tests/login-flow.spec.js index 4da8f35162..299bfc85c9 100644 --- a/core/examples/luigi-sample-angular/e2e/tests/login-flow.spec.js +++ b/core/examples/luigi-sample-angular/e2e/tests/login-flow.spec.js @@ -17,7 +17,7 @@ describe('Login Flow', () => { ); }); - it('Link in profile dropwdown', () => { + it('Link in profile dropdown', () => { cy.login('tets@email.com', 'tets'); cy.get('[data-e2e="luigi-topnav-profile"]').click(); diff --git a/core/examples/luigi-sample-angular/src/assets/auth-mock/login-mock.html b/core/examples/luigi-sample-angular/src/assets/auth-mock/login-mock.html index 1388be7d1d..751618edde 100644 --- a/core/examples/luigi-sample-angular/src/assets/auth-mock/login-mock.html +++ b/core/examples/luigi-sample-angular/src/assets/auth-mock/login-mock.html @@ -72,8 +72,18 @@

Login to Luigi sample app

-
-
+
+
diff --git a/core/examples/luigi-sample-angular/src/assets/auth-mock/logout-mock.html b/core/examples/luigi-sample-angular/src/assets/auth-mock/logout-mock.html index 9bf71ffa9d..2739002510 100644 --- a/core/examples/luigi-sample-angular/src/assets/auth-mock/logout-mock.html +++ b/core/examples/luigi-sample-angular/src/assets/auth-mock/logout-mock.html @@ -1,15 +1,47 @@ - - Luigi Mock Identity Provider - - -Logging out... - - + + Luigi Mock Identity Provider + + + Logging out... + + diff --git a/core/examples/luigi-sample-angular/src/logout.html b/core/examples/luigi-sample-angular/src/logout.html index 173757176e..2645f9298c 100644 --- a/core/examples/luigi-sample-angular/src/logout.html +++ b/core/examples/luigi-sample-angular/src/logout.html @@ -57,7 +57,7 @@
Sign in again to continue working on awesome things!

- +

@@ -74,16 +74,12 @@ var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'); var results = regex.exec(location.search); return results && decodeURIComponent(results[1].replace(/\+/g, ' ')) || ''; -}; +} -var reason = getUrlParameter('reason'); var error = getUrlParameter('error'); +var errorDescription = getUrlParameter('errorDescription'); -if (error) { - document.getElementById('message').innerText = error; -} - -switch (reason) { +switch (error) { case 'tokenExpired': document.getElementById('headline').innerText = 'Your session has expired.'; break; @@ -94,6 +90,11 @@ default: break; } + +if (errorDescription) { + document.getElementById('message').innerText = errorDescription; +} + diff --git a/core/examples/luigi-sample-angular/src/luigi-config/extended/auth.js b/core/examples/luigi-sample-angular/src/luigi-config/extended/auth.js index d66bb5d783..b9bfbdd686 100644 --- a/core/examples/luigi-sample-angular/src/luigi-config/extended/auth.js +++ b/core/examples/luigi-sample-angular/src/luigi-config/extended/auth.js @@ -91,18 +91,19 @@ class Auth { }; events = { - onLogout: () => { - console.log('onLogout'); + onLogout: settings => { + console.log('onLogout', settings); }, - onAuthSuccessful: data => { - console.log('onAuthSuccessful', data); + onAuthSuccessful: (settings, authData) => { + console.log('onAuthSuccessful', settings, authData); }, - onAuthExpired: () => { - console.log('onAuthExpired'); + onAuthExpired: settings => { + console.log('onAuthExpired', settings); + // return false; // prevent redirect to logoutUrl }, - // TODO: define luigi-client api for getting errors - onAuthError: err => { - console.log('authErrorHandler 1', err); + onAuthError: (settings, err) => { + console.log('authErrorHandler 1', err, settings); + // return false; // prevent redirect to logoutUrl, but go to / } }; } diff --git a/core/examples/luigi-sample-vue/package-lock.json b/core/examples/luigi-sample-vue/package-lock.json index a9bd8f1d13..c124edd8d7 100644 --- a/core/examples/luigi-sample-vue/package-lock.json +++ b/core/examples/luigi-sample-vue/package-lock.json @@ -5611,7 +5611,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5632,12 +5633,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5652,17 +5655,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5779,7 +5785,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5791,6 +5798,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5805,6 +5813,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5812,12 +5821,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -5836,6 +5847,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5916,7 +5928,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5928,6 +5941,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -6013,7 +6027,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -6049,6 +6064,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6068,6 +6084,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6111,12 +6128,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/core/package-lock.json b/core/package-lock.json index b73baac06b..471ac47b4c 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1647,7 +1647,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -3228,7 +3228,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3249,12 +3250,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3269,17 +3272,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3396,7 +3402,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3408,6 +3415,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3422,6 +3430,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3429,12 +3438,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3453,6 +3464,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3533,7 +3545,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3545,6 +3558,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3630,7 +3644,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3666,6 +3681,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3685,6 +3701,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3728,12 +3745,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -3845,7 +3864,7 @@ "dependencies": { "axios": { "version": "0.15.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", "dev": true, "requires": { @@ -5301,7 +5320,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -11643,7 +11662,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { diff --git a/core/package.json b/core/package.json index 3876142ff0..9a856293e6 100644 --- a/core/package.json +++ b/core/package.json @@ -41,7 +41,7 @@ "test": "babel-node ./node_modules/nyc/bin/nyc.js mocha -- --recursive test", "test:watch": "npm run test -- --watch", "bundlesize": "npm run bundle && bundlesize", - "prepush": "npm test" + "prepush": "../scripts/remove-test-prefixes.sh && npm test" }, "bundlesize": [ { diff --git a/core/src/App.html b/core/src/App.html index 7187aae071..a6f92c122b 100644 --- a/core/src/App.html +++ b/core/src/App.html @@ -55,7 +55,7 @@ import ConfirmationModal from './ConfirmationModal.html'; import Alerts from './Alerts.html'; import Modal from './Modal.html'; - import { LuigiConfig } from './services/config.js'; + import { LuigiConfig } from './core-api'; import * as Routing from './services/routing.js'; import * as Navigation from './navigation/services/navigation.js'; import * as Iframe from './services/iframe'; diff --git a/core/src/Authorization.html b/core/src/Authorization.html index 746161a556..b4fd0d1cda 100644 --- a/core/src/Authorization.html +++ b/core/src/Authorization.html @@ -63,7 +63,7 @@ {/if} - + var processExpDate = function(expiresInString) { + var expirationDate; + var expiresIn = Number(expiresInString); + if (!isNaN(expiresIn) && expiresIn > 0) { + var nsToMsMultiplier = 1000; + expirationDate = + Number(new Date()) + nsToMsMultiplier * (expiresIn - tokenLifetimeDays); + } + return expirationDate; + }; + + - - - + + window.location.href = appState; + } else { + // else tree only applies to idtoken auths, I guess + var errorDescription = hashParams['error_description']; + console.error('error', errorDescription); + window.location.href = + '/?error=' + error + '&errorDescription=' + errorDescription; + } + } + + diff --git a/core/src/core-api/auth.js b/core/src/core-api/auth.js new file mode 100644 index 0000000000..9eab4c9b79 --- /dev/null +++ b/core/src/core-api/auth.js @@ -0,0 +1,41 @@ +// import * as AsyncHelpers from '../utilities/helpers/async-helpers'; +// import * as GenericHelpers from '../utilities/helpers/generic-helpers'; +import { config } from './config'; + +class LuigiAuthManager { + constructor() {} + + /* + * Detects if authorization is enabled via configuration. + * @returns {boolean} returns true if authorization is enabled. Otherwise returns false. + */ + isAuthorizationEnabled() { + const idpProviderName = config.getConfigValue('auth.use'); + const idpProviderSettings = config.getConfigValue( + `auth.${idpProviderName}` + ); + return !!idpProviderSettings; + } + + async handleAuthEvent( + eventName, + providerInstanceSettings, + data, + redirectUrl + ) { + const result = await config.executeConfigFnAsync( + 'auth.events.' + eventName, + false, + providerInstanceSettings, + data + ); + let redirect = result === undefined || !!result; + if (redirect && redirectUrl) { + window.location.href = redirectUrl; + return; + } + return redirect; + } +} + +export const auth = new LuigiAuthManager(); diff --git a/core/src/services/config.js b/core/src/core-api/config.js similarity index 73% rename from core/src/services/config.js rename to core/src/core-api/config.js index eb46a1f838..a39343dd24 100644 --- a/core/src/services/config.js +++ b/core/src/core-api/config.js @@ -1,5 +1,6 @@ import * as AsyncHelpers from '../utilities/helpers/async-helpers'; import * as GenericHelpers from '../utilities/helpers/generic-helpers'; +import { auth } from './auth'; class LuigiConfigManager { constructor() { @@ -86,19 +87,36 @@ class LuigiConfigManager { ); } + /* + * Executes the function of the given property on the Luigi config object. + * Fails if property is not a function. + * + * If the value is a Function it is called (with the given parameters) and the result of that call is the value. + * If the value is not a Promise it is wrapped to a Promise so that the returned value is definitely a Promise. + */ + async executeConfigFnAsync(property, throwError = false, ...parameters) { + const fn = this.getConfigValue(property); + if (GenericHelpers.isFunction(fn)) { + try { + return await AsyncHelpers.applyFunctionPromisified(fn, parameters); + } catch (error) { + if (throwError) { + return Promise.reject(error); + } + } + } + + // Promise.reject(property + ' is not a function.'); + return Promise.resolve(undefined); + } /* * Detects if authorization is enabled via configuration. * @returns {boolean} returns true if authorization is enabled. Otherwise returns false. + * @deprecated now located in Luigi.authManager instead of LuigiConfig */ isAuthorizationEnabled() { - const idpProviderName = this.getConfigValue('auth.use'); - const idpProviderSettings = this.getConfigValue(`auth.${idpProviderName}`); - return !!idpProviderSettings; + return auth.isAuthorizationEnabled(); } } -const LuigiInstance = new LuigiConfigManager(); - -// Expose it window for user app to call Luigi.setConfig() -window.Luigi = LuigiInstance; -export const LuigiConfig = LuigiInstance; +export const config = new LuigiConfigManager(); diff --git a/core/src/core-api/index.js b/core/src/core-api/index.js new file mode 100644 index 0000000000..8662fd3594 --- /dev/null +++ b/core/src/core-api/index.js @@ -0,0 +1,11 @@ +import { config } from './config'; +import { auth } from './auth'; + +export const LuigiConfig = config; +export const LuigiAuth = auth; + +// Expose it window for user app to call Luigi.setConfig() +window.Luigi = Object.assign( + config, + auth +); diff --git a/core/src/main.js b/core/src/main.js index 1de260cf68..e8979fa620 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -1,6 +1,6 @@ import App from './App.html'; import { authLibraries } from './providers/auth/libraryLoaders'; -import { LuigiConfig } from './services/config'; +import { LuigiConfig } from './core-api'; const configReadyCallback = () => { const authLib = LuigiConfig.getConfigValue('auth.use'); diff --git a/core/src/navigation/ContextSwitcher.html b/core/src/navigation/ContextSwitcher.html index 404dc9abfb..e12d369417 100644 --- a/core/src/navigation/ContextSwitcher.html +++ b/core/src/navigation/ContextSwitcher.html @@ -67,7 +67,7 @@ {/if}