{"version":3,"file":"PublicAuthPrompt-7_GNN76e.mjs","sources":["../../lib/utils/guestNameValidity.ts","../../lib/components/PublicAuthPrompt.vue"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { InvalidFilenameError, InvalidFilenameErrorReason, validateFilename } from '@nextcloud/files'\nimport { t } from '../utils/l10n.ts'\n\n/**\n * Get the validity of a filename (empty if valid).\n * This can be used for `setCustomValidity` on input elements\n *\n * @param name The filename\n */\nexport function getGuestNameValidity(name: string): string {\n\tif (name.trim() === '') {\n\t\treturn t('Names must not be empty.')\n\t}\n\n\tif (name.startsWith('.')) {\n\t\treturn t('Names must not start with a dot.')\n\t}\n\n\tif (name.length > 64) {\n\t\treturn t('Names may be at most 64 characters long.')\n\t}\n\n\ttry {\n\t\tvalidateFilename(name)\n\t\treturn ''\n\t} catch (error) {\n\t\tif (!(error instanceof InvalidFilenameError)) {\n\t\t\tthrow error\n\t\t}\n\n\t\tswitch (error.reason) {\n\t\t\tcase InvalidFilenameErrorReason.Character:\n\t\t\t\treturn t('\"{char}\" is not allowed inside a name.', { char: error.segment })\n\t\t\tcase InvalidFilenameErrorReason.ReservedName:\n\t\t\t\treturn t('\"{segment}\" is a reserved name and not allowed.', { segment: error.segment })\n\t\t\tcase InvalidFilenameErrorReason.Extension:\n\t\t\t\tif (error.segment.match(/\\.[a-z]/i)) {\n\t\t\t\t\treturn t('\"{extension}\" is not an allowed name.', { extension: error.segment })\n\t\t\t\t}\n\t\t\t\treturn t('Names must not end with \"{extension}\".', { extension: error.segment })\n\t\t\tdefault:\n\t\t\t\treturn t('Invalid name.')\n\t\t}\n\t}\n}\n","<!--\n  - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n  - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<script setup lang=\"ts\">\nimport { setGuestNickname } from '@nextcloud/auth'\nimport { getBuilder } from '@nextcloud/browser-storage'\nimport { computed, ref, useTemplateRef, watch } from 'vue'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport NcNoteCard from '@nextcloud/vue/components/NcNoteCard'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\nimport { showError } from '../toast.ts'\nimport { getGuestNameValidity } from '../utils/guestNameValidity.ts'\nimport { t } from '../utils/l10n.ts'\nimport { logger } from '../utils/logger.ts'\n\nexport interface PublicAuthPromptProps {\n\t/**\n\t * Preselected nickname.\n\t * No name preselected by default.\n\t */\n\tnickname?: string\n\n\t/**\n\t * Dialog title\n\t */\n\ttitle?: string\n\n\t/**\n\t * Dialog text under the dialog title.\n\t * e.g 'Enter your name to access the file'.\n\t * Not shown by default.\n\t */\n\ttext?: string\n\n\t/**\n\t * Dialog notice\n\t */\n\tnotice?: string\n\n\t/**\n\t * Dialog submit button label\n\t */\n\tsubmitLabel?: string\n\n\t/**\n\t * Whether the dialog is cancellable\n\t */\n\tcancellable?: boolean\n}\n\nconst props = withDefaults(defineProps<PublicAuthPromptProps>(), {\n\tnickname: '',\n\tnotice: '',\n\tsubmitLabel: t('Submit name'),\n\ttext: '',\n\ttitle: t('Guest identification'),\n})\n\nconst emit = defineEmits<{\n\tclose: [nickname?: string]\n}>()\n\nconst inputElement = useTemplateRef('input')\nconst storage = getBuilder('public').build()\n\nconst name = ref(props.nickname)\nwatch(() => props.nickname, () => {\n\t// Reset name to pre-selected nickname (e.g. Talk / Collabora)\n\tname.value = props.nickname\n})\n\nwatch(name, (newName) => {\n\t// Check validity of the new name\n\tconst validity = getGuestNameValidity(newName)\n\tif (!validity && inputElement.value) {\n\t\t// If the nickname is not valid, show an error\n\t\tsetCustomValidity(validity)\n\t\treturn\n\t}\n})\n\nconst buttons = computed(() => {\n\tconst cancelButton = {\n\t\tlabel: t('Cancel'),\n\t\tvariant: 'tertiary',\n\t\tcallback: () => emit('close'),\n\t} as const\n\n\tconst submitButton = {\n\t\tlabel: props.submitLabel,\n\t\ttype: 'submit',\n\t\tvariant: 'primary',\n\t} as const\n\n\t// If the dialog is cancellable, add a cancel button\n\tif (props.cancellable) {\n\t\treturn [cancelButton, submitButton]\n\t}\n\n\treturn [submitButton]\n})\n\nconst defaultNotice = computed(() => {\n\tif (props.notice) {\n\t\treturn props.notice\n\t}\n\n\t// If no notice is provided, use a default one\n\t// that changes based on the nickname definition\n\tif (name.value) {\n\t\treturn t('You are currently identified as {nickname}.', { nickname: name.value })\n\t}\n\n\treturn t('You are currently not identified.')\n})\n\n/**\n * Handle saving the nickname and return it.\n */\nfunction onSubmit() {\n\tconst nickname = name.value.trim()\n\n\tconst validity = getGuestNameValidity(nickname)\n\tif (validity) {\n\t\t// If the nickname is not valid, show an error\n\t\tsetCustomValidity(validity)\n\t\treturn\n\t}\n\n\tif (nickname === '') {\n\t\t// Show error if the nickname is empty\n\t\tsetCustomValidity(t('You cannot leave the name empty.'))\n\t\treturn\n\t}\n\n\tif (nickname.length < 2) {\n\t\t// Show error if the nickname is too short\n\t\tsetCustomValidity(t('Please enter a name with at least 2 characters.'))\n\t\treturn\n\t}\n\n\ttry {\n\t\t// Set the nickname\n\t\tsetGuestNickname(nickname)\n\t} catch (error) {\n\t\tlogger.error('Failed to set nickname', { error })\n\t\tshowError(t('Failed to set nickname.'))\n\t\tinputElement.value!.focus()\n\t\treturn\n\t}\n\n\t// Set the dialog as shown\n\tstorage.setItem('public-auth-prompt-shown', 'true')\n\n\t// Close the dialog\n\temit('close', name.value)\n}\n\n/**\n * Set custom validity message on the input\n *\n * @param message - The validity message\n */\nfunction setCustomValidity(message: string) {\n\tif (inputElement.value) {\n\t\t// @ts-expect-error -- not exposed by the library but exists (todo: fix in vue library)\n\t\tinputElement.value.setCustomValidity(message)\n\t\t// @ts-expect-error -- not exposed by the library but exists (todo: fix in vue library)\n\t\tinputElement.value.reportValidity()\n\t\tinputElement.value.focus()\n\t}\n}\n</script>\n\n<template>\n\t<NcDialog\n\t\t:buttons\n\t\tclass=\"public-auth-prompt\"\n\t\tdata-cy-public-auth-prompt-dialog\n\t\tisForm\n\t\tnoClose\n\t\t:name=\"title\"\n\t\t@submit=\"onSubmit\">\n\t\t<p v-if=\"text\" class=\"public-auth-prompt__text\">\n\t\t\t{{ text }}\n\t\t</p>\n\n\t\t<!-- Header -->\n\t\t<NcNoteCard\n\t\t\tclass=\"public-auth-prompt__header\"\n\t\t\t:text=\"defaultNotice\"\n\t\t\ttype=\"info\" />\n\n\t\t<!-- Form -->\n\t\t<NcTextField\n\t\t\tref=\"input\"\n\t\t\tv-model=\"name\"\n\t\t\tclass=\"public-auth-prompt__input\"\n\t\t\tdata-cy-public-auth-prompt-dialog-name\n\t\t\t:label=\"t('Name')\"\n\t\t\t:placeholder=\"t('Enter your name')\"\n\t\t\t:required=\"!cancellable\"\n\t\t\tminlength=\"2\"\n\t\t\tmaxlength=\"64\"\n\t\t\tname=\"name\" />\n\t</NcDialog>\n</template>\n\n<style scoped lang=\"scss\">\n.public-auth-prompt {\n\t&__text {\n\t\t// Smaller than dialog title\n\t\tfont-size: 1.25em;\n\t\tmargin-block: 0 calc(3 * var(--default-grid-baseline));\n\t}\n\n\t&__header {\n\t\tmargin-block: 0 calc(3 * var(--default-grid-baseline));\n\t\t// No extra top margin for the first child\n\t\t&:first-child {\n\t\t\tmargin-top: 0;\n\t\t}\n\t}\n\n\t&__input {\n\t\tmargin-block: calc(4 * var(--default-grid-baseline)) calc(2 * var(--default-grid-baseline));\n\t}\n}\n</style>\n"],"names":["_createBlock","_unref","_createElementBlock","_toDisplayString","_createVNode"],"mappings":"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"}