diff --git a/index.html b/index.html index f35d8aeb58a2759e442615bb4d76b34a9e4f0c4b..1535dd90034df558dede4e5e1065650095d8f13b 100644 --- a/index.html +++ b/index.html @@ -10,35 +10,54 @@ sib-test { display: block; } + pre{ + white-space: normal; + word-wrap: break-word; + } + .bu-test{ + border: 3px solid red; + } + .bu-test[data-src]{ + border-color: green; + } + .bu-test:after{ + content: '???'; + } + .bu-test[data-src]:after{ + color: green; + content: attr(data-src); + + } </style> </head> <body> + <div bind-user class="bu-test">user-id: </div> <h1>sib-oidc</h1> <button id="reset">clear storage and set new URL</button> <button id="reload">reload</button> - <sib-test> + <sib-test bind-user> <button id="login">Se connecter</button> <button id="logout">Se déconnecter</button> - <button id="stat">Status (console)</button> <div id="result"></div> </sib-test> <sib-auth> <sib-auth-provider - data-authority="https://test-paris.happy-dev.fr/openid/" + data-authority="https://api.test-paris.happy-dev.fr/" data-client_id="234528" data-id="paris" > </sib-auth-provider> <sib-auth-provider - data-authority="https://test-paris.happy-dev.fr/openid/" + data-authority="https://api.test-paris.happy-dev.fr/" data-client_id="234528" data-id="paris2" > </sib-auth-provider> </sib-auth> + <script> reset.onclick = () => { window.sessionStorage.clear(); @@ -49,11 +68,10 @@ </script> <script type="module"> - import { SIBBase } from 'https://unpkg.com/@startinblox/core@0.7'; + import { SIBBase, store } from 'https://unpkg.com/@startinblox/core@0.7'; class TestComponent extends SIBBase { async connectedCallback() { - stat.onclick = () => console.log(this.getStatus()); login.onclick = () => this.triggerLogin(); logout.onclick = () => this.triggerLogout(); @@ -66,21 +84,22 @@ async triggerLogout() { await this.logout(); } - - async getStatus() { - return this.getUser(); - } - - update() { - const user = this.getUser(); - if (user) { - result.innerHTML = `Bonjour ${user.profile.name} !`; - } else { + + async update() { + let user = await this.getUser(); + let idToken = await this.getUserIdToken(); + if (!user) { result.innerHTML = `Vous n'êtes pas connecté !`; + return; } + user = await store.get(user); + console.log(user); + result.innerHTML = `Bonjour ${user.username} !<br>ID Token: <pre>${idToken}</pre>`; } + empty(){} + populate(){} } customElements.define('sib-test', TestComponent); </script> </body> -</html> +</html> \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 016d102ea8181dc87f1a3adb0fcd1e3f8e4eb720..df819f9d4be86e620331159a5f1378fc938653b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -620,7 +620,8 @@ "core-js": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz", - "integrity": "sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==" + "integrity": "sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==", + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1391,7 +1392,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1412,12 +1414,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" @@ -1432,17 +1436,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", @@ -1559,7 +1566,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1571,6 +1579,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1585,6 +1594,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1592,12 +1602,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" @@ -1616,6 +1628,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1696,7 +1709,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1708,6 +1722,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1793,7 +1808,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1829,6 +1845,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", @@ -1848,6 +1865,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1891,12 +1909,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 } } }, diff --git a/sib-auth-provider.js b/sib-auth-provider.js index 61ea9d0c3ab5934ac5e5d4b88c1e64680f8bf8dd..ceee72987cf7399854b08b63c55ae817b7e831f2 100644 --- a/sib-auth-provider.js +++ b/sib-auth-provider.js @@ -1,18 +1,4 @@ -import 'https://unpkg.com/oidc-client@1.6'; - -Log.logger = console; // eslint-disable-line no-undef -Log.level = Log.INFO; // eslint-disable-line no-undef - -const defaultSettings = { - redirect_uri: window.location.origin, - post_logout_redirect_uri: window.location.origin, - // authority: 'https://test-paris.happy-dev.fr/openid/', - // client_id: '833925', - response_type: 'id_token token', - scope: 'openid profile email', - automaticsilentrenew: 'true', - loaduserinfo: 'true', -}; +import auth from 'https://dev.jspm.io/solid-auth-client'; class SIBAuthProvider extends HTMLElement { /** @@ -24,7 +10,6 @@ class SIBAuthProvider extends HTMLElement { constructor() { super(); - this.manager = null; this.id = null; } @@ -34,106 +19,20 @@ class SIBAuthProvider extends HTMLElement { * with the params set in the component, render view */ async connectedCallback() { - const { authority, client_id, id } = this.dataset; // eslint-disable-line camelcase + const { id } = this.dataset; // eslint-disable-line camelcase this.id = id; - const settings = Object.assign({}, defaultSettings, { authority, client_id }); - this.manager = new UserManager(settings); // eslint-disable-line no-undef this.render(this.dataset); } - /** @function - * @name processState - * Try to get user, the if a state is set, call the appropriate method - * If failed, clear state - */ - async processState(parent) { - const user = await this.manager.getUser(); - const state = parent.getState(); - - if (user) { - parent.setUser(user); - } - - if (state && state.value) { - try { - switch (state.value) { - case 'login': - this.loginCallback(parent); - break; - case 'logout': - this.logoutCallback(parent); - break; - default: - parent.clearState(); - } - } catch (e) { - parent.clearState(); - } - } - } - - /** @function - * @name disconnectedCallback - * Remove manager - */ - disconnectedCallback() { - this.manager = null; - } - /** @function * @name login * Start login procedure * @param {SIBAuth} parent - SIBAuth parent instance */ - async login(parent) { - const { token } = parent.setState('login', this.id); - await this.manager.signinRedirect({ - state: token, - }); - } - - /** @function - * @name loginCallback - * Finish the login procedure - * @param {SIBAuth} parent - SIBAuth parent instance - */ - async loginCallback(parent) { - const { token, previousUri } = parent.getState(); - const user = await this.manager.signinRedirectCallback(); - if (user.state !== token) { - throw new Error('CRSF token doesnt match'); - } - parent.setUser(user); - parent.clearState(); - window.location.href = previousUri; + async login() { + auth.login(this.dataset.authority); } - /** @function - * @name logout - * Start a logout procedure - * @param {SIBAuth} parent - SIBAuth parent instance - */ - async logout(parent) { - const { token } = parent.setState('logout', this.id); - await this.manager.signoutRedirect({ - state: token, - }); - } - - /** @function - * @name logoutCallback - * Finish the logout procedure - * @param {SIBAuth} parent - SIBAuth parent instance - */ - async logoutCallback(parent) { - const { token } = parent.getState(); - const signout = await this.manager.signoutRedirectCallback(); - if (signout.state !== token) { - throw new Error('CRSF token doesnt match'); - } - parent.setUser(null); - parent.clearState(); - } /** @function * @name render diff --git a/sib-auth.js b/sib-auth.js index 322e4663934340223462acce97de325069dc5da0..81843aa270e1ec1d90688a064a010e860bb4be3a 100644 --- a/sib-auth.js +++ b/sib-auth.js @@ -1,5 +1,5 @@ -import 'https://unpkg.com/oidc-client@1.6'; -import { SIBBase, Helpers } from 'https://unpkg.com/@startinblox/core@0.7'; +import auth from 'https://dev.jspm.io/solid-auth-client'; +import { Helpers, SIBBase } from 'https://unpkg.com/@startinblox/core@0.7'; const baseUrl = import.meta.url.replace(/\/[^/]*$/, ''); Helpers.importCSS(`${baseUrl}/sib-auth.css`); @@ -15,7 +15,7 @@ class SIBAuth extends HTMLElement { constructor() { super(); - this.state = null; + this.provider = null; this.user = null; this.hide(); } @@ -27,8 +27,8 @@ class SIBAuth extends HTMLElement { */ async connectedCallback() { this.install(); - this.processState(); - if (this.getUser()) { + // this.processState(); + if (await this.getUserWebId()) { this.dispatchUserInfo(); } } @@ -38,8 +38,7 @@ class SIBAuth extends HTMLElement { * Clear state and user, uninstall */ disconnectedCallback() { - this.setUser(); - this.clearState(); + auth.logout(); // .then(() => alert('Goodbye!')); this.uninstall(); } @@ -51,7 +50,12 @@ class SIBAuth extends HTMLElement { install() { SIBBase.prototype.login = () => this.login(); SIBBase.prototype.logout = () => this.logout(); - SIBBase.prototype.getUser = () => this.getUser(); + SIBBase.prototype.getUserIdToken = () => this.getUserIdToken(); + SIBBase.prototype.getUser = async () => { + const id = await this.getUserWebId(); + if (!id) return null; + return { '@id': id }; + }; this.bindUserObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'attributes') { @@ -85,6 +89,7 @@ class SIBAuth extends HTMLElement { SIBBase.prototype.login = null; SIBBase.prototype.logout = null; SIBBase.prototype.getUser = null; + SIBBase.prototype.getUserIdToken = null; this.bindUserObserver.disconnect(); } @@ -134,57 +139,6 @@ class SIBAuth extends HTMLElement { } - /** @function - * @name getState - * Search in localStorage for previous OIDC state - * @returns {State} - The state - */ - getState() { - if (!this.state) { - const state = localStorage.getItem('oidc_state'); - if (state) { - this.state = JSON.parse(state); - } else { - this.state = { - provider: null, - value: null, - token: null, - previousUri: null, - }; - } - } - return this.state; - } - - /** @function - * @name setState - * Set state in localStorage - * @param {string} value - 'login' or 'logout', default null - * @param {string} provider - the id of the provider - * @returns {State} - The state - */ - setState(value = null, provider = null) { - const state = { - value, - provider, - token: (value === null) ? null : Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5), - previousUri: (value === null) ? null : window.location.href, - }; - - localStorage.setItem('oidc_state', JSON.stringify(state)); - this.state = state; - - return state; - } - - /** @function - * @name clearState - * Reset current state - */ - clearState() { - this.setState(); - } - /** @function * @name processState * Try to get user, the if a state is set, call the appropriate provider @@ -199,7 +153,8 @@ class SIBAuth extends HTMLElement { /** @function * @name dispatchUserInfo - * Try to replace data-src by user iri on [bind-user] elements + * @param {User} userWebId - User + * Try to replace data-src by userWebId iri on [bind-user] elements */ // eslint-disable-next-line class-methods-use-this async dispatchUserInfo() { @@ -211,7 +166,7 @@ class SIBAuth extends HTMLElement { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', processDOM); } else { - await processDOM(); + processDOM(); } } @@ -219,43 +174,46 @@ class SIBAuth extends HTMLElement { * @name applyUser * @param {Element} element */ - applyUser(element) { - const user = this.getUser(); - if (user == null) return; - const id = user.profile.website; + async applyUser(element) { + const id = await this.getUserWebId(); + if (id == null) return; if (element.getAttribute(id === 'data-src')) return; element.setAttribute('data-src', id); } /** @function - * @name getUser + * @name getUserWebId * Return User or undefined * @return {User} */ - getUser() { - if (this.user) { - return this.user; - } - - const storedUser = localStorage.getItem('oidc_user'); - - if (!storedUser) { - return null; - } - - this.user = JSON.parse(storedUser); - return this.user; + // eslint-disable-next-line class-methods-use-this + getUserWebId() { + return new Promise((resolve) => { + auth.trackSession((session) => { + if (!session) { + return resolve(null); + } + return resolve(session.webId); + }); + }); } + /** @function - * @name setUser - * Set User - * @param {User} user + * @name getUserIdToken + * Return IdToken or undefined + * @return {User} */ - setUser(user) { - localStorage.setItem('oidc_user', JSON.stringify(user)); - this.user = user; - this.dispatchUserInfo(); + // eslint-disable-next-line class-methods-use-this + getUserIdToken() { + return new Promise((resolve) => { + auth.trackSession((session) => { + if (!session) { + return resolve(null); + } + return resolve(session.authorization && session.authorization.id_token); + }); + }); } /** @function @@ -274,11 +232,8 @@ class SIBAuth extends HTMLElement { * @name logout * Try to logout if favorite provider is set */ - async logout() { - const favoriteProvider = this.getFavoriteProvider(); - if (favoriteProvider) { - this.callProvider(favoriteProvider, 'logout', this); - } + logout() { + auth.logout().then(() => this.dispatchUserInfo()); } /** @function