UNPKG

@authup/client-web-kit

Version:

This package contains vue components.

1 lines 772 kB
{"version":3,"file":"index.mjs","names":["_inject","sym","sym","storeToRefs","_useTranslation","_useTranslationsForBaseValidation","_useTranslationsForNestedValidations","isObject","buildPagination","_buildPagination","buildPagination","create","create","isObject","isObject","APolicySummary","APolicyInlineInfo","elements","AIdentityProviderOAuth2EndpointFields","AIdentityProviderPicker","components"],"sources":["../src/components/utility/form-input-list/AFormInputListItem.vue","../src/components/utility/form-input-list/AFormInputListItem.vue","../src/core/inject.ts","../src/core/provide.ts","../src/core/http-client/authentication-hook/singleton.ts","../src/core/store/constants.ts","../src/core/store/dispatcher/constants.ts","../../../node_modules/@posva/event-emitter/dist/index.js","../src/core/store/dispatcher/module.ts","../src/core/store/dispatcher/singleton.ts","../src/core/store/create.ts","../src/core/store/singleton.ts","../src/core/store/install.ts","../src/core/store/utils.ts","../src/core/http-client/authentication-hook/install.ts","../src/core/http-client/singleton.ts","../src/core/http-client/install.ts","../src/core/form/properties.ts","../src/core/translator/constants.ts","../src/core/translator/singleton.ts","../src/core/translator/helpers.ts","../src/core/translator/de/client.ts","../src/core/translator/de/default.ts","../src/core/vuelidate.ts","../src/core/translator/de/vuelidate.ts","../src/core/translator/de/vuecs.ts","../src/core/translator/en/client.ts","../src/core/translator/en/default.ts","../src/core/translator/en/vuelidate.ts","../src/core/translator/en/vuecs.ts","../src/core/translator/install.ts","../src/core/form/submit.ts","../src/core/query/sort.ts","../src/core/busy.ts","../src/core/permission-check/module.ts","../src/core/socket-manager/singleton.ts","../src/core/socket-manager/install.ts","../src/core/slot.ts","../src/components/utility/translation/ATranslation.ts","../src/components/utility/translation/ATranslationDefault.vue","../src/components/utility/translation/ATranslationDefault.vue","../src/components/utility/form-input-list/AFormInputList.vue","../src/components/utility/form-input-list/AFormInputList.vue","../src/components/utility/pagination/module.ts","../src/components/utility/pagination/APagination.ts","../src/components/utility/entity/collection/utils/component.ts","../src/components/utility/entity/collection/utils/options.ts","../src/components/utility/entity/collection/utils/handlers.ts","../src/utils/boolable-to-object.ts","../src/components/utility/entity/socket/module.ts","../src/components/utility/entity/collection/module.ts","../src/components/utility/entity/record/error.ts","../src/components/utility/entity/record/helpers.ts","../src/components/utility/entity/record/module.ts","../src/components/utility/toggle-button/AToggleButton.vue","../src/components/utility/toggle-button/AToggleButton.vue","../src/components/utility/toggle-button/module.ts","../src/components/utility/search/module.ts","../src/components/utility/search/ASearch.ts","../src/components/utility/entity/picker/module.ts","../src/components/utility/entity/AEntityDelete.ts","../src/components/utility/title/module.ts","../src/components/utility/title/ATitle.ts","../src/components/utility/LanguageSwitcherDropdown.ts","../src/components/utility/AFormSubmit.ts","../src/components/entities/client/AClient.ts","../src/components/entities/realm/ARealm.ts","../src/composables/is-editing.ts","../src/composables/on-change.ts","../src/composables/updated-at.ts","../src/composables/use-permission-check.ts","../src/components/entities/realm/ARealmForm.ts","../src/components/entities/realm/ARealms.ts","../src/components/entities/realm/ARealmPicker.ts","../src/components/entities/client/AClientForm.vue","../src/components/entities/client/AClientForm.vue","../src/components/entities/client/AClients.ts","../src/components/entities/client/AClientPicker.ts","../src/components/entities/permission/APermission.ts","../src/components/entities/permission/APermissionCheck.ts","../src/components/entities/permission/APermissionForm.ts","../src/components/entities/permission/APermissions.ts","../src/components/entities/policy/APolicies.ts","../src/components/entities/policy/APolicyTypeBadge.vue","../src/components/entities/policy/APolicyTypeBadge.vue","../src/components/entities/policy/APolicyDetailNav.vue","../src/components/entities/policy/APolicyDetailNav.vue","../src/components/entities/policy/APolicyInlineInfo.vue","../src/components/entities/policy/APolicyInlineInfo.vue","../src/components/entities/policy/APolicySummary.vue","../src/components/entities/policy/APolicySummary.vue","../src/components/entities/permission-policy-binding/APermissionPolicyBindingButton.ts","../src/components/entities/client-permission/AClientPermissionAssignment.vue","../src/components/entities/client-permission/AClientPermissionAssignment.vue","../src/components/entities/client-permission/AClientPermissionAssignments.vue","../src/components/entities/client-permission/AClientPermissionAssignments.vue","../src/components/entities/role/ARoleForm.ts","../src/components/entities/role/ARoles.ts","../src/components/entities/role/ARole.ts","../src/components/entities/client-role/AClientRoleAssignment.vue","../src/components/entities/client-role/AClientRoleAssignment.vue","../src/components/entities/client-role/AClientRoleAssignments.vue","../src/components/entities/client-role/AClientRoleAssignments.vue","../src/components/entities/client-scope/AClientScope.ts","../src/components/entities/client-scope/AClientScopes.ts","../src/components/entities/scope/AScopeForm.ts","../src/components/entities/scope/AScopes.ts","../src/components/entities/scope/AScope.ts","../src/components/entities/client-scope/AClientScopeAssignment.vue","../src/components/entities/client-scope/AClientScopeAssignment.vue","../src/components/entities/client-scope/AClientScopeAssignments.vue","../src/components/entities/client-scope/AClientScopeAssignments.vue","../src/components/entities/identity-provider/AIdentityProvider.ts","../src/components/entities/identity-provider/AIdentityProviderBasicFields.ts","../src/components/entities/identity-provider/AIdentityProviderLdapConnectionFields.ts","../src/components/entities/identity-provider/AIdentityProviderLdapCredentialsFields.ts","../src/components/entities/identity-provider/AIdentityProviderLdapGroupFields.ts","../src/components/entities/identity-provider/AIdentityProviderLdapUserFields.ts","../src/components/entities/identity-provider/protocol/utils.ts","../src/components/entities/identity-provider/AIdentityProviderProtocol.ts","../src/components/entities/identity-provider/AIdentityProviderLdapForm.ts","../src/components/entities/identity-provider/preset/utils.ts","../src/components/entities/identity-provider/AIdentityProviderPreset.ts","../src/components/entities/identity-provider/AIdentityProviderPicker.vue","../src/components/entities/identity-provider/AIdentityProviderPicker.vue","../src/components/entities/identity-provider/AIdentityProviderOAuth2ClientFields.ts","../src/components/entities/identity-provider/AIdentityProviderOAuth2Discovery.ts","../src/components/entities/identity-provider/AIdentityProviderOAuth2EndpointFields.vue","../src/components/entities/identity-provider/AIdentityProviderOAuth2EndpointFields.vue","../src/components/entities/identity-provider/AIdentityProviderOAuth2Form.ts","../src/components/entities/identity-provider/AIdentityProviderForm.ts","../src/components/entities/identity-provider/AIdentityProviders.ts","../src/components/entities/identity-provider/AIdentityProviderIcon.vue","../src/components/entities/identity-provider/AIdentityProviderIcon.vue","../src/components/entities/identity-provider-role/AIdentityProviderRoleAssignment.vue","../src/components/entities/identity-provider-role/AIdentityProviderRoleAssignment.vue","../src/components/entities/identity-provider-role/AIdentityProviderRoleAssignments.vue","../src/components/entities/identity-provider-role/AIdentityProviderRoleAssignments.vue","../src/components/entities/policy/attribute-names/AAttributeNamesPolicyForm.vue","../src/components/entities/policy/attribute-names/AAttributeNamesPolicyForm.vue","../src/components/entities/policy/APolicyParentAssignment.ts","../src/components/entities/policy/APolicyPicker.vue","../src/components/entities/policy/APolicyPicker.vue","../src/components/entities/policy/composite/ACompositePolicyForm.vue","../src/components/entities/policy/composite/ACompositePolicyForm.vue","../src/components/entities/policy/date/ADatePolicyForm.vue","../src/components/entities/policy/date/ADatePolicyForm.vue","../src/components/entities/policy/identity/AIdentityPolicyForm.vue","../src/components/entities/policy/identity/AIdentityPolicyForm.vue","../src/components/entities/policy/realm-match/ARealmMatchPolicyForm.vue","../src/components/entities/policy/realm-match/ARealmMatchPolicyForm.vue","../src/components/entities/policy/time/ATimePolicyForm.vue","../src/components/entities/policy/time/ATimePolicyForm.vue","../src/components/entities/policy/APolicy.ts","../src/components/entities/policy/APolicyTypePicker.vue","../src/components/entities/policy/APolicyTypePicker.vue","../src/components/entities/policy/APolicyBasicForm.vue","../src/components/entities/policy/APolicyBasicForm.vue","../src/components/entities/policy/APolicyForm.vue","../src/components/entities/policy/APolicyForm.vue","../src/components/entities/permission-client/APermissionClientAssignments.vue","../src/components/entities/permission-client/APermissionClientAssignments.vue","../src/components/entities/permission-policy/APermissionPolicyAssignment.vue","../src/components/entities/permission-policy/APermissionPolicyAssignment.vue","../src/components/entities/permission-policy/APermissionPolicyAssignments.vue","../src/components/entities/permission-policy/APermissionPolicyAssignments.vue","../src/components/entities/robot-permission/ARobotPermissionAssignment.vue","../src/components/entities/robot-permission/ARobotPermissionAssignment.vue","../src/components/entities/robot/ARobot.ts","../src/components/entities/robot/ARobotForm.ts","../src/components/entities/robot/ARobots.ts","../src/components/entities/permission-robot/APermissionRobotAssignments.vue","../src/components/entities/permission-robot/APermissionRobotAssignments.vue","../src/components/entities/role-permission/ARolePermissionAssignment.vue","../src/components/entities/role-permission/ARolePermissionAssignment.vue","../src/components/entities/role-permission/ARolePermissionAssignments.vue","../src/components/entities/role-permission/ARolePermissionAssignments.vue","../src/components/entities/permission-role/APermissionRoleAssignments.vue","../src/components/entities/permission-role/APermissionRoleAssignments.vue","../src/components/entities/user-permission/AUserPermissionAssignment.vue","../src/components/entities/user-permission/AUserPermissionAssignment.vue","../src/components/entities/user-permission/AUserPermissionAssignments.vue","../src/components/entities/user-permission/AUserPermissionAssignments.vue","../src/components/entities/user/AUser.ts","../src/components/entities/user/AUserForm.ts","../src/components/entities/user/AUsers.ts","../src/components/entities/user/AUserPasswordForm.ts","../src/components/entities/permission-user/APermissionUserAssignments.vue","../src/components/entities/permission-user/APermissionUserAssignments.vue","../src/components/entities/robot-permission/ARobotPermissionAssignments.vue","../src/components/entities/robot-permission/ARobotPermissionAssignments.vue","../src/components/entities/robot-role/ARobotRoleAssignment.vue","../src/components/entities/robot-role/ARobotRoleAssignment.vue","../src/components/entities/robot-role/ARobotRoleAssignments.vue","../src/components/entities/robot-role/ARobotRoleAssignments.vue","../src/components/entities/role-client/ARoleClientAssignments.vue","../src/components/entities/role-client/ARoleClientAssignments.vue","../src/components/entities/role-robot/ARoleRobotAssignments.vue","../src/components/entities/role-robot/ARoleRobotAssignments.vue","../src/components/entities/user-role/AUserRoleAssignment.vue","../src/components/entities/user-role/AUserRoleAssignment.vue","../src/components/entities/user-role/AUserRoleAssignments.vue","../src/components/entities/user-role/AUserRoleAssignments.vue","../src/components/entities/role-user/ARoleUserAssignments.vue","../src/components/entities/role-user/ARoleUserAssignments.vue","../src/components/entities/scope-client/AScopeClientAssignments.vue","../src/components/entities/scope-client/AScopeClientAssignments.vue","../src/components/entities/index.ts","../src/module.ts","../src/components/workflows/Login.vue","../src/components/workflows/Login.vue","../src/components/workflows/authorize/AuthorizeScope.vue","../src/components/workflows/authorize/AuthorizeScope.vue","../src/components/workflows/authorize/AuthorizeScopes.vue","../src/components/workflows/authorize/AuthorizeScopes.vue","../src/components/workflows/authorize/AuthorizeForm.vue","../src/components/workflows/authorize/AuthorizeForm.vue","../src/components/workflows/authorize/AuthorizeText.vue","../src/components/workflows/authorize/AuthorizeText.vue","../src/components/workflows/authorize/Authorize.vue","../src/components/workflows/authorize/Authorize.vue","../src/index.ts"],"sourcesContent":["/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n<script lang=\"ts\">\nimport { IVuelidate } from '@ilingo/vuelidate';\nimport { VCFormGroup, VCFormInput } from '@vuecs/form-controls';\nimport useVuelidate from '@vuelidate/core';\nimport { maxLength, minLength, required } from '@vuelidate/validators';\nimport { defineComponent, reactive } from 'vue';\n\nexport default defineComponent({\n components: {\n IVuelidate,\n VCFormInput,\n VCFormGroup, \n },\n props: {\n name: {\n type: String,\n default: undefined,\n },\n disabled: {\n type: Boolean,\n default: false,\n },\n },\n emits: ['updated', 'deleted'],\n setup(props, ctx) {\n const form = reactive({ name: props.name });\n\n const vuelidate = useVuelidate({\n name: {\n required,\n minLength: minLength(2),\n maxLength: maxLength(512),\n },\n }, form);\n\n const handleUpdated = () => {\n ctx.emit('updated', vuelidate.value.name.$model);\n };\n\n const handleDeleted = () => {\n ctx.emit('deleted');\n };\n\n return {\n handleUpdated,\n handleDeleted,\n vuelidate,\n };\n },\n});\n</script>\n<template>\n <IVuelidate :validation=\"vuelidate.name\">\n <template #default=\"props\">\n <VCFormGroup\n :validation-messages=\"props.data\"\n :validation-severity=\"props.severity\"\n >\n <VCFormInput\n v-model=\"vuelidate.name.$model\"\n @change=\"handleUpdated\"\n >\n <template #groupAppend>\n <button\n :disabled=\"disabled\"\n type=\"button\"\n class=\"btn btn-xs btn-warning\"\n @click.prevent=\"handleDeleted\"\n >\n <i class=\"fa fa-minus\" />\n </button>\n </template>\n </VCFormInput>\n </VCFormGroup>\n </template>\n </IVuelidate>\n</template>\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n<script lang=\"ts\">\nimport { IVuelidate } from '@ilingo/vuelidate';\nimport { VCFormGroup, VCFormInput } from '@vuecs/form-controls';\nimport useVuelidate from '@vuelidate/core';\nimport { maxLength, minLength, required } from '@vuelidate/validators';\nimport { defineComponent, reactive } from 'vue';\n\nexport default defineComponent({\n components: {\n IVuelidate,\n VCFormInput,\n VCFormGroup, \n },\n props: {\n name: {\n type: String,\n default: undefined,\n },\n disabled: {\n type: Boolean,\n default: false,\n },\n },\n emits: ['updated', 'deleted'],\n setup(props, ctx) {\n const form = reactive({ name: props.name });\n\n const vuelidate = useVuelidate({\n name: {\n required,\n minLength: minLength(2),\n maxLength: maxLength(512),\n },\n }, form);\n\n const handleUpdated = () => {\n ctx.emit('updated', vuelidate.value.name.$model);\n };\n\n const handleDeleted = () => {\n ctx.emit('deleted');\n };\n\n return {\n handleUpdated,\n handleDeleted,\n vuelidate,\n };\n },\n});\n</script>\n<template>\n <IVuelidate :validation=\"vuelidate.name\">\n <template #default=\"props\">\n <VCFormGroup\n :validation-messages=\"props.data\"\n :validation-severity=\"props.severity\"\n >\n <VCFormInput\n v-model=\"vuelidate.name.$model\"\n @change=\"handleUpdated\"\n >\n <template #groupAppend>\n <button\n :disabled=\"disabled\"\n type=\"button\"\n class=\"btn btn-xs btn-warning\"\n @click.prevent=\"handleDeleted\"\n >\n <i class=\"fa fa-minus\" />\n </button>\n </template>\n </VCFormInput>\n </VCFormGroup>\n </template>\n </IVuelidate>\n</template>\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { App } from 'vue';\nimport { inject as _inject, hasInjectionContext } from 'vue';\n\nexport function inject<T = any>(\n key: string | symbol,\n instance?: App,\n) : T | undefined {\n if (\n instance &&\n instance._context &&\n instance._context.provides &&\n instance._context.provides[key]\n ) {\n return instance._context.provides[key];\n }\n\n if (hasInjectionContext()) {\n return _inject(key, undefined);\n }\n\n return undefined;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { App } from 'vue';\nimport { provide as _provide } from 'vue';\nimport { inject } from './inject';\n\nexport function provide(\n key: string | symbol,\n value: unknown,\n app?: App,\n) {\n if (typeof app === 'undefined') {\n const val = inject(key);\n if (typeof val !== 'undefined') {\n return;\n }\n\n _provide(key, value);\n\n return;\n }\n\n if (\n app &&\n app._context &&\n app._context.provides &&\n app._context.provides[key]\n ) {\n return;\n }\n\n app.provide(key, value);\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { App } from 'vue';\nimport type { ClientAuthenticationHook } from '@authup/core-http-kit';\nimport { inject } from '../../inject';\nimport { provide } from '../../provide';\n\nconst sym = Symbol.for('AuthupHTTPClientAuthenticationHook');\n\nexport function injectHTTPClientAuthenticationHook(app?: App) : ClientAuthenticationHook {\n const instance = inject<ClientAuthenticationHook>(sym, app);\n if (!instance) {\n throw new Error('The http client authentication hook has not been injected in the app context.');\n }\n\n return instance;\n}\n\nexport function hasHTTPClientAuthenticationHook(app?: App) : boolean {\n try {\n return !!injectHTTPClientAuthenticationHook(app);\n } catch {\n return false;\n }\n}\n\nexport function provideHTTPClientAuthenticationHook(\n refresher: ClientAuthenticationHook,\n app?: App,\n) {\n provide(sym, refresher, app);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport const STORE_ID = 'authup';\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport enum StoreDispatcherEventName {\n LOGGING_IN = 'loggingIn',\n LOGGED_IN = 'loggedIn',\n\n LOGGING_OUT = 'loggingOut',\n LOGGED_OUT = 'loggedOut',\n\n RESOLVING = 'resolving',\n RESOLVED = 'resolved',\n\n ACCESS_TOKEN_UPDATED = 'accessTokenUpdated',\n ACCESS_TOKEN_EXPIRE_DATE_UPDATED = 'accessTokenExpireDateUpdated',\n\n REFRESH_TOKEN_UPDATED = 'refreshTokenUpdated',\n\n USER_UPDATED = 'userUpdated',\n\n REALM_UPDATED = 'realmUpdated',\n REALM_MANAGEMENT_UPDATED = 'realmManagementUpdated',\n}\n","// src/event-emitter.ts\nvar EventEmitter = class {\n /**\n * A Map of event names to registered handler functions.\n */\n all;\n constructor(all) {\n this.all = all || /* @__PURE__ */ new Map();\n }\n on(type, handler) {\n if (!this.all.has(type)) {\n this.all.set(type, []);\n }\n const handlers = this.all.get(type);\n handlers.push(handler);\n return () => handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n }\n off(type, handler) {\n if (!type) {\n return this.all.clear();\n }\n const handlers = this.all.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n this.all.delete(type);\n }\n }\n }\n /**\n * Invoke all handlers for the given type.\n * If present, `'*'` handlers are invoked after type-matched handlers.\n *\n * Note: Manually firing `'*'` handlers is not supported.\n *\n * @param type The event type to invoke\n * @param payload Any value to each handler\n */\n emit(type, ...payload) {\n let handlers = this.all.get(type);\n handlers?.slice().map((handler) => {\n handler(...payload);\n });\n handlers = this.all.get(\"*\");\n if (handlers) {\n handlers.slice().map((handler) => {\n handler(type, payload);\n });\n }\n }\n};\nexport {\n EventEmitter\n};\n//# sourceMappingURL=index.js.map","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { EventEmitter } from '@posva/event-emitter';\nimport type { StoreDispatcher, StoreDispatcherEvents } from './types';\n\nexport function createStoreDispatcher() : StoreDispatcher {\n return new EventEmitter<StoreDispatcherEvents>();\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { App } from 'vue';\nimport { inject } from '../../inject';\nimport { provide } from '../../provide';\nimport type { StoreDispatcher } from './types';\n\nconst sym = Symbol.for('AuthupStoreEventBus');\n\nexport function injectStoreDispatcher(app?: App) : StoreDispatcher {\n const instance = inject<StoreDispatcher>(sym, app);\n if (!instance) {\n throw new Error('The store dispatcher has not been injected in the app context.');\n }\n\n return instance;\n}\n\nexport function provideStoreDispatcher(eventBus: StoreDispatcher, app?: App) {\n provide(sym, eventBus, app);\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n PermissionEvaluator,\n PermissionMemoryProvider,\n PolicyEngine,\n} from '@authup/access';\nimport { OAuth2Error } from '@authup/specs';\nimport { computed, ref } from 'vue';\nimport type {\n OAuth2TokenGrantResponse,\n OAuth2TokenIntrospectionResponse,\n} from '@authup/specs';\nimport type {\n Realm,\n User,\n} from '@authup/core-kit';\nimport { REALM_MASTER_NAME } from '@authup/core-kit';\nimport { Client } from '@authup/core-http-kit';\nimport { StoreDispatcherEventName } from './dispatcher';\nimport type { StoreCreateContext, StoreLoginContext } from './types';\n\ntype InputFn = (...args: any[]) => Promise<any>;\ntype OutputFn<F extends InputFn> = (...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>;\n\nfunction createPromiseShareWrapperFn<F extends InputFn>(\n fn: F,\n) : OutputFn<F> {\n let promise : Promise<Awaited<ReturnType<F>>> | undefined;\n\n return (...args: Parameters<F>) => {\n if (promise) {\n return promise;\n }\n\n promise = new Promise<Awaited<ReturnType<F>>>(\n (resolve, reject) => {\n fn(...args)\n .then((r) => resolve(r))\n .catch((e) => reject(e));\n },\n );\n\n promise.finally(() => {\n setTimeout(() => {\n promise = undefined;\n }, 0);\n });\n\n return promise;\n };\n}\n\ntype RealmMinimal = Pick<Realm, 'id' | 'name'>;\n\nexport function createStore(context: StoreCreateContext) {\n const client = new Client({ baseURL: context.baseURL });\n\n const cookiesRead = ref<boolean>(false);\n const setCookiesRead = (value: boolean) => {\n cookiesRead.value = value;\n };\n\n // --------------------------------------------------------------------\n\n const accessToken = ref<string | null>(null);\n const setAccessToken = (input: string | null) => {\n accessToken.value = input;\n\n context.dispatcher.emit(\n StoreDispatcherEventName.ACCESS_TOKEN_UPDATED,\n input,\n );\n };\n\n // --------------------------------------------------------------------\n\n const accessTokenExpireDate = ref<Date | null>(null);\n const setAccessTokenExpireDate = (input: Date | number | string | null) => {\n if (typeof input === 'number' || typeof input === 'string') {\n accessTokenExpireDate.value = new Date(input); // verify microseconds or seconds\n } else {\n accessTokenExpireDate.value = input;\n }\n\n context.dispatcher.emit(\n StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED,\n accessTokenExpireDate.value,\n );\n };\n\n // --------------------------------------------------------------------\n\n const refreshToken = ref<string | null>(null);\n const setRefreshToken = (input: string | null) => {\n refreshToken.value = input;\n\n context.dispatcher.emit(\n StoreDispatcherEventName.REFRESH_TOKEN_UPDATED,\n input,\n );\n };\n\n // --------------------------------------------------------------------\n\n const user = ref<User | null>(null);\n const userId = computed<string | null>(() => (user.value ? user.value.id : null));\n\n const setUser = (input: User | null) => {\n user.value = input;\n\n context.dispatcher.emit(StoreDispatcherEventName.USER_UPDATED, input);\n };\n\n // --------------------------------------------------------------------\n\n const realm = ref<RealmMinimal | null>(null);\n const realmId = computed<string | undefined>(() => (realm.value ? realm.value.id : undefined));\n const realmName = computed<string | undefined>(() => (realm.value ? realm.value.name : undefined));\n const realmIsRoot = computed<boolean>(() => {\n if (realm.value) {\n return realm.value.name === REALM_MASTER_NAME;\n }\n\n return false;\n });\n\n const setRealm = (input: RealmMinimal | null) => {\n realm.value = input;\n\n context.dispatcher.emit(StoreDispatcherEventName.REALM_UPDATED, input);\n };\n\n const realmManagement = ref<RealmMinimal | null>(null);\n const realmManagementId = computed<string | undefined>(() => (realmManagement.value ? realmManagement.value.id : realmId.value));\n const realmManagementName = computed<string | undefined>(() => (realmManagement.value ? realmManagement.value.name : realmName.value));\n\n const setRealmManagement = (input: RealmMinimal | null) => {\n realmManagement.value = input;\n\n context.dispatcher.emit(StoreDispatcherEventName.REALM_MANAGEMENT_UPDATED, input);\n };\n\n // --------------------------------------------------------------------\n\n const permissionProvider = new PermissionMemoryProvider();\n const permissionEvaluator = new PermissionEvaluator({\n provider: permissionProvider,\n policyEngine: new PolicyEngine(),\n });\n\n // --------------------------------------------------------------------\n\n const cleanup = async () => {\n const tempAccessToken = accessToken.value;\n const tempRefreshToken = refreshToken.value;\n\n setAccessToken(null);\n setAccessTokenExpireDate(null);\n setRefreshToken(null);\n setUser(null);\n setRealm(null);\n setRealmManagement(null);\n\n permissionProvider.setMany([]);\n\n tokenResolved.value = false;\n userResolved.value = false;\n\n try {\n if (tempAccessToken) {\n await client.token.revoke({ token: tempAccessToken });\n }\n } catch {\n // ...\n }\n\n try {\n if (tempRefreshToken) {\n await client.token.revoke({ token: tempRefreshToken });\n }\n } catch {\n // ...\n }\n };\n\n // --------------------------------------------------------------------\n\n const userResolved = ref(false);\n const resolveUser = async () : Promise<void> => {\n if (!accessToken.value || userResolved.value) {\n return Promise.resolve();\n }\n\n userResolved.value = true;\n\n return client.userInfo.get<User>(`Bearer ${accessToken.value}`)\n .then((response) => {\n setUser(response);\n });\n };\n\n // --------------------------------------------------------------------\n\n const tokenResolved = ref(false);\n const resolveToken = async () : Promise<void> => {\n if (!accessToken.value || tokenResolved.value) {\n return Promise.resolve();\n }\n\n tokenResolved.value = true;\n\n return client.token.introspect<OAuth2TokenIntrospectionResponse>({ token: accessToken.value }, {\n authorizationHeader: {\n type: 'Bearer',\n token: accessToken.value,\n },\n })\n .then((response) => {\n if (response.exp) {\n const expireDate = new Date(response.exp * 1000);\n setAccessTokenExpireDate(expireDate);\n }\n\n if (\n response.realm_id &&\n response.realm_name\n ) {\n realm.value = {\n id: response.realm_id,\n name: response.realm_name,\n };\n\n if (!realmManagement.value) {\n setRealmManagement(realm.value);\n }\n }\n\n if (response.permissions) {\n permissionProvider.setMany(response.permissions.map((permission) => ({\n permission: {\n name: permission.name,\n realm_id: permission.realm_id,\n client_id: permission.client_id,\n },\n })));\n }\n });\n };\n\n // --------------------------------------------------------------------\n\n const applyTokenGrantResponse = (\n response: OAuth2TokenGrantResponse,\n ) => {\n const expireDate = new Date(Date.now() + response.expires_in * 1000);\n\n setAccessTokenExpireDate(expireDate);\n setAccessToken(response.access_token);\n\n if (response.refresh_token) {\n setRefreshToken(response.refresh_token);\n } else {\n setRefreshToken(null);\n }\n };\n\n // --------------------------------------------------------------------\n\n const refreshSession = createPromiseShareWrapperFn(\n async (): Promise<void> => {\n if (!refreshToken.value) {\n throw new OAuth2Error('The access token can not be renewed.');\n }\n\n try {\n const response = await client.token.createWithRefreshToken({ refresh_token: refreshToken.value });\n\n applyTokenGrantResponse(response);\n } catch (e) {\n await cleanup();\n\n throw e;\n } finally {\n tokenResolved.value = false;\n userResolved.value = false;\n }\n },\n );\n\n // --------------------------------------------------------------------\n\n // todo: rename to reload() ?\n const resolveInternal = async () : Promise<void> => {\n context.dispatcher.emit(StoreDispatcherEventName.RESOLVING);\n\n try {\n if (\n !accessToken.value &&\n refreshToken.value\n ) {\n await refreshSession();\n }\n\n if (accessToken.value) {\n await resolveToken();\n\n if (!user.value) {\n await resolveUser();\n }\n }\n } catch (e) {\n if (refreshToken.value) {\n await refreshSession();\n await resolveToken();\n await resolveUser();\n } else {\n throw e;\n }\n }\n\n context.dispatcher.emit(StoreDispatcherEventName.RESOLVED);\n };\n\n const resolve = createPromiseShareWrapperFn(resolveInternal);\n\n const loggedIn = computed<boolean>(() => !!accessToken.value);\n const login = async (ctx: StoreLoginContext) => {\n context.dispatcher.emit(StoreDispatcherEventName.LOGGING_IN);\n\n const response = await client.token.createWithPassword({\n username: ctx.name,\n password: ctx.password,\n ...(realmId.value ? { realm_id: ctx.realmId } : {}),\n });\n\n applyTokenGrantResponse(response);\n\n await resolveToken();\n await resolveUser();\n\n context.dispatcher.emit(StoreDispatcherEventName.LOGGED_IN);\n };\n\n const exchangeAuthorizationCode = async (code: string) => {\n const response = await client.token.createWithAuthorizationCode({ code });\n\n await cleanup();\n\n applyTokenGrantResponse(response);\n\n await resolveToken();\n await resolveUser();\n };\n\n const logout = async () => {\n context.dispatcher.emit(StoreDispatcherEventName.LOGGING_OUT);\n\n await cleanup();\n\n context.dispatcher.emit(StoreDispatcherEventName.LOGGED_OUT);\n };\n\n return {\n cookiesRead,\n setCookiesRead,\n\n permissionEvaluator,\n\n login,\n logout,\n loggedIn,\n resolve,\n exchangeAuthorizationCode,\n\n applyTokenGrantResponse,\n accessToken,\n setAccessToken,\n accessTokenExpireDate,\n setAccessTokenExpireDate,\n refreshToken,\n setRefreshToken,\n\n realm,\n realmId,\n realmIsRoot,\n realmName,\n setRealm,\n\n realmManagement,\n realmManagementId,\n realmManagementName,\n setRealmManagement,\n\n user,\n userId,\n setUser,\n };\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Pinia } from 'pinia';\nimport type { App } from 'vue';\nimport { inject } from '../inject';\nimport { provide } from '../provide';\nimport type { Store, StoreDefinition } from './types';\n\nconst sym = Symbol.for('AuthupStore');\n\nexport function injectStore(pinia?: Pinia, app?: App) : Store {\n const instance = injectStoreFactory(app);\n if (!instance) {\n throw new Error('The store has not been injected in the app context.');\n }\n\n return instance(pinia);\n}\n\nexport function injectStoreFactory(app?: App) : StoreDefinition {\n const instance = inject<StoreDefinition>(sym, app);\n if (!instance) {\n throw new Error('The store factory has not been injected in the app context.');\n }\n\n return instance;\n}\n\nexport function hasStoreFactory(app?: App) : boolean {\n return !!inject(sym, app);\n}\n\nexport function provideStoreFactory(store: StoreDefinition, app?: App) {\n provide(sym, store, app);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { CookieName } from '@authup/core-http-kit';\nimport { useCookies } from '@vueuse/integrations/useCookies';\nimport { defineStore } from 'pinia';\nimport type { App } from 'vue';\nimport type {\n CookieGetFn, \n CookieOptions, \n CookieSetFn, \n CookieUnsetFn,\n} from '../../types';\nimport { STORE_ID } from './constants';\nimport { createStore } from './create';\nimport { StoreDispatcherEventName, createStoreDispatcher, provideStoreDispatcher } from './dispatcher';\nimport { hasStoreFactory, provideStoreFactory } from './singleton';\nimport type { StoreInstallOptions } from './types';\n\nexport function installStore(app: App, options: StoreInstallOptions = {}) {\n if (hasStoreFactory(app)) {\n return;\n }\n\n const storeDispatcher = createStoreDispatcher();\n provideStoreDispatcher(storeDispatcher, app);\n\n const storeFactory = defineStore(\n STORE_ID,\n () => createStore({\n baseURL: options.baseURL,\n dispatcher: storeDispatcher,\n }),\n );\n const store = storeFactory(options.pinia);\n\n let cookieGet : CookieGetFn;\n if (options.cookieGet) {\n cookieGet = options.cookieGet;\n } else {\n const cookies = useCookies();\n cookieGet = cookies.get;\n }\n\n let cookieSet: CookieSetFn;\n if (options.cookieSet) {\n cookieSet = options.cookieSet;\n } else {\n const cookies = useCookies();\n cookieSet = cookies.set;\n }\n\n let cookieUnset : CookieUnsetFn;\n if (options.cookieUnset) {\n cookieUnset = options.cookieUnset;\n } else if (options.cookieSet) {\n cookieUnset = (key: string, opts: CookieOptions) => {\n (options.cookieSet as CookieSetFn)(key, null, opts);\n };\n } else {\n const cookies = useCookies();\n cookieUnset = cookies.remove;\n }\n\n const readCookies = () => {\n if (store.cookiesRead) {\n return;\n }\n\n store.setCookiesRead(true);\n\n const keys = Object.values(CookieName);\n\n let value : any;\n for (const key of keys) {\n value = cookieGet(key);\n if (!value) {\n continue;\n }\n\n switch (key) {\n case CookieName.ACCESS_TOKEN:\n if (!store.accessToken) {\n store.setAccessToken(value);\n }\n break;\n case CookieName.ACCESS_TOKEN_EXPIRE_DATE:\n if (!store.accessTokenExpireDate) {\n store.setAccessTokenExpireDate(value);\n }\n break;\n case CookieName.REFRESH_TOKEN:\n if (!store.refreshToken) {\n store.setRefreshToken(value);\n }\n break;\n case CookieName.USER:\n if (!store.user) {\n store.setUser(value);\n }\n break;\n case CookieName.REALM:\n if (!store.realm) {\n store.setRealm(value);\n }\n break;\n case CookieName.REALM_MANAGEMENT:\n if (!store.realmManagement) {\n store.setRealmManagement(value);\n }\n break;\n }\n }\n };\n\n const maxAgeFn = () => {\n if (!store.accessTokenExpireDate) {\n return undefined;\n }\n\n return Math.floor(\n Math.max(1000, new Date(`${store.accessTokenExpireDate}`).getTime() - Date.now()) /\n 1000,\n );\n };\n\n storeDispatcher.on(\n StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED,\n (input) => {\n if (input) {\n cookieSet(CookieName.ACCESS_TOKEN_EXPIRE_DATE, input, { maxAge: maxAgeFn() });\n } else {\n cookieUnset(CookieName.ACCESS_TOKEN_EXPIRE_DATE, {});\n }\n },\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.ACCESS_TOKEN_UPDATED,\n (input) => {\n if (input) {\n const maxAge = maxAgeFn();\n cookieSet(CookieName.ACCESS_TOKEN, input, { maxAge });\n } else {\n cookieUnset(CookieName.ACCESS_TOKEN, {});\n }\n },\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.REFRESH_TOKEN_UPDATED,\n (input) => {\n if (input) {\n cookieSet(CookieName.REFRESH_TOKEN, input, {});\n } else {\n cookieUnset(CookieName.REFRESH_TOKEN, {});\n }\n },\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.USER_UPDATED,\n (input) => {\n if (input) {\n cookieSet(CookieName.USER, input, {});\n } else {\n cookieUnset(CookieName.USER, {});\n }\n },\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.REALM_UPDATED,\n (input) => {\n if (input) {\n cookieSet(CookieName.REALM, input, {});\n } else {\n cookieUnset(CookieName.REALM, {});\n }\n },\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.REALM_MANAGEMENT_UPDATED,\n (input) => {\n if (input) {\n cookieSet(CookieName.REALM_MANAGEMENT, input, {});\n } else {\n cookieUnset(CookieName.REALM_MANAGEMENT, {});\n }\n },\n );\n\n readCookies();\n\n provideStoreFactory(storeFactory, app);\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { StoreGeneric, storeToRefs as _storeToRefs } from 'pinia';\nimport {\n isReactive, \n isRef, \n toRaw, \n toRef,\n} from 'vue';\n\nexport type StoreToRefs<T extends StoreGeneric> = ReturnType<typeof _storeToRefs<T>>;\n\nexport function storeToRefs<SS extends StoreGeneric>(\n store: SS,\n): StoreToRefs<SS> {\n store = toRaw(store);\n\n const refs = {} as StoreToRefs<SS>;\n const keys = Object.keys(store);\n for (const key of keys) {\n const value = store[key];\n if (isRef(value) || isReactive(value)) {\n refs[key as (keyof StoreToRefs<SS>)] = toRef(store, key) as any;\n }\n }\n\n return refs;\n}\n","/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { Client, ClientAuthenticationHook, ClientAuthenticationHookEventName } from '@authup/core-http-kit';\nimport type { App } from 'vue';\nimport { storeToRefs } from 'pinia';\nimport { hasHTTPClientAuthenticationHook, provideHTTPClientAuthenticationHook } from './singleton';\nimport { StoreDispatcherEventName, injectStoreDispatcher, injectStoreFactory } from '../../store';\nimport type { HTTPClientAuthenticationHookInstallOptions } from './types';\n\nexport function installHTTPClientAuthenticationHook(\n app: App,\n options: HTTPClientAuthenticationHookInstallOptions = {},\n) {\n if (hasHTTPClientAuthenticationHook(app)) {\n return;\n }\n\n const storeFactory = injectStoreFactory(app);\n const store = storeFactory(options.pinia);\n\n const { refreshToken } = storeToRefs(store);\n\n const hook = new ClientAuthenticationHook({\n baseURL: options.baseURL,\n tokenCreator: () => {\n if (!refreshToken.value) {\n throw new Error('No refresh token available.');\n }\n\n const client = new Client({ baseURL: options.baseURL });\n return client.token.createWithRefreshToken({ refresh_token: refreshToken.value });\n },\n timer: !options.isServer,\n });\n\n hook.on(ClientAuthenticationHookEventName.REFRESH_FINISHED, (response) => {\n store.applyTokenGrantResponse(response);\n });\n\n let isSelfCallee = false;\n\n hook.on(ClientAuthenticationHookEventName.HEADER_UNSET, () => {\n if (!isSelfCallee) {\n Promise.resolve()\n .then(() => store.logout());\n }\n });\n\n const storeDispatcher = injectStoreDispatcher(app);\n\n const handleAccessTokenEvent = () => {\n isSelfCallee = true;\n\n if (store.accessToken) {\n hook.enable();\n hook.setAuthorizationHeader({\n type: 'Bearer',\n token: store.accessToken as string,\n });\n } else {\n hook.disable();\n hook.unsetAuthorizationHeader();\n }\n\n isSelfCallee = false;\n };\n\n const handleAccessTokenExpireDateEvent = () => {\n if (store.accessTokenExpireDate) {\n const expiresIn = Math.floor((store.accessTokenExpireDate.getTime() - Date.now()) / 1000);\n hook.setTimer(expiresIn);\n }\n };\n\n storeDispatcher.on(\n StoreDispatcherEventName.ACCESS_TOKEN_UPDATED,\n () => handleAccessTokenEvent(),\n );\n\n storeDispatcher.on(\n StoreDispatcherEventName.ACCESS_TOKEN_EXPIRE_DATE_UPDATED,\n () => handleAccessTokenExpireDateEvent(),\n );\n\n handleAccessTokenEvent();\n handleAccessTokenExpireDateEvent();\n\n provideHTTPClientAuthenticationHook(hook, app);\n}\n","/*\n * Copyright (c) 2022-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Client } from '@authup/core-http-kit';\nimport type { App } from 'vue';\nimport { inject } from '../inject';\nimport { provide } from '../provide';\n\nexport const HTTPClientSymbol = Symbol.for('AuthupHTTPClient');\n\nexport function provideHTTPClient(client: Client, app?: App) {\n provide(HTTPClientSymbol, client, app);\n}\n\nexport function hasHTTPClient(app?: App) : boolean {\n try {\n return !!injectHTTPClient(app);\n } catch {\n return false;\n }\n}\n\nexport function injectHTTPClient(app?: App) {\n const instance = inject<Client>(HTTPClientSymbol, app);\n if (!instance) {\n throw new Error('The api client has not been injected.');\n }\n\n return instance;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { Client } from '@authup/core-http-kit';\nimport type { App } from 'vue';\nimport { hasHTTPClient, provideHTTPClient } from './singleton';\nimport type { HTTPClientInstallOptions } from './types';\nimport { injectHTTPClientAuthenticationHook } from './authentication-hook';\n\nexport function installHTTPClient(app: App, options: HTTPClientInstallOptions = {}) {\n if (hasHTTPClient(app)) {\n return;\n }\n\n const client = new Client({ baseURL: options.baseURL });\n\n const authenticationHook = injectHTTPClientAuthenticationHook(app);\n authenticationHook.attach(client);\n\n provideHTTPClient(client, app);\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license in