UNPKG

@authup/client-web-kit

Version:

This package contains vue components.

1,432 lines (1,394 loc) 367 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var installFormControl = require('@vuecs/form-controls'); var smob = require('smob'); var vue = require('vue'); var installPagination = require('@vuecs/pagination'); var coreKit = require('@authup/core-kit'); var vuelidate = require('@ilingo/vuelidate'); var useVuelidate = require('@vuelidate/core'); var validators = require('@vuelidate/validators'); var listControls = require('@vuecs/list-controls'); var coreHttpKit = require('@authup/core-http-kit'); var pinia = require('pinia'); var access = require('@authup/access'); var specs = require('@authup/specs'); var kit = require('@authup/kit'); var rapiq = require('rapiq'); var coreRealtimeKit = require('@authup/core-realtime-kit'); var Cookie = require('universal-cookie'); /* * Copyright (c) 2024-2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ const BRACKET_NUMBER_REGEX = RegExp("(?<!\\\\)\\[(\\d+)]$"); /** * Convert string to property path array. * * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts * @see https://github.com/chaijs/pathval * * @param segment */ function pathToArray(segment) { const str = segment.replace(/([^\\])\[/g, '$1.['); const parts = str.match(/(\\\.|[^.]+?)+/g); if (!parts) { return []; } const result = []; for(let i = 0; i < parts.length; i++){ if (parts[i] === 'constructor' || parts[i] === '__proto__' || parts[i] === 'prototype') { continue; } const regex = BRACKET_NUMBER_REGEX.exec(parts[i]); if (regex) { result.push(regex[1]); } else { result.push(parts[i].replace(/\\([.[\]])/g, '$1')); } } return result; } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var Character; (function(Character) { Character["WILDCARD"] = "*"; Character["GLOBSTAR"] = "**"; })(Character || (Character = {})); /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function isObject(input) { return !!input && typeof input === 'object' && !Array.isArray(input); } function getPathValue(data, path) { const parts = Array.isArray(path) ? path : pathToArray(path); let res; let temp = data; let index = 0; while(index < parts.length){ if (temp === null || typeof temp === 'undefined') { break; } if (parts[index] in Object(temp)) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error temp = temp[parts[index]]; } else { break; } if (index === parts.length - 1) { res = temp; } index++; } return res; } const NUMBER_REGEX = /^\d+$/; function setPathValue(data, path, value) { const parts = Array.isArray(path) ? path : pathToArray(path); let temp = data; let index = 0; while(index < parts.length){ /* istanbul ignore next */ if (!Array.isArray(temp) && !isObject(temp)) { break; } const key = parts[index]; // [foo, '0'] if (typeof temp[key] === 'undefined') { const match = NUMBER_REGEX.test(key); if (match) { temp[key] = []; } else { temp[key] = {}; } } if (index === parts.length - 1) { temp[key] = value; break; } index++; temp = temp[key]; } return data; } class Store { /** * Set options for all groups. * * @param items */ setAll(items) { const keys = Object.keys(items); for(let i = 0; i < keys.length; i++){ this.setOptions(keys[i], items[keys[i]]); } } /** * Set options for a specific group. * * @param group * @param options */ setOptions(group, options) { if (typeof this.data[group] === 'undefined') { this.data[group] = {}; } this.data[group] = options; } hasOptions(group) { return smob.hasOwnProperty(this.data, group); } getOptions(group) { if (typeof this.data[group] !== 'undefined') { return this.data[group]; } return {}; } hasOption(group, option) { return typeof this.data[group] !== 'undefined' && smob.hasOwnProperty(this.data[group], option); } getOption(group, option) { if (typeof this.data[group] === 'undefined') { return undefined; } return this.data[group][option]; } constructor(){ this.data = {}; } } class StoreManager { keys() { return Object.keys(this.instances); } use(key) { if (typeof this.instances[key] !== 'undefined') { return this.instances[key]; } this.instances[key] = new Store(); return this.instances[key]; } constructor(){ this.instances = {}; } } function inject$2(key, instance) { if (instance && instance._context && instance._context.provides && instance._context.provides[key]) { return instance._context.provides[key]; } if (vue.hasInjectionContext()) { return vue.inject(key, undefined); } return undefined; } function provide$1(key, value, app) { if (typeof app === 'undefined') { const val = inject$2(key); if (typeof val !== 'undefined') { return; } vue.provide(key, value); return; } if (app && app._context && app._context.provides && app._context.provides[key]) { return; } app.provide(key, value); } function getSymbol(key) { return Symbol.for('VCStoreManager'); } function installStoreManager(instance, key) { const symbol = getSymbol(); let manager = inject$2(symbol, instance); if (manager) { return manager; } manager = new StoreManager(); provide$1(symbol, manager, instance); return manager; } var _sfc_main$h = vue.defineComponent({ components: { IVuelidate: vuelidate.IVuelidate, VCFormInput: installFormControl.VCFormInput, VCFormGroup: installFormControl.VCFormGroup }, props: { name: { type: String, default: undefined }, disabled: { type: Boolean, default: false } }, emits: [ 'updated', 'deleted' ], setup (props, ctx) { const form = vue.reactive({ name: props.name }); const vuelidate = useVuelidate({ name: { required: validators.required, minLength: validators.minLength(2), maxLength: validators.maxLength(512) } }, form); const handleUpdated = ()=>{ ctx.emit('updated', vuelidate.value.name.$model); }; const handleDeleted = ()=>{ ctx.emit('deleted'); }; return { handleUpdated, handleDeleted, vuelidate }; } }); var _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _hoisted_1$c = [ "disabled" ]; function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) { const _component_VCFormInput = vue.resolveComponent("VCFormInput"); const _component_VCFormGroup = vue.resolveComponent("VCFormGroup"); const _component_IVuelidate = vue.resolveComponent("IVuelidate"); return vue.openBlock(), vue.createBlock(_component_IVuelidate, { validation: _ctx.vuelidate.name }, { default: vue.withCtx((props)=>[ vue.createVNode(_component_VCFormGroup, { "validation-messages": props.data, "validation-severity": props.severity }, { default: vue.withCtx(()=>[ vue.createVNode(_component_VCFormInput, { modelValue: _ctx.vuelidate.name.$model, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event)=>_ctx.vuelidate.name.$model = $event), onChange: _ctx.handleUpdated }, { groupAppend: vue.withCtx(()=>[ vue.createElementVNode("button", { disabled: _ctx.disabled, type: "button", class: "btn btn-xs btn-warning", onClick: _cache[0] || (_cache[0] = vue.withModifiers((...args)=>_ctx.handleDeleted && _ctx.handleDeleted(...args), [ "prevent" ])) }, _cache[2] || (_cache[2] = [ vue.createElementVNode("i", { class: "fa fa-minus" }, null, -1) ]), 8, _hoisted_1$c) ]), _: 1 }, 8, [ "modelValue", "onChange" ]) ]), _: 2 }, 1032, [ "validation-messages", "validation-severity" ]) ]), _: 1 }, 8, [ "validation" ]); } var AFormInputListItem = /* @__PURE__ */ _export_sfc(_sfc_main$h, [ [ "render", _sfc_render$g ] ]); function inject$1(key, instance) { if (instance && instance._context && instance._context.provides && instance._context.provides[key]) { return instance._context.provides[key]; } if (vue.hasInjectionContext()) { return vue.inject(key, undefined); } return undefined; } function provide(key, value, app) { if (typeof app === 'undefined') { const val = inject$1(key); if (typeof val !== 'undefined') { return; } vue.provide(key, value); return; } if (app && app._context && app._context.provides && app._context.provides[key]) { return; } app.provide(key, value); } const sym$2 = Symbol.for('AuthupHTTPClientAuthenticationHook'); function injectHTTPClientAuthenticationHook(app) { const instance = inject$1(sym$2, app); if (!instance) { throw new Error('The http client authentication hook has not been injected in the app context.'); } return instance; } function hasHTTPClientAuthenticationHook(app) { try { return !!injectHTTPClientAuthenticationHook(app); } catch (e) { return false; } } function provideHTTPClientAuthenticationHook(refresher, app) { provide(sym$2, refresher, app); } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ const STORE_ID = 'authup'; /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var StoreDispatcherEventName = /*#__PURE__*/ function(StoreDispatcherEventName) { StoreDispatcherEventName["LOGGING_IN"] = "loggingIn"; StoreDispatcherEventName["LOGGED_IN"] = "loggedIn"; StoreDispatcherEventName["LOGGING_OUT"] = "loggingOut"; StoreDispatcherEventName["LOGGED_OUT"] = "loggedOut"; StoreDispatcherEventName["RESOLVING"] = "resolving"; StoreDispatcherEventName["RESOLVED"] = "resolved"; StoreDispatcherEventName["ACCESS_TOKEN_UPDATED"] = "accessTokenUpdated"; StoreDispatcherEventName["ACCESS_TOKEN_EXPIRE_DATE_UPDATED"] = "accessTokenExpireDateUpdated"; StoreDispatcherEventName["REFRESH_TOKEN_UPDATED"] = "refreshTokenUpdated"; StoreDispatcherEventName["USER_UPDATED"] = "userUpdated"; StoreDispatcherEventName["REALM_UPDATED"] = "realmUpdated"; StoreDispatcherEventName["REALM_MANAGEMENT_UPDATED"] = "realmManagementUpdated"; return StoreDispatcherEventName; }({}); // src/event-emitter.ts var EventEmitter = class { on(type, handler) { if (!this.all.has(type)) { this.all.set(type, []); } const handlers = this.all.get(type); handlers.push(handler); return ()=>handlers.splice(handlers.indexOf(handler) >>> 0, 1); } off(type, handler) { if (!type) { return this.all.clear(); } const handlers = this.all.get(type); if (handlers) { if (handler) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); } else { this.all.delete(type); } } } /** * Invoke all handlers for the given type. * If present, `'*'` handlers are invoked after type-matched handlers. * * Note: Manually firing `'*'` handlers is not supported. * * @param type The event type to invoke * @param payload Any value to each handler */ emit(type, ...payload) { let handlers = this.all.get(type); handlers?.slice().map((handler)=>{ handler(...payload); }); handlers = this.all.get("*"); if (handlers) { handlers.slice().map((handler)=>{ handler(type, payload); }); } } constructor(all){ this.all = all || /* @__PURE__ */ new Map(); } }; function createStoreDispatcher() { return new EventEmitter(); } const sym$1 = Symbol.for('AuthupStoreEventBus'); function injectStoreDispatcher(app) { const instance = inject$1(sym$1, app); if (!instance) { throw new Error('The store dispatcher has not been injected in the app context.'); } return instance; } function provideStoreDispatcher(eventBus, app) { provide(sym$1, eventBus, app); } function createPromiseShareWrapperFn(fn) { let promise; return (...args)=>{ if (promise) { return promise; } promise = new Promise((resolve, reject)=>{ fn(...args).then((r)=>resolve(r)).catch((e)=>reject(e)); }); promise.finally(()=>{ setTimeout(()=>{ promise = undefined; }, 0); }); return promise; }; } function createStore(context) { const client = new coreHttpKit.Client({ baseURL: context.baseURL }); const cookiesRead = vue.ref(false); const setCookiesRead = (value)=>{ cookiesRead.value = value; }; // -------------------------------------------------------------------- const accessToken = vue.ref(null); const setAccessToken = (input)=>{ accessToken.value = input; context.dispatcher.emit(StoreDispatcherEventName.ACCESS_TOKEN_UPDATED, input); }; // -------------------------------------------------------------------- const accessTokenExpireDate = vue.ref(null); const setAccessTokenExpireDate = (input)=>{ if (typeof input === 'number' || typeof input === 'string') { accessTokenExpireDate.value = new Date(input); // verify microseconds or seconds } else { accessTokenExpireDate.value = input; } context.dispatcher.emit(StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED, accessTokenExpireDate.value); }; // -------------------------------------------------------------------- const refreshToken = vue.ref(null); const setRefreshToken = (input)=>{ refreshToken.value = input; context.dispatcher.emit(StoreDispatcherEventName.REFRESH_TOKEN_UPDATED, input); }; // -------------------------------------------------------------------- const user = vue.ref(null); const userId = vue.computed(()=>user.value ? user.value.id : null); const setUser = (input)=>{ user.value = input; context.dispatcher.emit(StoreDispatcherEventName.USER_UPDATED, input); }; // -------------------------------------------------------------------- const realm = vue.ref(null); const realmId = vue.computed(()=>realm.value ? realm.value.id : undefined); const realmName = vue.computed(()=>realm.value ? realm.value.name : undefined); const realmIsRoot = vue.computed(()=>{ if (realm.value) { return realm.value.name === coreKit.REALM_MASTER_NAME; } return false; }); const setRealm = (input)=>{ realm.value = input; context.dispatcher.emit(StoreDispatcherEventName.REALM_UPDATED, input); }; const realmManagement = vue.ref(null); const realmManagementId = vue.computed(()=>realmManagement.value ? realmManagement.value.id : realmId.value); const realmManagementName = vue.computed(()=>realmManagement.value ? realmManagement.value.name : realmName.value); const setRealmManagement = (input)=>{ realmManagement.value = input; context.dispatcher.emit(StoreDispatcherEventName.REALM_MANAGEMENT_UPDATED, input); }; // -------------------------------------------------------------------- const permissionRepository = new access.PermissionMemoryProvider(); const permissionChecker = new access.PermissionChecker({ provider: permissionRepository, policyEngine: new access.PolicyEngine() }); // -------------------------------------------------------------------- const cleanup = async ()=>{ const tempAccessToken = accessToken.value; const tempRefreshToken = refreshToken.value; setAccessToken(null); setAccessTokenExpireDate(null); setRefreshToken(null); setUser(null); setRealm(null); setRealmManagement(null); permissionRepository.setMany([]); tokenResolved.value = false; userResolved.value = false; try { if (tempAccessToken) { await client.token.revoke({ token: tempAccessToken }); } } catch (e) { // ... } try { if (tempRefreshToken) { await client.token.revoke({ token: tempRefreshToken }); } } catch (e) { // ... } }; // -------------------------------------------------------------------- const userResolved = vue.ref(false); const resolveUser = async ()=>{ if (!accessToken.value || userResolved.value) { return Promise.resolve(); } userResolved.value = true; return client.userInfo.get(`Bearer ${accessToken.value}`).then((response)=>{ setUser(response); }); }; // -------------------------------------------------------------------- const tokenResolved = vue.ref(false); const resolveToken = async ()=>{ if (!accessToken.value || tokenResolved.value) { return Promise.resolve(); } tokenResolved.value = true; return client.token.introspect({ token: accessToken.value }, { authorizationHeader: { type: 'Bearer', token: accessToken.value } }).then((response)=>{ if (response.exp) { const expireDate = new Date(response.exp * 1000); setAccessTokenExpireDate(expireDate); } if (response.realm_id && response.realm_name) { realm.value = { id: response.realm_id, name: response.realm_name }; if (!realmManagement.value) { setRealmManagement(realm.value); } } if (response.permissions) { permissionRepository.setMany(response.permissions.map((permission)=>({ name: permission.name, realmId: permission.realm_id, clientId: permission.client_id }))); } }); }; // -------------------------------------------------------------------- const applyTokenGrantResponse = (response)=>{ const expireDate = new Date(Date.now() + response.expires_in * 1000); setAccessTokenExpireDate(expireDate); setAccessToken(response.access_token); if (response.refresh_token) { setRefreshToken(response.refresh_token); } else { setRefreshToken(null); } }; // -------------------------------------------------------------------- const refreshSession = createPromiseShareWrapperFn(async ()=>{ if (!refreshToken.value) { throw new specs.OAuth2Error('The access token can not be renewed.'); } try { const response = await client.token.createWithRefreshToken({ refresh_token: refreshToken.value }); applyTokenGrantResponse(response); } catch (e) { await cleanup(); throw e; } finally{ tokenResolved.value = false; userResolved.value = false; } }); // -------------------------------------------------------------------- // todo: rename to reload() ? const resolveInternal = async ()=>{ context.dispatcher.emit(StoreDispatcherEventName.RESOLVING); try { if (!accessToken.value && refreshToken.value) { await refreshSession(); } if (accessToken.value) { await resolveToken(); if (!user.value) { await resolveUser(); } } } catch (e) { if (refreshToken.value) { await refreshSession(); await resolveToken(); await resolveUser(); } else { throw e; } } context.dispatcher.emit(StoreDispatcherEventName.RESOLVED); }; const resolve = createPromiseShareWrapperFn(resolveInternal); const loggedIn = vue.computed(()=>!!accessToken.value); const login = async (ctx)=>{ context.dispatcher.emit(StoreDispatcherEventName.LOGGING_IN); const response = await client.token.createWithPassword({ username: ctx.name, password: ctx.password, ...realmId.value ? { realm_id: ctx.realmId } : {} }); applyTokenGrantResponse(response); await resolveToken(); await resolveUser(); context.dispatcher.emit(StoreDispatcherEventName.LOGGED_IN); }; const logout = async ()=>{ context.dispatcher.emit(StoreDispatcherEventName.LOGGING_OUT); await cleanup(); context.dispatcher.emit(StoreDispatcherEventName.LOGGED_OUT); }; return { cookiesRead, setCookiesRead, permissionChecker, login, logout, loggedIn, resolve, applyTokenGrantResponse, accessToken, setAccessToken, accessTokenExpireDate, setAccessTokenExpireDate, refreshToken, setRefreshToken, realm, realmId, realmIsRoot, realmName, setRealm, realmManagement, realmManagementId, realmManagementName, setRealmManagement, user, userId, setUser }; } function tryOnScopeDispose(fn) { if (vue.getCurrentScope()) { vue.onScopeDispose(fn); return true; } return false; } typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope; const noop = ()=>{}; function useCookies(dependencies, { doNotParse = false, autoUpdateDependencies = false } = {}, cookies = new Cookie()) { const watchingDependencies = autoUpdateDependencies ? [ ...[] ] : dependencies; let previousCookies = cookies.getAll({ doNotParse: true }); const touches = vue.shallowRef(0); const onChange = ()=>{ const newCookies = cookies.getAll({ doNotParse: true }); if (shouldUpdate(watchingDependencies || null, newCookies, previousCookies)) { touches.value++; } previousCookies = newCookies; }; cookies.addChangeListener(onChange); tryOnScopeDispose(()=>{ cookies.removeChangeListener(onChange); }); return { /** * Reactive get cookie by name. If **autoUpdateDependencies = true** then it will update watching dependencies */ get: (...args)=>{ if (autoUpdateDependencies && watchingDependencies && !watchingDependencies.includes(args[0])) watchingDependencies.push(args[0]); touches.value; return cookies.get(args[0], { doNotParse, ...args[1] }); }, /** * Reactive get all cookies */ getAll: (...args)=>{ touches.value; return cookies.getAll({ doNotParse, ...args[0] }); }, set: (...args)=>cookies.set(...args), remove: (...args)=>cookies.remove(...args), addChangeListener: (...args)=>cookies.addChangeListener(...args), removeChangeListener: (...args)=>cookies.removeChangeListener(...args) }; } function shouldUpdate(dependencies, newCookies, oldCookies) { if (!dependencies) return true; for (const dependency of dependencies){ if (newCookies[dependency] !== oldCookies[dependency]) return true; } return false; } const sym = Symbol.for('AuthupStore'); function injectStore(pinia, app) { const instance = injectStoreFactory(app); if (!instance) { throw new Error('The store has not been injected in the app context.'); } return instance(pinia); } function injectStoreFactory(app) { const instance = inject$1(sym, app); if (!instance) { throw new Error('The store factory has not been injected in the app context.'); } return instance; } function hasStoreFactory(app) { return !!inject$1(sym, app); } function provideStoreFactory(store, app) { provide(sym, store, app); } function installStore(app, options = {}) { if (hasStoreFactory(app)) { return; } const storeDispatcher = createStoreDispatcher(); provideStoreDispatcher(storeDispatcher, app); const storeFactory = pinia.defineStore(STORE_ID, ()=>createStore({ baseURL: options.baseURL, dispatcher: storeDispatcher })); const store = storeFactory(options.pinia); let cookieGet; if (options.cookieGet) { cookieGet = options.cookieGet; } else { const cookies = useCookies(); cookieGet = cookies.get; } let cookieSet; if (options.cookieSet) { cookieSet = options.cookieSet; } else { const cookies = useCookies(); cookieSet = cookies.set; } let cookieUnset; if (options.cookieUnset) { cookieUnset = options.cookieUnset; } else if (options.cookieSet) { cookieUnset = (key, opts)=>{ options.cookieSet(key, null, opts); }; } else { const cookies = useCookies(); cookieUnset = cookies.remove; } const readCookies = ()=>{ if (store.cookiesRead) { return; } store.setCookiesRead(true); const keys = Object.values(coreHttpKit.CookieName); let value; for(let i = 0; i < keys.length; i++){ value = cookieGet(keys[i]); if (!value) { continue; } switch(keys[i]){ case coreHttpKit.CookieName.ACCESS_TOKEN: if (!store.accessToken) { store.setAccessToken(value); } break; case coreHttpKit.CookieName.ACCESS_TOKEN_EXPIRE_DATE: if (!store.accessTokenExpireDate) { store.setAccessTokenExpireDate(value); } break; case coreHttpKit.CookieName.REFRESH_TOKEN: if (!store.refreshToken) { store.setRefreshToken(value); } break; case coreHttpKit.CookieName.USER: if (!store.user) { store.setUser(value); } break; case coreHttpKit.CookieName.REALM: if (!store.realm) { store.setRealm(value); } break; case coreHttpKit.CookieName.REALM_MANAGEMENT: if (!store.realmManagement) { store.setRealmManagement(value); } break; } } }; const maxAgeFn = ()=>{ if (!store.accessTokenExpireDate) { return undefined; } return Math.floor(Math.max(1000, new Date(`${store.accessTokenExpireDate}`).getTime() - Date.now()) / 1000); }; storeDispatcher.on(StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED, (input)=>{ if (input) { cookieSet(coreHttpKit.CookieName.ACCESS_TOKEN_EXPIRE_DATE, input, { maxAge: maxAgeFn() }); } else { cookieUnset(coreHttpKit.CookieName.ACCESS_TOKEN_EXPIRE_DATE, {}); } }); storeDispatcher.on(StoreDispatcherEventName.ACCESS_TOKEN_UPDATED, (input)=>{ if (input) { const maxAge = maxAgeFn(); cookieSet(coreHttpKit.CookieName.ACCESS_TOKEN, input, { maxAge }); } else { cookieUnset(coreHttpKit.CookieName.ACCESS_TOKEN, {}); } }); storeDispatcher.on(StoreDispatcherEventName.REFRESH_TOKEN_UPDATED, (input)=>{ if (input) { cookieSet(coreHttpKit.CookieName.REFRESH_TOKEN, input, {}); } else { cookieUnset(coreHttpKit.CookieName.REFRESH_TOKEN, {}); } }); storeDispatcher.on(StoreDispatcherEventName.USER_UPDATED, (input)=>{ if (input) { cookieSet(coreHttpKit.CookieName.USER, input, {}); } else { cookieUnset(coreHttpKit.CookieName.USER, {}); } }); storeDispatcher.on(StoreDispatcherEventName.REALM_UPDATED, (input)=>{ if (input) { cookieSet(coreHttpKit.CookieName.REALM, input, {}); } else { cookieUnset(coreHttpKit.CookieName.REALM, {}); } }); storeDispatcher.on(StoreDispatcherEventName.REALM_MANAGEMENT_UPDATED, (input)=>{ if (input) { cookieSet(coreHttpKit.CookieName.REALM_MANAGEMENT, input, {}); } else { cookieUnset(coreHttpKit.CookieName.REALM_MANAGEMENT, {}); } }); readCookies(); provideStoreFactory(storeFactory, app); } function storeToRefs(store) { store = vue.toRaw(store); const refs = {}; const keys = Object.keys(store); for(let i = 0; i < keys.length; i++){ const value = store[keys[i]]; if (vue.isRef(value) || vue.isReactive(value)) { refs[keys[i]] = vue.toRef(store, keys[i]); } } return refs; } function installHTTPClientAuthenticationHook(app, options = {}) { if (hasHTTPClientAuthenticationHook(app)) { return; } const storeFactory = injectStoreFactory(app); const store = storeFactory(options.pinia); const { refreshToken } = pinia.storeToRefs(store); const hook = new coreHttpKit.ClientAuthenticationHook({ baseURL: options.baseURL, tokenCreator: ()=>{ if (!refreshToken.value) { throw new Error('No refresh token available.'); } const client = new coreHttpKit.Client({ baseURL: options.baseURL }); return client.token.createWithRefreshToken({ refresh_token: refreshToken.value }); }, timer: !options.isServer }); hook.on(coreHttpKit.ClientAuthenticationHookEventName.REFRESH_FINISHED, (response)=>{ store.applyTokenGrantResponse(response); }); let isSelfCallee = false; hook.on(coreHttpKit.ClientAuthenticationHookEventName.HEADER_UNSET, ()=>{ if (!isSelfCallee) { Promise.resolve().then(()=>store.logout()); } }); const storeDispatcher = injectStoreDispatcher(app); const handleAccessTokenEvent = ()=>{ isSelfCallee = true; if (store.accessToken) { hook.enable(); hook.setAuthorizationHeader({ type: 'Bearer', token: store.accessToken }); } else { hook.disable(); hook.unsetAuthorizationHeader(); } isSelfCallee = false; }; const handleAccessTokenExpireDateEvent = ()=>{ if (store.accessTokenExpireDate) { const expiresIn = Math.floor((store.accessTokenExpireDate.getTime() - Date.now()) / 1000); hook.setTimer(expiresIn); } }; storeDispatcher.on(StoreDispatcherEventName.ACCESS_TOKEN_UPDATED, ()=>handleAccessTokenEvent()); storeDispatcher.on(StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED, ()=>handleAccessTokenExpireDateEvent()); handleAccessTokenEvent(); handleAccessTokenExpireDateEvent(); provideHTTPClientAuthenticationHook(hook, app); } const HTTPClientSymbol = Symbol.for('AuthupHTTPClient'); function provideHTTPClient(client, app) { provide(HTTPClientSymbol, client, app); } function hasHTTPClient(app) { try { return !!injectHTTPClient(app); } catch (e) { return false; } } function injectHTTPClient(app) { const instance = inject$1(HTTPClientSymbol, app); if (!instance) { throw new Error('The api client has not been injected.'); } return instance; } function installHTTPClient(app, options = {}) { if (hasHTTPClient(app)) { return; } const client = new coreHttpKit.Client({ baseURL: options.baseURL }); const authenticationHook = injectHTTPClientAuthenticationHook(app); authenticationHook.attach(client); provideHTTPClient(client, app); } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ /** * Assign properties from input to src. * 'null' values will be transformed to an empty string. * * @param src * @param input */ function assignFormProperties(src, input = {}) { const keys = Object.keys(input); for(let i = 0; i < keys.length; i++){ const value = input[keys[i]]; if (value === null) { src[keys[i]] = ''; } else { src[keys[i]] = value; } } return src; } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var TranslatorTranslationGroup = /*#__PURE__*/ function(TranslatorTranslationGroup) { TranslatorTranslationGroup["DEFAULT"] = "default"; TranslatorTranslationGroup["CLIENT"] = "authupClient"; TranslatorTranslationGroup["VUECS"] = "vuecs"; TranslatorTranslationGroup["VUELIDATE"] = "vuelidate"; return TranslatorTranslationGroup; }({}); var TranslatorTranslationVuecsKey = /*#__PURE__*/ function(TranslatorTranslationVuecsKey) { TranslatorTranslationVuecsKey["NO_MORE"] = "noMore"; return TranslatorTranslationVuecsKey; }({}); var TranslatorTranslationClientKey = /*#__PURE__*/ function(TranslatorTranslationClientKey) { TranslatorTranslationClientKey["NAME_HINT"] = "nameHint"; TranslatorTranslationClientKey["DESCRIPTION_HINT"] = "descriptionHint"; TranslatorTranslationClientKey["REDIRECT_URI_HINT"] = "redirectURIHint"; TranslatorTranslationClientKey["IS_CONFIDENTIAL"] = "isConfidential"; return TranslatorTranslationClientKey; }({}); var TranslatorTranslationDefaultKey = /*#__PURE__*/ function(TranslatorTranslationDefaultKey) { TranslatorTranslationDefaultKey["ADD"] = "add"; TranslatorTranslationDefaultKey["CREATE"] = "create"; TranslatorTranslationDefaultKey["DELETE"] = "delete"; TranslatorTranslationDefaultKey["GENERATE"] = "generate"; TranslatorTranslationDefaultKey["UPDATE"] = "update"; TranslatorTranslationDefaultKey["ACTIVE"] = "active"; TranslatorTranslationDefaultKey["INACTIVE"] = "inactive"; TranslatorTranslationDefaultKey["LOCKED"] = "locked"; TranslatorTranslationDefaultKey["NOT_LOCKED"] = "notLocked"; TranslatorTranslationDefaultKey["VALUE_IS_REGEX"] = "valueIsRegex"; TranslatorTranslationDefaultKey["CLIENT"] = "client"; TranslatorTranslationDefaultKey["CLIENTS"] = "clients"; TranslatorTranslationDefaultKey["CLIENT_SCOPES"] = "clientScopes"; TranslatorTranslationDefaultKey["DISPLAY_NAME"] = "displayName"; TranslatorTranslationDefaultKey["EMAIL"] = "email"; TranslatorTranslationDefaultKey["EXTERNAL_ID"] = "externalId"; TranslatorTranslationDefaultKey["HASHED"] = "hashed"; TranslatorTranslationDefaultKey["OVERVIEW"] = "overview"; TranslatorTranslationDefaultKey["IDENTITY_PROVIDERS"] = "identityProviders"; TranslatorTranslationDefaultKey["NAME"] = "name"; TranslatorTranslationDefaultKey["DESCRIPTION"] = "description"; TranslatorTranslationDefaultKey["PERMISSIONS"] = "permissions"; TranslatorTranslationDefaultKey["POLICY"] = "policy"; TranslatorTranslationDefaultKey["POLICIES"] = "policies"; TranslatorTranslationDefaultKey["REALM"] = "realm"; TranslatorTranslationDefaultKey["ROBOTS"] = "robots"; TranslatorTranslationDefaultKey["REALMS"] = "realms"; TranslatorTranslationDefaultKey["ROLES"] = "roles"; TranslatorTranslationDefaultKey["SCOPES"] = "scopes"; TranslatorTranslationDefaultKey["SECRET"] = "secret"; TranslatorTranslationDefaultKey["REDIRECT_URIS"] = "redirectUris"; TranslatorTranslationDefaultKey["USERS"] = "users"; return TranslatorTranslationDefaultKey; }({}); class MemoryStore { async get(context) { if (!this.data[context.locale] || !this.data[context.locale][context.group]) { return undefined; } const output = getPathValue(this.data[context.locale][context.group], context.key); if (typeof output === 'string') { return output; } return undefined; } async set(context) { this.initLines(context.group, context.locale); setPathValue(this.data[context.locale][context.group], context.key, context.value); } initLines(group, locale) { if (typeof this.data[locale] === 'undefined') { this.data[locale] = {}; } if (typeof this.data[locale][group] === 'undefined') { this.data[locale][group] = {}; } } async getLocales() { return Object.keys(this.data); } constructor(options){ this.data = options.data; } } function computedAsync(evaluationCallback, initialState, optionsOrRef) { let options; if (vue.isRef(optionsOrRef)) { options = { evaluating: optionsOrRef }; } else { options = {}; } const { lazy = false, flush = "pre", evaluating = void 0, shallow = true, onError = noop } = options; const started = vue.shallowRef(!lazy); const current = shallow ? vue.shallowRef(initialState) : vue.ref(initialState); let counter = 0; vue.watchEffect(async (onInvalidate)=>{ if (!started.value) return; counter++; const counterAtBeginning = counter; let hasFinished = false; if (evaluating) { Promise.resolve().then(()=>{ evaluating.value = true; }); } try { const result = await evaluationCallback((cancelCallback)=>{ onInvalidate(()=>{ if (evaluating) evaluating.value = false; if (!hasFinished) cancelCallback(); }); }); if (counterAtBeginning === counter) current.value = result; } catch (e) { onError(e); } finally{ if (evaluating && counterAtBeginning === counter) evaluating.value = false; hasFinished = true; } }, { flush }); if (lazy) { return vue.computed(()=>{ started.value = true; return current.value; }); } else { return current; } } function inject(key, instance) { if (vue.hasInjectionContext()) { return vue.inject(key, undefined); } return undefined; } const IlingoSymbol = Symbol.for('Ilingo'); function injectIlingo(app) { const instance = inject(IlingoSymbol); if (!instance) { throw new Error('An ilingo instance is not present in the vue context.'); } return instance; } const LocaleSymbol = Symbol.for('ILocale'); function injectLocale(app) { const locale = inject(LocaleSymbol); if (!locale) { throw new Error('An ilingo locale is not present in the vue context.'); } return locale; } function extractReactiveData(input) { const output = {}; const keys = Object.keys(input); for(let i = 0; i < keys.length; i++){ output[keys[i]] = vue.unref(input[keys[i]]); } return output; } function useTranslation$1(ctx) { const instance = injectIlingo(); const locale = injectLocale(); const defaultValue = `${ctx.group}.${ctx.key}`; return computedAsync(async ()=>{ const value = await instance.get({ locale: ctx.locale ? ctx.locale : locale.value, data: ctx.data ? extractReactiveData(ctx.data) : undefined, group: ctx.group, key: ctx.key }); return value || defaultValue; }, defaultValue); } vue.defineComponent({ props: { path: { type: String, required: true }, data: { type: Object } }, setup (props) { const parseKey = (key)=>{ const index = key.indexOf('.'); if (index === -1) { throw new SyntaxError('The key with required group prefix could not be parsed.'); } const group = key.substring(0, index); const line = key.substring(group.length + 1); return [ group, line ]; }; const [group, key] = parseKey(props.path); const text = useTranslation$1({ group, key, data: props.data }); return { text }; } }); function injectTranslatorLocale() { return injectLocale(); } function useTranslation(input) { return useTranslation$1(input); } function useTranslationsForBaseValidation(result) { return vuelidate.useTranslationsForBaseValidation(result); } function useTranslationsForNestedValidation(validation) { return vuelidate.useTranslationsForNestedValidations(validation); } function useTranslationsForGroup(group, elements) { const output = {}; for(let i = 0; i < elements.length; i++){ output[elements[i].key] = useTranslation({ ...elements[i], group }); } return output; } const TranslatorTranslationClientGerman = { [TranslatorTranslationClientKey.NAME_HINT]: 'Etwas, das Benutzer erkennen und vertrauen werden', [TranslatorTranslationClientKey.DESCRIPTION_HINT]: 'Dies wird allen Benutzern dieser Anwendung angezeigt', [TranslatorTranslationClientKey.REDIRECT_URI_HINT]: 'URI-Muster, zu dem ein Browser nach einem erfolgreichen Login weiterleiten kann', [TranslatorTranslationClientKey.IS_CONFIDENTIAL]: 'Ist vertraulich?' }; const TranslatorTranslationDefaultGerman = { [TranslatorTranslationDefaultKey.ADD]: 'hinzufügen', [TranslatorTranslationDefaultKey.CREATE]: 'erstellen', [TranslatorTranslationDefaultKey.DELETE]: 'löschen', [TranslatorTranslationDefaultKey.GENERATE]: 'generieren', [TranslatorTranslationDefaultKey.UPDATE]: 'aktualisieren', [TranslatorTranslationDefaultKey.ACTIVE]: 'aktiv', [TranslatorTranslationDefaultKey.INACTIVE]: 'inaktiv', [TranslatorTranslationDefaultKey.LOCKED]: 'gesperrt', [TranslatorTranslationDefaultKey.NOT_LOCKED]: 'nicht gesperrt', [TranslatorTranslationDefaultKey.VALUE_IS_REGEX]: 'Wert ist regex pattern?', [TranslatorTranslationDefaultKey.CLIENT]: 'Client', [TranslatorTranslationDefaultKey.CLIENTS]: 'Clients', [TranslatorTranslationDefaultKey.CLIENT_SCOPES]: 'Client-Bereiche', [TranslatorTranslationDefaultKey.DISPLAY_NAME]: 'Anzeigename', [TranslatorTranslationDefaultKey.EMAIL]: 'E-Mail', [TranslatorTranslationDefaultKey.EXTERNAL_ID]: 'externe ID', [TranslatorTranslationDefaultKey.HASHED]: 'gehasht', [TranslatorTranslationDefaultKey.OVERVIEW]: 'Überblick', [TranslatorTranslationDefaultKey.IDENTITY_PROVIDERS]: 'Identitätsanbieter', [TranslatorTranslationDefaultKey.NAME]: 'Name', [TranslatorTranslationDefaultKey.DESCRIPTION]: 'Beschreibung', [TranslatorTranslationDefaultKey.PERMISSIONS]: 'Berechtigungen', [TranslatorTranslationDefaultKey.POLICY]: 'Richtlinie', [TranslatorTranslationDefaultKey.POLICIES]: 'Richtlinien', [TranslatorTranslationDefaultKey.REALM]: 'Organisation', [TranslatorTranslationDefaultKey.REALMS]: 'Organisationen', [TranslatorTranslationDefaultKey.ROLES]: 'Rollen', [TranslatorTranslationDefaultKey.SCOPES]: 'Bereiche', [TranslatorTranslationDefaultKey.SECRET]: 'Geheimnis', [TranslatorTranslationDefaultKey.REDIRECT_URIS]: 'Weiterleitungs-URIs', [TranslatorTranslationDefaultKey.USERS]: 'Benutzer' }; var VuelidateCustomRuleKey = /*#__PURE__*/ function(VuelidateCustomRuleKey) { VuelidateCustomRuleKey["ALPHA_NUM_HYPHEN_UNDERSCORE"] = "alphaNumHyphenUnderscore"; VuelidateCustomRuleKey["ALPHA_UPPER_NUM_HYPHEN_UNDERSCORE_DOT"] = "alphaUpperNumHyphenUnderscoreDot"; return VuelidateCustomRuleKey; }({}); const VuelidateCustomRule = { ["alphaNumHyphenUnderscore"]: validators.helpers.regex(/^[a-z0-9-_]*$/), ["alphaUpperNumHyphenUnderscoreDot"]: validators.helpers.regex(/^[a-zA-Z0-9-_.]*$/) }; function getVuelidateSeverity(vuelidate$1) { return vuelidate.getSeverity(vuelidate$1); } function extractVuelidateResultsFromChild(vuelidate, child, keys) { const childResults = vuelidate.value.$getResultsForChild(child); if (!childResults) { return {}; } const childKeys = keys ?? Object.keys(childResults).filter((key)=>!key.startsWith('$')); const result = {}; for(let i = 0; i < childKeys.length; i++){ if (kit.hasOwnProperty(childResults, childKeys[i])) { result[childKeys[i]] = childResults[childKeys[i]].$model; } } return result; } const TranslatorTranslationVuelidateGerman = { [VuelidateCustomRuleKey.ALPHA_NUM_HYPHEN_UNDERSCORE]: 'Der Eingabewert darf nur aus folgenden Zeichen bestehen: [0-9a-z-_]+', [VuelidateCustomRuleKey.ALPHA_UPPER_NUM_HYPHEN_UNDERSCORE_DOT]: 'Der Eingabewert darf nur aus folgenden Zeichen bestehen: [0-9a-zA-Z-_.]+' }; const TranslatorTranslationVuecsGerman = { [TranslatorTranslationVuecsKey.NO_MORE]: 'Keine weiteren {{name}} verfügbar' }; const TranslatorTranslationClientEnglish = { [TranslatorTranslationClientKey.NAME_HINT]: 'Something users will recognize and trust', [TranslatorTranslationClientKey.DESCRIPTION_HINT]: 'Displayed to all users of this application', [TranslatorTranslationClientKey.REDIRECT_URI_HINT]: 'URI pattern a browser can redirect to after a successful login', [TranslatorTranslationClientKey.IS_CONFIDENTIAL]: 'Is confidential?' }; const TranslatorTranslationDefaultEnglish = { [TranslatorTranslationDefaultKey.ADD]: 'add', [TranslatorTranslationDefaultKey.CREATE]: 'create', [TranslatorTranslationDefaultKey.DELETE]: 'delete', [TranslatorTranslationDefaultKey.GENERATE]: 'generate', [TranslatorTranslationDefaultKey.UPDATE]: 'update', [TranslatorTranslationDefaultKey.ACTIVE]: 'active', [TranslatorTranslationDefaultKey.INACTIVE]: 'inactive', [TranslatorTranslationDefaultKey.LOCKED]: 'locked', [TranslatorTranslationDefaultKey.NOT_LOCKED]: 'not locked', [TranslatorTranslationDefaultKey.VALUE_IS_REGEX]: 'Value is regex pattern?', [TranslatorTranslationDefaultKey.CLIENT]: 'update', [TranslatorTranslationDefaultKey.CLIENTS]: 'clients', [TranslatorTranslationDefaultKey.CLIENT_SCOPES]: 'client scopes', [TranslatorTranslationDefaultKey.DISPLAY_NAME]: 'display name', [TranslatorTranslationDefaultKey.EMAIL]: 'email', [Translator