UNPKG

@nextcloud/auth

Version:

Nextcloud helpers related to authentication and the current user

1 lines 8.24 kB
{"version":3,"file":"index.mjs","sources":["../lib/requesttoken.ts","../lib/csp-nonce.ts","../lib/guest.ts","../lib/user.ts"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { subscribe } from '@nextcloud/event-bus'\n\nexport interface CsrfTokenObserver {\n\t(token: string): void\n}\n\nlet token: string | null | undefined\nconst observers: CsrfTokenObserver[] = []\n\n/**\n * Get current request token\n *\n * @return Current request token or null if not set\n */\nexport function getRequestToken(): string | null {\n\tif (token === undefined) {\n\t\t// Only on first load, try to get token from document\n\t\ttoken = document.head.dataset.requesttoken ?? null\n\t}\n\treturn token\n}\n\n/**\n * Add an observer which is called when the CSRF token changes\n *\n * @param observer The observer\n */\nexport function onRequestTokenUpdate(observer: CsrfTokenObserver): void {\n\tobservers.push(observer)\n}\n\n// Listen to server event and keep token in sync\nsubscribe('csrf-token-update', (e: unknown) => {\n\ttoken = (e as { token: string }).token\n\n\tobservers.forEach((observer) => {\n\t\ttry {\n\t\t\tobserver(token!)\n\t\t} catch (error) {\n\t\t\t// we cannot use the logger as the logger uses this library = circular dependency\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error('Error updating CSRF token observer', error)\n\t\t}\n\t})\n})\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { getRequestToken } from './requesttoken.ts'\n\n/**\n * Get the CSP nonce for script loading\n *\n * @return Current nonce if set\n * @example When using webpack this can be used to allow webpack to dynamically load additional modules:\n * ```js\n * import { getCSPNonce } from '@nextcloud/auth'\n *\n * __webpack_nonce__ = getCSPNonce()\n * ```\n */\nexport function getCSPNonce(): string | undefined {\n\tconst meta = document?.querySelector<HTMLMetaElement>('meta[name=\"csp-nonce\"]')\n\t// backwards compatibility with older Nextcloud versions\n\tif (!meta) {\n\t\tconst token = getRequestToken()\n\t\treturn token ? btoa(token) : undefined\n\t}\n\treturn meta.nonce\n}\n","/*!\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport type { NextcloudUser } from './user.ts'\n\nimport { getBuilder } from '@nextcloud/browser-storage'\nimport { emit, subscribe } from '@nextcloud/event-bus'\n\nconst browserStorage = getBuilder('public').persist().build()\n\nclass GuestUser implements NextcloudUser {\n\tprivate _displayName: string | null\n\treadonly uid: string\n\treadonly isAdmin: boolean\n\n\tconstructor() {\n\t\tif (!browserStorage.getItem('guestUid')) {\n\t\t\tbrowserStorage.setItem('guestUid', randomUUID())\n\t\t}\n\n\t\tthis._displayName = browserStorage.getItem('guestNickname') || ''\n\t\tthis.uid = browserStorage.getItem('guestUid') || randomUUID()\n\t\tthis.isAdmin = false\n\n\t\tsubscribe('user:info:changed', (guest) => {\n\t\t\tthis._displayName = guest.displayName\n\t\t\tbrowserStorage.setItem('guestNickname', guest.displayName || '')\n\t\t})\n\t}\n\n\tget displayName(): string | null {\n\t\treturn this._displayName\n\t}\n\n\tset displayName(displayName: string) {\n\t\tthis._displayName = displayName\n\t\tbrowserStorage.setItem('guestNickname', displayName)\n\t\temit('user:info:changed', this)\n\t}\n}\n\nlet currentUser: NextcloudUser | undefined\n\n/**\n * Get the currently Guest user or null if not logged in\n */\nexport function getGuestUser(): NextcloudUser {\n\tif (!currentUser) {\n\t\tcurrentUser = new GuestUser()\n\t}\n\n\treturn currentUser\n}\n\n/**\n * Get the guest nickname for public pages\n */\nexport function getGuestNickname(): string | null {\n\treturn getGuestUser()?.displayName || null\n}\n\n/**\n * Set the guest nickname for public pages\n *\n * @param nickname - The nickname to set\n */\nexport function setGuestNickname(nickname: string): void {\n\tif (!nickname || nickname.trim().length === 0) {\n\t\tthrow new Error('Nickname cannot be empty')\n\t}\n\n\tgetGuestUser().displayName = nickname\n}\n\n/**\n * Generate a random UUID (version 4) if the crypto API is not available.\n * If the crypto API is available, it uses the less secure `randomUUID` method.\n * Crypto API is available in modern browsers on secure contexts (HTTPS).\n *\n * @return A random UUID.\n */\nfunction randomUUID(): string {\n\t// Use the crypto API if available\n\tif (globalThis.crypto?.randomUUID) {\n\t\treturn globalThis.crypto.randomUUID()\n\t}\n\n\t// Generate a random UUID (version 4)\n\treturn 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n\t\tconst r = Math.random() * 16 | 0\n\t\tconst v = c === 'x' ? r : (r & 0x3 | 0x8)\n\t\treturn v.toString(16)\n\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nexport interface NextcloudUser {\n\tuid: string\n\tdisplayName: string | null\n\tisAdmin: boolean\n}\n\nlet currentUser: NextcloudUser | null | undefined\n\n/**\n * @param el - The element\n * @param attribute - The attribute to fetch\n */\nfunction getAttribute(el: HTMLHeadElement | undefined, attribute: string): string | null {\n\tif (el) {\n\t\treturn el.getAttribute(attribute)\n\t}\n\n\treturn null\n}\n\n/**\n * Get the currently logged in Nextcloud user or null if not logged in\n */\nexport function getCurrentUser(): NextcloudUser | null {\n\tif (currentUser !== undefined) {\n\t\treturn currentUser\n\t}\n\n\tconst head = document?.getElementsByTagName('head')[0]\n\tif (!head) {\n\t\treturn null\n\t}\n\n\t// No user logged in so cache and return null\n\tconst uid = getAttribute(head, 'data-user')\n\tif (uid === null) {\n\t\tcurrentUser = null\n\t\treturn currentUser\n\t}\n\n\tcurrentUser = {\n\t\tuid,\n\t\tdisplayName: getAttribute(head, 'data-user-displayname'),\n\t\tisAdmin: !!window._oc_isadmin,\n\t} as NextcloudUser\n\n\treturn currentUser\n}\n"],"names":["token","currentUser"],"mappings":"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"}