diff --git a/README.md b/README.md index 6331f4179e068cf67ec2aced582325b553129315..81b30f6698dfb74012c97f3c1fd079bd6d554221 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,14 @@ the version number in its `package.json` is higher than the version number on np ## Reserved attributes -| Attribute | Description | -| ----------------- | ------------------------------------------------------------------- | -| `subscribe` | Used in all components to subscribe to attributes set by a provider | -| `unsubscribe` | Reserved for future use | -| `auth` | Authentication information, set by the authentication component | -| `lang` | Currently selected language, set by the language selector | -| `entry-point-url` | Entry point url for all api requests | +| Attribute | Description | +| ------------------------ | ------------------------------------------------------------------- | +| `subscribe` | Used in all components to subscribe to attributes set by a provider | +| `unsubscribe` | Reserved for future use | +| `auth` | Authentication information, set by the authentication component | +| `lang` | Currently selected language, set by the language selector | +| `entry-point-url` | Entry point url for all api requests | +| `requested-login-status` | Used by the login buttons to trigger a login in auth components | ## Reserved events diff --git a/package.json b/package.json index 37616160429b172160d938007a01c579e2500740..35e5c5359ce690bbfbbe3131803dd6c3b9755f68 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "version-patch": "lerna version patch", "version": "lerna version", "yarn-install": "for d in ./packages/*/ ; do (cd \"$d\" && yarn install); done;", + "rm-dist": "for d in ./packages/*/ ; do (cd \"$d\" && rm dist -Rf); done;", "lint": "lerna run lint", "publish": "lerna publish from-package --yes" }, diff --git a/packages/app-shell/src/app-shell.js b/packages/app-shell/src/app-shell.js index 2ad9b93345214ff644fcfdd1ab56e2d78df9235e..e4eb5c65fd9ee0233955efc84df59be9f396a64f 100644 --- a/packages/app-shell/src/app-shell.js +++ b/packages/app-shell/src/app-shell.js @@ -2,7 +2,7 @@ import {createI18nInstance} from './i18n.js'; import {html, css} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {LanguageSelect} from '@dbp-toolkit/language-select'; -import {Icon, EventBus} from '@dbp-toolkit/common'; +import {Icon} from '@dbp-toolkit/common'; import {AuthKeycloak} from '@dbp-toolkit/auth'; import {AuthMenuButton} from './auth-menu-button.js'; import {Notification} from '@dbp-toolkit/notification'; @@ -60,8 +60,6 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { this.env = ''; this.buildUrl = ''; this.buildTime = ''; - - this._updateAuth = this._updateAuth.bind(this); this._loginStatus = 'unknown'; this.matomoUrl = ''; @@ -73,6 +71,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { this.shellName = 'TU Graz'; this.shellSubname= 'Graz University of Technology'; this.noBrand = false; + this.auth = {}; } static get scopedElements() { @@ -250,43 +249,22 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { buildUrl: { type: String, attribute: "build-url" }, buildTime: { type: String, attribute: "build-time" }, env: { type: String }, + auth: { type: Object }, }; } - _updateAuth(login) { - if (login.status != this._loginStatus) { - console.log('Login status: ' + login.status); - } - - this._loginStatus = login.status; - - // Clear the session storage when the user logs out - if (this._loginStatus === 'logging-out') { - sessionStorage.clear(); - } - } - connectedCallback() { super.connectedCallback(); - this._bus = new EventBus(); - if (this.src) this.fetchMetadata(this.src); this.initRouter(); - this._bus.subscribe('auth-update', this._updateAuth); - this.updateComplete.then(()=> { this.matomo = this.shadowRoot.querySelector(this.constructor.getScopedTagName('dbp-matomo')); }); } - disconnectedCallback() { - this._bus.close(); - super.disconnectedCallback(); - } - /** * Switches language if another language is requested * @@ -304,14 +282,32 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { - // For screen readers - document.documentElement.setAttribute("lang", this.lang); - i18n.changeLanguage(this.lang); - - this.router.update(); - this.subtitle = this.activeMetaDataText("short_name"); - this.description = this.activeMetaDataText("description"); + switch (propName) { + case 'lang': + i18n.changeLanguage(this.lang); + // For screen readers + document.documentElement.setAttribute("lang", this.lang); + i18n.changeLanguage(this.lang); + + this.router.update(); + this.subtitle = this.activeMetaDataText("short_name"); + this.description = this.activeMetaDataText("description"); + break; + case 'auth': + { + const loginStatus = this.auth['login-status']; + if (loginStatus !== this._loginStatus) { + console.log('Login status: ' + loginStatus); + } + + this._loginStatus = loginStatus; + + // Clear the session storage when the user logs out + if (this._loginStatus === 'logging-out') { + sessionStorage.clear(); + } + } + break; } }); @@ -815,8 +811,8 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { return html` <slot class="${slotClassMap}"></slot> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="${kc.url}" realm="${kc.realm}" client-id="${kc.clientId}" silent-check-sso-redirect-uri="${kc.silentCheckSsoRedirectUri || ''}" scope="${kc.scope || ''}" idp-hint="${kc.idpHint || ''}" load-person ?force-login="${kc.forceLogin}" ?try-login="${!kc.forceLogin}"></dbp-auth-keycloak> - <dbp-matomo endpoint="${this.matomoUrl}" site-id="${this.matomoSiteId}" git-info="${this.gitInfo}"></dbp-matomo> + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="${kc.url}" realm="${kc.realm}" client-id="${kc.clientId}" silent-check-sso-redirect-uri="${kc.silentCheckSsoRedirectUri || ''}" scope="${kc.scope || ''}" idp-hint="${kc.idpHint || ''}" load-person ?force-login="${kc.forceLogin}" ?try-login="${!kc.forceLogin}"></dbp-auth-keycloak> + <dbp-matomo subscribe="auth" endpoint="${this.matomoUrl}" site-id="${this.matomoSiteId}" git-info="${this.gitInfo}"></dbp-matomo> <div class="${mainClassMap}"> <div id="main"> <dbp-notification lang="${this.lang}"></dbp-notification> @@ -827,7 +823,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { <div class="hd1-middle"> </div> <div class="hd1-right"> - <dbp-auth-menu-button class="auth-button" lang="${this.lang}"></dbp-auth-menu-button> + <dbp-auth-menu-button subscribe="auth" class="auth-button" lang="${this.lang}"></dbp-auth-menu-button> </div> <div class="hd2-left"> <div class="header"> diff --git a/packages/app-shell/src/auth-menu-button.js b/packages/app-shell/src/auth-menu-button.js index 8d86bd852c9fae4a78b2c16362254dc9793d66db..ce8e9fc1b076d8d498548afd7dfb22c17c53568a 100644 --- a/packages/app-shell/src/auth-menu-button.js +++ b/packages/app-shell/src/auth-menu-button.js @@ -3,8 +3,9 @@ import {html, css} from 'lit-element'; import {unsafeHTML} from 'lit-html/directives/unsafe-html.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import {Icon, EventBus} from '@dbp-toolkit/common'; +import {Icon} from '@dbp-toolkit/common'; import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {LoginStatus} from "@dbp-toolkit/auth/src/util"; const i18n = createI18nInstance(); @@ -15,7 +16,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { super(); this.lang = 'de'; this.showImage = false; - this._loginData = {}; + this.auth = {}; this.closeDropdown = this.closeDropdown.bind(this); this.onWindowResize = this.onWindowResize.bind(this); @@ -32,7 +33,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { ...super.properties, lang: { type: String }, showImage: { type: Boolean, attribute: 'show-image' }, - _loginData: { type: Object, attribute: false }, + auth: { type: Object }, }; } @@ -43,18 +44,12 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { connectedCallback() { super.connectedCallback(); - this._bus = new EventBus(); - this._bus.subscribe('auth-update', (data) => { - this._loginData = data; - }); - window.addEventListener('resize', this.onWindowResize); document.addEventListener('click', this.closeDropdown); } disconnectedCallback() { window.removeEventListener('resize', this.onWindowResize); - this._bus.close(); document.removeEventListener('click', this.closeDropdown); super.disconnectedCallback(); } @@ -76,12 +71,12 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } onLoginClicked(e) { - this._bus.publish('auth-login'); + this.sendSetPropertyEvent('requested-login-status', LoginStatus.LOGGED_IN); e.preventDefault(); } onLogoutClicked(e) { - this._bus.publish('auth-logout'); + this.sendSetPropertyEvent('requested-login-status', LoginStatus.LOGGED_OUT); } update(changedProperties) { @@ -251,14 +246,14 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } renderLoggedIn() { - const person = this._loginData.person; + const person = this.auth.person; const imageURL = (this.showImage && person && person.image) ? person.image : null; return html` <div class="dropdown" @click="${this.onDropdownClick}"> <a href="#"> <div class="dropdown-trigger login-button"> - <div class="name">${this._loginData.name}</div> + <div class="name">${this.auth['user-full-name']}</div> <dbp-icon class="menu-icon" name="chevron-down" id="menu-chevron-icon"></dbp-icon> </div> </a> @@ -307,7 +302,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } render() { - const loggedIn = (this._loginData.status === 'logged-in'); + const loggedIn = (this.auth['login-status'] === 'logged-in'); return html` <div class="authbox"> ${loggedIn ? this.renderLoggedIn() : this.renderLoggedOut()} diff --git a/packages/auth/README.md b/packages/auth/README.md index 9b1a061b2c05ebe3fa4433ead2f404b88fa1713c..238f9e16048fca1b3f818ab55f7faeb2c131166c 100644 --- a/packages/auth/README.md +++ b/packages/auth/README.md @@ -27,6 +27,9 @@ npm i @dbp-toolkit/auth - `try-login` (optional, default: off): if enabled the a login will happen if the user is already logged in and finishing the login process would not result in a page location change (reload/redirect). - example `<dbp-auth-keycloak try-login></dbp-auth-keycloak>` +- `requested-login-status` (optional, default: `unknown`): can be set to `logged-in` or `logged-out` to request a login or logout + - example `<dbp-auth-keycloak requested-login-status="logged-in"></dbp-auth-keycloak>` + - note: most often this should be an attribute that is not set directly, but subscribed at a provider ### Keycloak Specific Attributes @@ -41,6 +44,7 @@ npm i @dbp-toolkit/auth The component emits a `dbp-set-property` event for the attribute `auth`: - `auth.subject`: Keycloak username +- `auth.login-status`: Login status (`unknown`, `logging-in`, `logging-out`, `logged-in`, `logged-out`) - `auth.token`: Keycloak token to send with your requests - `auth.user-full-name`: Full name of the user - `auth.person-id`: Person identifier of the user diff --git a/packages/auth/assets/index.html b/packages/auth/assets/index.html index a79ecbd9235e09bdf22f4df2c1e5364cc2270a2b..a96e02202a402c6204e3342618457c2aaac304ea 100644 --- a/packages/auth/assets/index.html +++ b/packages/auth/assets/index.html @@ -8,8 +8,8 @@ <body> -<dbp-provider auth> - <dbp-auth-keycloak lang="de" entry-point-url="http://127.0.0.1:8000" +<dbp-provider auth requested-login-status> + <dbp-auth-keycloak subscribe="requested-login-status" lang="de" entry-point-url="http://127.0.0.1:8000" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" @@ -17,7 +17,7 @@ scope="optional-test-scope" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="de" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="de" show-image></dbp-login-button> <dbp-auth-demo lang="de" entry-point-url="http://127.0.0.1:8000" subscribe="auth:auth"></dbp-auth-demo> </dbp-provider> diff --git a/packages/auth/src/auth-keycloak.js b/packages/auth/src/auth-keycloak.js index f72d7dd3ed737a19bff6a5f5748a501ba555542a..65441ec00e9dedb15b19f82dcb6b07c1a24f83bb 100644 --- a/packages/auth/src/auth-keycloak.js +++ b/packages/auth/src/auth-keycloak.js @@ -1,6 +1,5 @@ import {i18n} from './i18n.js'; import JSONLD from '@dbp-toolkit/common/jsonld'; -import {EventBus} from '@dbp-toolkit/common'; import {KeycloakWrapper} from './keycloak.js'; import {LoginStatus} from './util.js'; import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; @@ -12,6 +11,7 @@ import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; * * Emits a dbp-set-property event for the attribute "auth": * auth.subject: Keycloak username + * auth.login-status: Login status (see object LoginStatus) * auth.token: Keycloak token to send with your requests * auth.user-full-name: Full name of the user * auth.person-id: Person identifier of the user @@ -31,6 +31,7 @@ export class AuthKeycloak extends AdapterLitElement { this.person = null; this.entryPointUrl = ''; this._loginStatus = LoginStatus.UNKNOWN; + this.requestedLoginStatus = LoginStatus.UNKNOWN; // Keycloak config this.keycloakUrl = null; @@ -44,9 +45,33 @@ export class AuthKeycloak extends AdapterLitElement { } update(changedProperties) { + console.log("changedProperties", changedProperties); changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { - i18n.changeLanguage(this.lang); + switch (propName) { + case 'lang': + i18n.changeLanguage(this.lang); + break; + case 'requestedLoginStatus': + console.log("requested-login-status changed", this.requestedLoginStatus); + switch(this.requestedLoginStatus) { + case LoginStatus.LOGGED_IN: + this._kcwrapper.login({lang: this.lang, scope: this.scope || ''}); + break; + case LoginStatus.LOGGED_OUT: + // Keycloak will redirect right away without emitting events, so we have + // to do this manually here + if (this._loginStatus === LoginStatus.LOGGED_IN) { + this._setLoginStatus(LoginStatus.LOGGING_OUT); + } + this._kcwrapper.logout(); + // In case logout was aborted, for example with beforeunload, + // revert back to being logged in + if (this._loginStatus === LoginStatus.LOGGING_OUT) { + this._setLoginStatus(LoginStatus.LOGGED_IN); + } + break; + } + break; } }); @@ -113,6 +138,7 @@ export class AuthKeycloak extends AdapterLitElement { sendSetPropertyEvents() { const auth = { + 'login-status': this._loginStatus, 'subject': this.subject, 'token': this.token, 'user-full-name': this.name, @@ -126,6 +152,7 @@ export class AuthKeycloak extends AdapterLitElement { } this.sendSetPropertyEvent('auth', auth); + JSONLD.doInitializationOnce(this.entryPointUrl, this.token); // this.sendSetPropertyEvent('auth-subject', this.subject); // this.sendSetPropertyEvent('auth-token', this.token); @@ -139,15 +166,7 @@ export class AuthKeycloak extends AdapterLitElement { return; this._loginStatus = status; - - this._bus.publish('auth-update', { - status: this._loginStatus, - token: this.token, - name: this.name, - person: this.person, - }, { - retain: true, - }); + this.sendSetPropertyEvents(); } static get properties() { @@ -170,6 +189,7 @@ export class AuthKeycloak extends AdapterLitElement { silentCheckSsoRedirectUri: { type: String, attribute: 'silent-check-sso-redirect-uri' }, scope: { type: String }, idpHint: { type: String, attribute: 'idp-hint' }, + requestedLoginStatus: { type: String, attribute: 'requested-login-status' }, }; } @@ -183,28 +203,9 @@ export class AuthKeycloak extends AdapterLitElement { if (!this.clientId) throw Error("client-id not set"); - this._bus = new EventBus(); this._kcwrapper = new KeycloakWrapper(this.keycloakUrl, this.realm, this.clientId, this.silentCheckSsoRedirectUri, this.idpHint); this._kcwrapper.addEventListener('changed', this._onKCChanged); - this._bus.subscribe('auth-login', () => { - this._kcwrapper.login({lang: this.lang, scope: this.scope || ''}); - }); - - this._bus.subscribe('auth-logout', () => { - // Keycloak will redirect right away without emitting events, so we have - // to do this manually here - if (this._loginStatus === LoginStatus.LOGGED_IN) { - this._setLoginStatus(LoginStatus.LOGGING_OUT); - } - this._kcwrapper.logout(); - // In case logout was aborted, for example with beforeunload, - // revert back to being logged in - if (this._loginStatus === LoginStatus.LOGGING_OUT) { - this._setLoginStatus(LoginStatus.LOGGED_IN); - } - }); - const handleLogin = async () => { if (this.forceLogin || this._kcwrapper.isLoggingIn()) { this._setLoginStatus(LoginStatus.LOGGING_IN); @@ -225,7 +226,6 @@ export class AuthKeycloak extends AdapterLitElement { disconnectedCallback() { this._kcwrapper.close(); this._kcwrapper.removeEventListener('changed', this._onKCChanged); - this._bus.close(); super.disconnectedCallback(); } diff --git a/packages/auth/src/login-button.js b/packages/auth/src/login-button.js index 8465c5879efb132a9ebf9e9adc83a06e4319bd24..27dc27cdf1db7170ea49b38bba19b78e5ebc537d 100644 --- a/packages/auth/src/login-button.js +++ b/packages/auth/src/login-button.js @@ -3,9 +3,8 @@ import {html, css} from 'lit-element'; import {unsafeHTML} from 'lit-html/directives/unsafe-html.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import {LitElement} from "lit-element"; -import {EventBus} from '@dbp-toolkit/common'; import {LoginStatus} from './util.js'; +import {AdapterLitElement} from "../../provider/src/adapter-lit-element"; let logoutSVG = ` <svg @@ -63,12 +62,12 @@ let loggingInSVG = ` </svg> `; -export class LoginButton extends ScopedElementsMixin(LitElement) { +export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); this.lang = 'de'; - this._loginData = {}; + this.auth = {}; } static get scopedElements() { @@ -79,31 +78,25 @@ export class LoginButton extends ScopedElementsMixin(LitElement) { static get properties() { return { lang: { type: String }, - _loginData: { type: Object, attribute: false }, + auth: { type: Object }, }; } connectedCallback() { super.connectedCallback(); - - this._bus = new EventBus(); - this._bus.subscribe('auth-update', (data) => { - this._loginData = data; - }); } disconnectedCallback() { - this._bus.close(); super.disconnectedCallback(); } _onLoginClicked(e) { - this._bus.publish('auth-login'); + this.sendSetPropertyEvent('requested-login-status', LoginStatus.LOGGED_IN); e.preventDefault(); } _onLogoutClicked(e) { - this._bus.publish('auth-logout'); + this.sendSetPropertyEvent('requested-login-status', LoginStatus.LOGGED_OUT); e.preventDefault(); } @@ -164,7 +157,7 @@ export class LoginButton extends ScopedElementsMixin(LitElement) { } render() { - if (this._loginData.status === LoginStatus.LOGGING_IN) { + if (this.auth['login-status'] === LoginStatus.LOGGING_IN) { // try to keep the layout the same to avoid layout shifts return html` <a href="#"> @@ -174,7 +167,7 @@ export class LoginButton extends ScopedElementsMixin(LitElement) { </div> </a> `; - } else if (this._loginData.status === LoginStatus.LOGGED_IN) { + } else if (this.auth['login-status'] === LoginStatus.LOGGED_IN) { return html` <a href="#" @click="${this._onLogoutClicked}"> <div class="login-box login-button"> diff --git a/packages/check-in-place-select/assets/index.html b/packages/check-in-place-select/assets/index.html index 7aff3df6307822a46d91b174106dc17864408c22..05c5fbdbd4436c88ee1976643d8d1d0f9fabe4cd 100644 --- a/packages/check-in-place-select/assets/index.html +++ b/packages/check-in-place-select/assets/index.html @@ -8,6 +8,6 @@ <body> -<dbp-check-in-place-select-demo lang="de" entry-point-url="http://127.0.0.1:8000" auth></dbp-check-in-place-select-demo> +<dbp-check-in-place-select-demo lang="de" entry-point-url="http://127.0.0.1:8000" auth requested-login-status></dbp-check-in-place-select-demo> </body> </html> diff --git a/packages/check-in-place-select/src/check-in-place-select.js b/packages/check-in-place-select/src/check-in-place-select.js index 9cff78324e49102ebf1ac993e86432cfe2e77bc8..24a8d285b31414bc0dc8cdea1624358e06f3c597 100644 --- a/packages/check-in-place-select/src/check-in-place-select.js +++ b/packages/check-in-place-select/src/check-in-place-select.js @@ -308,6 +308,9 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { // we don't need to preset the selector if the entry point url changes this.initJSONLD(true); break; + case "auth": + JSONLD.doInitializationOnce(this.entryPointUrl, this.auth.token); + break; } }); diff --git a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js index f4e58324a25fd3e16c5f34519dbccc0d44baa3e3..1d302c0aba432d24b5b4fef1bf31f26818287ee1 100644 --- a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js +++ b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js @@ -53,12 +53,12 @@ export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } diff --git a/packages/common/jsonld.js b/packages/common/jsonld.js index 139a54e8923e9e96152d8c6eeb460897912e6486..fc7d7fcae65127f7332fdc007892ddc22610e407 100644 --- a/packages/common/jsonld.js +++ b/packages/common/jsonld.js @@ -3,7 +3,6 @@ import {send as notify} from './notification'; import * as utils from "./utils"; import {i18n} from "./i18n"; -import {EventBus} from './'; let instances = {}; let successFunctions = {}; @@ -44,21 +43,25 @@ export default class JSONLD { // add success and failure functions if (typeof successFnc == 'function') successFunctions[apiUrl].push(successFnc); if (typeof failureFnc == 'function') failureFunctions[apiUrl].push(failureFnc); + } - // check if api call was already started - if (initStarted[apiUrl] !== undefined) { + /** + * This should be run as soon as an api token is available (can be run multiple times) + * + * @param apiUrl + * @param token + */ + static doInitializationOnce(apiUrl, token) { + // console.log("doInitializationOnce", apiUrl, token); + + // check if token is not set or api call was already started + if (!apiUrl || !token || initStarted[apiUrl] !== undefined) { return; } initStarted[apiUrl] = true; - - this._bus = new EventBus(); - this._bus.subscribe('auth-update', (data) => { - if (data.token) { - this._bus.close(); - JSONLD.doInitialization(apiUrl, data.token); - } - }); + JSONLD.doInitialization(apiUrl, token); + // console.log("doInitializationOnce Done", apiUrl, token); } static doInitialization(apiUrl, token) { diff --git a/packages/data-table-view/assets/index.html b/packages/data-table-view/assets/index.html index bd116466b850a22ff9177b008cd0889ea95247cc..f6bdd8b3b8a76537a24f5840d9f2718ce48581d7 100644 --- a/packages/data-table-view/assets/index.html +++ b/packages/data-table-view/assets/index.html @@ -15,6 +15,6 @@ <body> -<dbp-data-table-view-demo lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-data-table-view-demo> +<dbp-data-table-view-demo lang="de" entry-point-url="http://127.0.0.1:8000" auth requested-login-status></dbp-data-table-view-demo> </body> </html> diff --git a/packages/data-table-view/src/dbp-data-table-view-demo.js b/packages/data-table-view/src/dbp-data-table-view-demo.js index 91508ff76e52073541fa74eae004a7eee8d69e8f..dc2bb24d0398aab00880490fd4b0b16b14bf0ef0 100644 --- a/packages/data-table-view/src/dbp-data-table-view-demo.js +++ b/packages/data-table-view/src/dbp-data-table-view-demo.js @@ -139,12 +139,12 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } diff --git a/packages/knowledge-base-web-page-element-view/assets/index.html b/packages/knowledge-base-web-page-element-view/assets/index.html index bd187181e4406404da0690ae98840c453a63a1b1..1835cd2dcad40c2e80bbf9eb3841dfa2d274ff9e 100644 --- a/packages/knowledge-base-web-page-element-view/assets/index.html +++ b/packages/knowledge-base-web-page-element-view/assets/index.html @@ -14,7 +14,7 @@ </style> <body> -<dbp-knowledge-base-web-page-element-view-demo auth lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-knowledge-base-web-page-element-view-demo> +<dbp-knowledge-base-web-page-element-view-demo auth requested-login-status lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-knowledge-base-web-page-element-view-demo> </body> </html> diff --git a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js index d4ad245daff9437dceee12f1be1df30d8eaba783..14a2f4fdd5380e071fff06446fa9ada6485bba51 100644 --- a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js +++ b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js @@ -67,12 +67,12 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } diff --git a/packages/matomo/assets/index.html.ejs b/packages/matomo/assets/index.html.ejs index 4b5cf90ddbe730b29c2d8ee228578a2bc8992e49..c4c469e559eb506b99e1784a3c9647fd4bde8ee3 100644 --- a/packages/matomo/assets/index.html.ejs +++ b/packages/matomo/assets/index.html.ejs @@ -7,7 +7,7 @@ <body> -<dbp-matomo-demo lang="de" entry-point-url="http://127.0.0.1:8000" matomo-url="<%= matomoUrl %>" matomo-site-id="<%= matomoSiteId %>"></dbp-matomo-demo> +<dbp-matomo-demo lang="de" auth requested-login-status entry-point-url="http://127.0.0.1:8000" matomo-url="<%= matomoUrl %>" matomo-site-id="<%= matomoSiteId %>"></dbp-matomo-demo> <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p> <p>Matomo: url: <%= matomoUrl %>, site-id: <%= matomoSiteId %></p> diff --git a/packages/matomo/src/dbp-matomo-demo.js b/packages/matomo/src/dbp-matomo-demo.js index 79e4d6757d80175f8708ae7e393776b575db2635..e7fee8d8c35940bdbd4e27d4294b39a8cd7dd94a 100644 --- a/packages/matomo/src/dbp-matomo-demo.js +++ b/packages/matomo/src/dbp-matomo-demo.js @@ -69,12 +69,12 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } diff --git a/packages/matomo/src/matomo.js b/packages/matomo/src/matomo.js index 4af66dfadf5d9378a0c7a953cc0dfec08297dff2..6da1d3700793b658a539567a6910066251320360 100644 --- a/packages/matomo/src/matomo.js +++ b/packages/matomo/src/matomo.js @@ -1,5 +1,5 @@ import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; -import {EventBus} from '@dbp-toolkit/common'; +import {LoginStatus} from "@dbp-toolkit/auth/src/util"; function pushEvent(event) { window._paq = window._paq || []; @@ -15,6 +15,8 @@ export class MatomoElement extends DBPLitElement { this.isRunning = false; this.lastEvent = []; this.gitInfo = ''; + this.auth = {}; + this.loginStatus = ''; } @@ -23,21 +25,27 @@ export class MatomoElement extends DBPLitElement { endpoint: { type: String }, siteId: { type: Number, attribute: 'site-id' }, gitInfo: { type: Number, attribute: 'git-info' }, + auth: { type: Object }, }; } - connectedCallback() { - super.connectedCallback(); - - this._bus = new EventBus(); - this._bus.subscribe('auth-update', (data) => { - this.setupMatomo(data.status === 'logged-in'); + update(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + switch (propName) { + case 'auth': + { + const loginStatus = this.auth['login-status']; + + if (this.loginStatus !== loginStatus) { + this.setupMatomo(loginStatus === LoginStatus.LOGGED_IN); + this.loginStatus = loginStatus; + } + } + break; + } }); - } - disconnectedCallback() { - this._bus.close(); - super.disconnectedCallback(); + super.update(changedProperties); } render() { diff --git a/packages/person-profile/assets/index.html b/packages/person-profile/assets/index.html index 98f592977cbbb248707f467e6dbd187e71439362..9fab97b784b87e35daa8b50f9fe71dd5cb20d48d 100644 --- a/packages/person-profile/assets/index.html +++ b/packages/person-profile/assets/index.html @@ -7,6 +7,6 @@ <body> -<dbp-person-profile-demo auth lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-person-profile-demo> +<dbp-person-profile-demo auth requested-login-status lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-person-profile-demo> </body> </html> diff --git a/packages/person-profile/src/dbp-person-profile-demo.js b/packages/person-profile/src/dbp-person-profile-demo.js index 9ced45b8f7edf1864bbc80998da86d74389bd80c..d696cfdc1ab2fbd13508fd6cd8d536d44f8a4818 100644 --- a/packages/person-profile/src/dbp-person-profile-demo.js +++ b/packages/person-profile/src/dbp-person-profile-demo.js @@ -8,7 +8,6 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import $ from 'jquery'; import {PersonSelect} from '@dbp-toolkit/person-select'; -import {EventBus} from '@dbp-toolkit/common'; export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -18,6 +17,7 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { this.person = ''; this.selectedPerson = ''; this.noAuth = false; + this.auth = {}; } static get scopedElements() { @@ -37,21 +37,33 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { person: { type: String, attribute: false }, selectedPerson: { type: String, attribute: false }, noAuth: { type: Boolean, attribute: 'no-auth' }, + auth: { type: Object }, }; } + update(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + switch (propName) { + case 'auth': + { + const person = this.auth.person; + + if (person) { + this.person = person.identifier; + } + } + break; + } + }); + + super.update(changedProperties); + } + connectedCallback() { super.connectedCallback(); i18n.changeLanguage(this.lang); const that = this; - this._bus = new EventBus(); - this._bus.subscribe('auth-update', (data) => { - if (data.person) { - this.person = data.person.identifier; - } - }); - this.updateComplete.then(()=>{ const personSelect = that._(this.constructor.getScopedTagName('dbp-person-select')); personSelect.onchange = function () { @@ -61,11 +73,6 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { }); } - disconnectedCallback() { - this._bus.close(); - super.disconnectedCallback(); - } - static get styles() { // language=css return css` @@ -78,12 +85,12 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } @@ -97,7 +104,7 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { <h1 class="title">Person-Profile-Demo</h1> </div> <div class="container"> - <dbp-person-profile subscribe="auth:auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.person}"></dbp-person-profile> + <dbp-person-profile subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.person}"></dbp-person-profile> </div> </section> <section class="section"> @@ -105,10 +112,10 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { <h1 class="title">Select-Profile-Demo</h1> </div> <div class="container"> - <dbp-person-select subscribe="auth:auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-person-select> + <dbp-person-select subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-person-select> </div> <div class="container"> - <dbp-person-profile subscribe="auth:auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.selectedPerson}"></dbp-person-profile> + <dbp-person-profile subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.selectedPerson}"></dbp-person-profile> </div> </section> `; diff --git a/packages/person-profile/src/person-profile.js b/packages/person-profile/src/person-profile.js index 8a3fe9c3e1889dd412b687580a4eeea1bd2d7f79..2b6846eae89cf728af83f140a70939a593ff7fa1 100644 --- a/packages/person-profile/src/person-profile.js +++ b/packages/person-profile/src/person-profile.js @@ -67,6 +67,9 @@ export class PersonProfile extends DBPLitElement { }); } break; + case "auth": + JSONLD.doInitializationOnce(this.entryPointUrl, this.auth.token); + break; default: } }); diff --git a/packages/person-select/assets/index.html b/packages/person-select/assets/index.html index 95f89808d4490b16c8c90ce308d89a6716584dcb..2365b956e3b2354b6c0cdfe36a1b65b9eb5a2770 100644 --- a/packages/person-select/assets/index.html +++ b/packages/person-select/assets/index.html @@ -7,6 +7,6 @@ <body> -<dbp-person-select-demo auth lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-person-select-demo> +<dbp-person-select-demo auth requested-login-status lang="de" entry-point-url="http://127.0.0.1:8000"></dbp-person-select-demo> </body> </html> diff --git a/packages/person-select/src/dbp-person-select-demo.js b/packages/person-select/src/dbp-person-select-demo.js index c4adde1e990cd5b767ffb4d467cff5b27d7e8104..a0838df349561fc4730af170a41148726728fc44 100644 --- a/packages/person-select/src/dbp-person-select-demo.js +++ b/packages/person-select/src/dbp-person-select-demo.js @@ -53,12 +53,12 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html` + return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> </div> `; } diff --git a/packages/person-select/src/person-select.js b/packages/person-select/src/person-select.js index d105d7648e59ea4fa49b47fd7e6edbeaa425d218..d425691637f3974cb32400b4c82e2a84c43b72d8 100644 --- a/packages/person-select/src/person-select.js +++ b/packages/person-select/src/person-select.js @@ -290,6 +290,9 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { // we don't need to preset the selector if the entry point url changes this.initJSONLD(true); break; + case "auth": + JSONLD.doInitializationOnce(this.entryPointUrl, this.auth.token); + break; } }); diff --git a/packages/provider/assets/index.html.ejs b/packages/provider/assets/index.html.ejs index 4140474df15cf5bfc3725bf85e27018fbc574e9d..a69096d594ba4f3723e174a971d87fc3f83ca555 100644 --- a/packages/provider/assets/index.html.ejs +++ b/packages/provider/assets/index.html.ejs @@ -19,7 +19,7 @@ </head> <body> - <dbp-provider id="root" root="1" availability="global" lang="de" entry-point-url="http://127.0.0.1:8000"> + <dbp-provider id="root" root="1" availability="global" lang="de" entry-point-url="http://127.0.0.1:8000" auth requested-login-status> <dbp-provider-demo id="provider-demo" subscribe="lang:lang:entry-point-url:entry-point-url"></dbp-provider-demo> </dbp-provider> <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p> diff --git a/packages/provider/src/adapter-lit-element.js b/packages/provider/src/adapter-lit-element.js index bef5034ec3a86ea223d3056106f3f036cf4475eb..e22a1914456e67349828e5702e713202a15d24b8 100644 --- a/packages/provider/src/adapter-lit-element.js +++ b/packages/provider/src/adapter-lit-element.js @@ -290,6 +290,8 @@ export class AdapterLitElement extends LitElement { // This should prevent 'Uncaught SyntaxError: JSON.parse unexpected end of data at line 1 column 1 of the JSON data' if (newValue || !oldValue || !name) { super.attributeChangedCallback(name, oldValue, newValue); + // } else { + // console.log("attributeChangedCallback ignored", name, oldValue, newValue); } } diff --git a/packages/provider/src/dbp-provider-demo.js b/packages/provider/src/dbp-provider-demo.js index b1ea183a74478a27f22d7ebd42d11da9223cba43..df6154888f47c4e632a41605034c147d8991c02f 100644 --- a/packages/provider/src/dbp-provider-demo.js +++ b/packages/provider/src/dbp-provider-demo.js @@ -79,8 +79,8 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { <h1 class="title">${i18n.t('demo.provider')}-Demo</h1> </div> <div class="container"> - <dbp-auth-keycloak lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> - <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button> <dbp-language-select></dbp-language-select> </div> <dbp-provider id="demo" diff --git a/toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs b/toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs index 59898d0901c6b5327f2762c8b4b13b10b00492b5..6eaace94c742f5f0b4d4b6f00f0f967273b0b4a0 100644 --- a/toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs +++ b/toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs @@ -62,6 +62,7 @@ <<%= name %> src="<%= getUrl(name + '.topic.metadata.json') %>" auth + requested-login-status lang="en" base-path="<%= getUrl('') %>" keycloak-config='{"url": "<%= keyCloakBaseURL %>", "realm": "tugraz", "clientId": "<%= keyCloakClientId %>", "silentCheckSsoRedirectUri": "<%= getUrl('silent-check-sso.html') %>"}'