{"version":3,"file":"lockout-CdntU-Zp.js","sources":["../../../../authui/src/copy.ts","../../../../authui/src/passwordVisibility.ts","../../../../authui/src/clickToSwitch.ts","../../../../authui/src/preventDoubleTap.ts","../../../../authui/src/accountdeletion.ts","../../../../authui/src/resendButton.ts","../../../../authui/src/messageBar.ts","../../../../authui/src/loading.ts","../../../../authui/src/imagepicker.ts","../../../../authui/src/retry.ts","../../../../authui/src/authflow_websocket.ts","../../../../authui/src/authflow_polling.ts","../../../../authui/src/feature.ts","../../../../authui/src/form.ts","../../../../authui/src/base64.ts","../../../../authui/src/base64url.ts","../../../../authui/src/authflowv2/alert-message.ts","../../../../authui/src/passkey.ts","../../../../authui/src/lockout.ts"],"sourcesContent":["import { Controller } from \"@hotwired/stimulus\";\n\nfunction copyToClipboard(str: string): void {\n const el = document.createElement(\"textarea\");\n el.value = str;\n // Set non-editable to avoid focus and move outside of view\n el.setAttribute(\"readonly\", \"\");\n el.setAttribute(\"style\", \"position: absolute; left: -9999px\");\n document.body.appendChild(el);\n // Select text inside element\n el.select();\n el.setSelectionRange(0, el.value.length); // for mobile device\n document.execCommand(\"copy\");\n // Remove temporary element\n document.body.removeChild(el);\n}\n\nexport class CopyButtonController extends Controller {\n static values = {\n source: String,\n copyLabel: String,\n copiedLabel: String,\n };\n\n declare sourceValue: string;\n declare copyLabelValue: string;\n declare copiedLabelValue: string;\n declare hasCopyLabelValue: boolean;\n declare hasCopiedLabelValue: boolean;\n declare timeoutHandle: number | null;\n\n copy(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n\n const button = this.element as HTMLButtonElement;\n\n const copyLabel = this.copyLabelValue;\n const copiedLabel = this.copiedLabelValue;\n\n const target = document.querySelector(this.sourceValue);\n if (target == null) {\n return;\n }\n\n const textContent = target.textContent;\n if (textContent == null) {\n return;\n }\n\n copyToClipboard(textContent);\n\n // Show feedback\n let currentHandle = this.timeoutHandle;\n // Clear scheduled timeout if the timeout function has NOT been executed yet.\n if (currentHandle != null) {\n window.clearTimeout(currentHandle);\n this.timeoutHandle = null;\n }\n // Changing label as feedback is optional\n if (this.hasCopyLabelValue && this.hasCopiedLabelValue) {\n button.textContent = copiedLabel;\n }\n button.classList.add(\"outline\");\n const newHandle = window.setTimeout(() => {\n // Changing label as feedback is optional\n if (this.hasCopyLabelValue && this.hasCopiedLabelValue) {\n button.textContent = copyLabel;\n }\n button.classList.remove(\"outline\");\n this.timeoutHandle = null;\n }, 1000);\n this.timeoutHandle = newHandle;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport class PasswordVisibilityToggleController extends Controller {\n static targets = [\"input\", \"showButton\", \"hideButton\"];\n\n declare inputTarget: HTMLInputElement;\n declare showButtonTarget: HTMLButtonElement;\n declare hideButtonTarget: HTMLButtonElement;\n\n connect() {\n this.inputTarget.type = \"password\";\n this.showButtonTarget.classList.remove(\"hidden\");\n this.hideButtonTarget.classList.add(\"hidden\");\n }\n\n show(e: Event) {\n e.preventDefault();\n e.stopImmediatePropagation();\n\n this.inputTarget.type = \"text\";\n this.showButtonTarget.classList.add(\"hidden\");\n this.hideButtonTarget.classList.remove(\"hidden\");\n }\n\n hide(e: Event) {\n e.preventDefault();\n e.stopImmediatePropagation();\n\n this.inputTarget.type = \"password\";\n this.showButtonTarget.classList.remove(\"hidden\");\n this.hideButtonTarget.classList.add(\"hidden\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport class ClickToSwitchController extends Controller {\n static targets = [\"clickToShow\", \"clickToHide\"];\n\n declare clickToShowTarget: HTMLElement;\n declare clickToHideTarget: HTMLElement;\n\n click() {\n // Do not call prevent default intentionally.\n this.clickToHideTarget.classList.add(\"hidden\");\n this.clickToShowTarget.classList.remove(\"hidden\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n// Disable double tap zoom\n// There are rumours on the web claiming that touch-action: manipulation can do that.\n// However, I tried\n// * {\n// touch-action: manipulation;\n// }\n// and\n// * {\n// touch-action: pan-y;\n// }\n// None of them work.\nexport class PreventDoubleTapController extends Controller {\n action(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport class AccountDeletionController extends Controller {\n static targets = [\"input\", \"button\"];\n\n declare inputTarget: HTMLInputElement;\n declare buttonTarget: HTMLButtonElement;\n\n delete() {\n const input = this.inputTarget;\n const button = this.buttonTarget;\n\n const inputText = input.value;\n button.disabled = inputText !== \"DELETE\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport class ResendButtonController extends Controller {\n static values = {\n cooldown: Number,\n label: String,\n labelUnit: String,\n };\n\n declare cooldownValue: number;\n declare labelValue: string;\n declare labelUnitValue: string;\n declare animHandle: number | null;\n\n connect() {\n const button = this.element as HTMLButtonElement;\n\n const scheduledAt = new Date();\n const cooldown = this.cooldownValue * 1000;\n const label = this.labelValue;\n const labelUnit = this.labelUnitValue;\n\n const tick = () => {\n const now = new Date();\n const timeElapsed = now.getTime() - scheduledAt.getTime();\n\n let displaySeconds = 0;\n if (timeElapsed <= cooldown) {\n displaySeconds = Math.round((cooldown - timeElapsed) / 1000);\n }\n\n if (displaySeconds === 0) {\n button.disabled = false;\n button.textContent = label;\n this.animHandle = null;\n } else {\n button.disabled = true;\n button.textContent = labelUnit.replace(\"%d\", String(displaySeconds));\n this.animHandle = requestAnimationFrame(tick);\n }\n };\n\n this.animHandle = requestAnimationFrame(tick);\n }\n\n disconnect() {\n if (this.animHandle != null) {\n cancelAnimationFrame(this.animHandle);\n this.animHandle = null;\n }\n }\n}\n","import { AxiosResponse } from \"axios\";\nimport { Controller } from \"@hotwired/stimulus\";\nimport { session } from \"@hotwired/turbo\";\n\nexport function handleAxiosError(e: unknown) {\n const err = e as any;\n if (err.code === \"ERR_NETWORK\") {\n showErrorMessage(\"error-message-network\");\n } else if (err.response != null) {\n const response: AxiosResponse = err.response;\n\n if (typeof response.data === \"string\") {\n session.renderStreamMessage(response.data);\n return;\n }\n\n showErrorMessage(\"error-message-server\");\n } else if (err.request != null) {\n showErrorMessage(\"error-message-network\");\n } else {\n // programming error\n }\n\n console.error(err);\n}\n\nexport function showErrorMessage(id: string) {\n setErrorMessage(id, false);\n}\n\nexport function hideErrorMessage(id: string) {\n setErrorMessage(id, true);\n}\n\nfunction setErrorMessage(id: string, hidden: boolean) {\n if (hidden) {\n const e = new CustomEvent(\"messagebar:hide-message\", {\n detail: {\n id,\n },\n });\n document.dispatchEvent(e);\n } else {\n const e = new CustomEvent(\"messagebar:show-message\", {\n detail: {\n id,\n },\n });\n document.dispatchEvent(e);\n }\n}\n\nexport class MessageBarController extends Controller {\n // Close the message bar before cache the page.\n // So that the cached page does not have the message bar shown.\n // See https://github.com/authgear/authgear-server/issues/1424\n beforeCache = () => {\n this.hide();\n };\n\n open = () => {\n const barTarget = this.element as HTMLElement;\n barTarget.classList.remove(\"hidden\");\n };\n\n hide = () => {\n const barTarget = this.element as HTMLElement;\n barTarget.classList.add(\"hidden\");\n };\n\n connect() {\n document.addEventListener(\"turbo:before-cache\", this.beforeCache);\n }\n\n close(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n\n this.hide();\n }\n\n disconnect() {\n document.removeEventListener(\"turbo:before-cache\", this.beforeCache);\n }\n\n showMessage(e: CustomEvent) {\n this.open();\n const id: string = e.detail.id;\n document.getElementById(id)?.classList?.remove(\"hidden\");\n }\n\n hideMessage(e: CustomEvent) {\n this.hide();\n const id: string = e.detail.id;\n document.getElementById(id)?.classList?.add(\"hidden\");\n }\n}\n","import { AxiosProgressEvent } from \"axios\";\n//\n// disableAllButtons remembers the disabled state of all buttons.\n// It disables all button and returns a function to revert to original state.\nexport function disableAllButtons(): () => void {\n const buttons = document.querySelectorAll(\"button\");\n const original: [HTMLButtonElement, boolean][] = [];\n for (let i = 0; i < buttons.length; i++) {\n const button = buttons[i];\n const disabled = button.disabled;\n const state: [HTMLButtonElement, boolean] = [button, disabled];\n button.disabled = true;\n original.push(state);\n }\n\n return () => {\n for (let i = 0; i < original.length; i++) {\n const [button, disabled] = original[i];\n button.disabled = disabled;\n }\n };\n}\n\nexport function hideProgressBar(): void {\n const loadingProgressBar = document.getElementById(\"loading-progress-bar\");\n if (loadingProgressBar == null) {\n return;\n }\n loadingProgressBar.style.opacity = \"0\";\n}\n\nexport function showProgressBar(): void {\n const loadingProgressBar = document.getElementById(\"loading-progress-bar\");\n if (loadingProgressBar == null) {\n return;\n }\n loadingProgressBar.style.opacity = \"1\";\n}\n\nexport function progressEventHandler(progressEvent: AxiosProgressEvent): void {\n const loadingProgressBar = document.getElementById(\"loading-progress-bar\");\n if (loadingProgressBar == null) {\n return;\n }\n\n if (progressEvent.total == null) {\n return;\n }\n\n const percentage = Math.round(\n (100 * progressEvent.loaded) / progressEvent.total\n );\n const width = Math.max(0, Math.min(100, percentage));\n loadingProgressBar.style.width = `${width}%`;\n}\n","import axios from \"axios\";\nimport Cropper from \"cropperjs\";\nimport { Controller } from \"@hotwired/stimulus\";\nimport {\n disableAllButtons,\n hideProgressBar,\n showProgressBar,\n progressEventHandler,\n} from \"./loading\";\nimport {\n handleAxiosError,\n showErrorMessage,\n hideErrorMessage,\n} from \"./messageBar\";\n\nfunction destroyCropper(img: HTMLImageElement) {\n // The namespace .cropper is known by reading the source code.\n // It could change anytime!\n const cropper = (img as any).cropper;\n if (cropper instanceof Cropper) {\n cropper.destroy();\n }\n}\n\nfunction initCropper(img: HTMLImageElement) {\n new Cropper(img, {\n // Make crop region not able to move outside the image.\n viewMode: 1,\n // We want to crop a square image.\n aspectRatio: 1,\n movable: false,\n rotatable: false,\n scalable: false,\n zoomable: false,\n zoomOnTouch: false,\n zoomOnWheel: false,\n });\n}\n\nfunction getCropper(img: HTMLImageElement): Cropper | undefined {\n const cropper = (img as any).cropper;\n return cropper;\n}\n\nexport class ImagePickerController extends Controller {\n static targets = [\n \"inputFile\",\n \"buttonFile\",\n \"buttonSave\",\n \"buttonRemove\",\n \"imgCropper\",\n \"imgPreview\",\n \"inputValue\",\n \"formUpload\",\n ];\n\n declare inputFileTarget: HTMLInputElement;\n declare buttonFileTarget: HTMLButtonElement;\n declare buttonSaveTarget: HTMLButtonElement;\n declare buttonRemoveTarget: HTMLButtonElement;\n declare imgCropperTarget: HTMLImageElement;\n declare imgPreviewTarget: HTMLButtonElement;\n declare inputValueTarget: HTMLInputElement;\n declare formUploadTarget: HTMLFormElement;\n\n onChange(e: Event) {\n const target = this.inputFileTarget;\n\n const file = target.files?.[0];\n if (file == null) {\n return;\n }\n\n const imgCropper = this.imgCropperTarget;\n\n hideErrorMessage(\"error-message-invalid-selected-image\");\n\n imgCropper.classList.remove(\"hidden\");\n const buttonFile = this.buttonFileTarget;\n buttonFile.classList.add(\"hidden\");\n const buttonRemove = this.buttonRemoveTarget;\n buttonRemove.classList.add(\"hidden\");\n const imgPreview = this.imgPreviewTarget;\n imgPreview.classList.add(\"hidden\");\n const buttonSave = this.buttonSaveTarget;\n buttonSave.classList.remove(\"hidden\");\n\n const reader = new FileReader();\n reader.addEventListener(\"load\", () => {\n if (typeof reader.result === \"string\") {\n imgCropper.src = reader.result;\n destroyCropper(imgCropper);\n initCropper(imgCropper);\n }\n });\n reader.readAsDataURL(file);\n }\n\n onError() {\n const target = this.imgCropperTarget;\n\n const src = target.src;\n // It is a file from the file system and it does not load.\n // It is probably the file is broken.\n if (/^data:/.test(src)) {\n const buttonFile = this.buttonFileTarget;\n buttonFile.classList.remove(\"hidden\");\n const buttonSave = this.buttonSaveTarget;\n buttonSave.classList.add(\"hidden\");\n showErrorMessage(\"error-message-invalid-selected-image\");\n }\n }\n\n onClickFile(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n\n const inputFile = this.inputFileTarget;\n inputFile.click();\n }\n\n onClickSave(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n\n const imgCropper = this.imgCropperTarget;\n\n const cropper = getCropper(imgCropper);\n if (cropper == null) {\n return;\n }\n\n const maxDimensions = 1024;\n const dimensionsOptions = (function () {\n const imageData = cropper.getImageData();\n const cropBoxData = cropper.getCropBoxData();\n // assume the cropped area is square\n if (\n imageData.naturalWidth > 0 &&\n imageData.width > 0 &&\n cropBoxData.width > 0\n ) {\n const imageScale = imageData.naturalWidth / imageData.width;\n const croppedImageWidth = Math.floor(cropBoxData.width * imageScale);\n const resultDimensions = Math.min(croppedImageWidth, maxDimensions);\n return {\n width: resultDimensions,\n height: resultDimensions,\n };\n }\n\n // last resort when any of the image or crop box data is unavailable\n return {\n maxWidth: maxDimensions,\n maxHeight: maxDimensions,\n };\n })();\n\n const canvas = cropper.getCroppedCanvas({\n ...dimensionsOptions,\n imageSmoothingQuality: \"high\",\n });\n canvas.toBlob(async (blob) => {\n if (blob == null) {\n return;\n }\n\n const inputValue = this.inputValueTarget;\n const formUpload = this.formUploadTarget;\n\n const revert = disableAllButtons();\n showProgressBar();\n try {\n const resp = await axios(\"/api/images/upload\", {\n method: \"POST\",\n headers: {\n Accept: \"text/vnd.turbo-stream.html, application/json\",\n },\n onDownloadProgress: progressEventHandler,\n onUploadProgress: progressEventHandler,\n });\n const body = resp.data;\n\n const {\n result: { upload_url },\n } = body;\n\n const formData = new FormData();\n formData.append(\"file\", blob);\n const uploadResp = await axios(upload_url, {\n method: \"POST\",\n data: formData,\n headers: {\n Accept: \"text/vnd.turbo-stream.html, application/json\",\n },\n onDownloadProgress: progressEventHandler,\n onUploadProgress: progressEventHandler,\n });\n const uploadRespBody = uploadResp.data;\n const {\n result: { url },\n } = uploadRespBody;\n\n inputValue.value = url;\n formUpload.submit();\n } catch (e) {\n // revert is only called for error branch because\n // The success branch also loads a new page.\n // Keeping the buttons in disabled state reduce flickering in the UI.\n revert();\n handleAxiosError(e);\n } finally {\n hideProgressBar();\n }\n });\n }\n}\n","export function exponential(index: number): number {\n return Math.pow(2, index) * 1000;\n}\n\nexport interface RetryOptions {\n // The default value is 2.\n // So the index would be 0, 1, and 2.\n maxIndex?: number;\n // The default is the exponential function\n indexToMillis?: (index: number) => number;\n\n // So by default, retry in 1, 2, and 4 seconds.\n\n abortController?: AbortController;\n}\n\nexport class RetryEventTarget extends EventTarget {\n options?: RetryOptions;\n index: number;\n handle: ReturnType | null;\n\n constructor(options?: RetryOptions) {\n super();\n this.options = options;\n this.index = 0;\n this.handle = null;\n\n this.options?.abortController?.signal?.addEventListener(\"abort\", () => {\n this._cancelSchedule();\n });\n }\n\n _cancelSchedule() {\n if (this.handle != null) {\n clearTimeout(this.handle);\n this.handle = null;\n }\n }\n\n _dispatchRetry() {\n this.dispatchEvent(new CustomEvent(\"retry\"));\n }\n\n scheduleRetry() {\n const maxIndex = this.options?.maxIndex ?? 2;\n const indexToMillis = this.options?.indexToMillis ?? exponential;\n\n const oldIndex = this.index;\n const newIndex = oldIndex < maxIndex ? oldIndex + 1 : maxIndex;\n this.index = newIndex;\n\n this._cancelSchedule();\n const delay = indexToMillis(oldIndex);\n this.handle = setTimeout(() => {\n this._dispatchRetry();\n }, delay);\n }\n\n markSuccess() {\n this.index = 0;\n this._cancelSchedule();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { visit } from \"@hotwired/turbo\";\nimport { RetryEventTarget } from \"./retry\";\n\nfunction refreshPage() {\n let url = window.location.pathname;\n if (window.location.search !== \"\") {\n url += window.location.search;\n }\n if (window.location.hash !== \"\") {\n url += window.location.hash;\n }\n visit(url, { action: \"replace\" });\n}\n\nexport class AuthflowWebsocketController extends Controller {\n static values = {\n url: String,\n };\n\n declare urlValue: string;\n\n ws: WebSocket | null = null;\n abortController: AbortController | null = null;\n retryEventTarget: RetryEventTarget | null = null;\n\n dispose = () => {\n if (this.ws != null) {\n this.ws.onclose = () => {};\n this.ws.close();\n }\n this.ws = null;\n };\n\n refreshIfNeeded = () => {\n refreshPage();\n };\n\n connectWebSocket = () => {\n const url = this.urlValue;\n\n this.ws = new WebSocket(url);\n\n this.ws.onopen = (e) => {\n console.info(\"authflow_websocket onopen\", e);\n this.retryEventTarget?.markSuccess();\n };\n\n this.ws.onclose = (e) => {\n console.info(\"authflow_websocket onclose\", e);\n // Close code 1000 means we do not need to reconnect.\n if (e.code === 1000) {\n return;\n }\n this.retryEventTarget?.scheduleRetry();\n };\n\n this.ws.onerror = (e) => {\n console.error(\"authflow_websocket onerror\", e);\n };\n\n this.ws.onmessage = (e) => {\n console.info(\"authflow_websocket onmessage\", e);\n const message = JSON.parse(e.data);\n switch (message.kind) {\n case \"refresh\":\n this.refreshIfNeeded();\n }\n };\n };\n\n connect() {\n this.abortController = new AbortController();\n this.retryEventTarget = new RetryEventTarget({\n abortController: this.abortController,\n });\n this.retryEventTarget.addEventListener(\"retry\", () => {\n this.dispose();\n this.connectWebSocket();\n });\n\n this.connectWebSocket();\n }\n\n disconnect() {\n this.dispose();\n\n if (this.abortController != null) {\n this.abortController.abort();\n }\n this.abortController = null;\n\n this.retryEventTarget = null;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { visit } from \"@hotwired/turbo\";\nimport axios from \"axios\";\n\nfunction refreshPage() {\n let url = window.location.pathname;\n if (window.location.search !== \"\") {\n url += window.location.search;\n }\n if (window.location.hash !== \"\") {\n url += window.location.hash;\n }\n visit(url, { action: \"replace\" });\n}\n\nconst TIMEOUT = 3000;\n\nexport class AuthflowPollingController extends Controller {\n static values = {\n statetoken: String,\n };\n\n declare statetokenValue: string;\n\n setTimeoutHandle: number | null = null;\n\n connect() {\n this.poll();\n }\n\n disconnect() {\n this.cancel();\n }\n\n poll() {\n let recur = true;\n\n this.setTimeoutHandle = window.setTimeout(async () => {\n try {\n const response = await axios(\"/api/v1/authentication_flows/states\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n data: {\n state_token: this.statetokenValue,\n },\n });\n console.info(\"authflow_polling poll success\");\n\n if (response.data?.result?.action?.data?.can_check === true) {\n recur = false;\n refreshPage();\n }\n } catch (e) {\n console.error(\"authflow_polling error\", e);\n } finally {\n if (recur) {\n this.poll();\n } else {\n this.cancel();\n }\n }\n }, TIMEOUT);\n }\n\n cancel() {\n if (this.setTimeoutHandle != null) {\n window.clearTimeout(this.setTimeoutHandle);\n }\n }\n}\n","export function intlDateTimeFormatIsSupported(): boolean {\n if (\"Intl\" in window && \"DateTimeFormat\" in Intl) {\n const testDate = new Date(\"2006-01-02T03:04:05Z\");\n const testFormat = new Intl.DateTimeFormat(\"en\", {\n dateStyle: \"long\",\n timeStyle: \"long\",\n timeZone: \"UTC\",\n } as any);\n const actual = testFormat.format(testDate);\n const expected = \"January 2, 2006 at 3:04:05 AM UTC\";\n return actual === expected;\n }\n return false;\n}\n\nexport function intlRelativeTimeFormatIsSupported(): boolean {\n if (\"Intl\" in window && \"RelativeTimeFormat\" in Intl) {\n return true;\n }\n return false;\n}\n","import { visit, clearCache } from \"@hotwired/turbo\";\nimport { Controller } from \"@hotwired/stimulus\";\nimport axios, { Method } from \"axios\";\nimport {\n disableAllButtons,\n hideProgressBar,\n showProgressBar,\n progressEventHandler,\n} from \"./loading\";\nimport { handleAxiosError } from \"./messageBar\";\n\n// Turbo has builtin support for form submission.\n// We once migrated to use it.\n// However, redirect to external is broken because\n// the redirect is made with fetch, which is subject to CORS.\n// A typical problem is the support for the post login redirect URI.\n// The post login redirect URI is usually an external link that\n// the origin of the link does not list our origin as allowed origin.\n// If we rely on Turbo to handle form submission,\n// the post login redirect URI will be broken.\n// Therefore, we reverted to handle form submission ourselves.\n// To disable the builtin form submission of Turbo,\n// I studied its source code and discovered that\n// Turbo checked in the bubble event listener to see if\n// the event is prevented.\n// So I added a capture event listener to call preventDefault()\n// to stop Turbo from submitting forms.\n//\n// See https://github.com/authgear/authgear-server/issues/2333\nexport class XHRSubmitFormController extends Controller {\n revertDisabledButtons: { (): void } | null = null;\n forms: HTMLFormElement[] = [];\n\n // Revert disabled buttons before Turbo caches the page\n // To avoid flickering in the UI\n beforeCache = () => {\n if (this.revertDisabledButtons) {\n this.revertDisabledButtons();\n }\n };\n\n onSubmitCapture = (e: Event) => {\n e.preventDefault();\n };\n\n onSubmit = (e: Event) => {\n this.submitForm(e);\n };\n\n async submitForm(e: Event) {\n const form = e.currentTarget as HTMLFormElement;\n\n if (form.querySelector('[data-turbo=\"false\"]')) {\n return;\n }\n\n // Do not stop propagation so that GTM can recognize the event as Form Submission trigger.\n // e.stopPropagation();\n\n const formData = new FormData(form);\n\n const params = new URLSearchParams();\n formData.forEach((value, name) => {\n params.set(name, value as string);\n });\n // FormData does not include any submit button's data:\n // include them manually, since we have at most one submit button per form.\n const submitButtons = form.querySelectorAll('button[type=\"submit\"]');\n for (let i = 0; i < submitButtons.length; i++) {\n const button = submitButtons[i] as HTMLButtonElement;\n params.set(button.name, button.value);\n }\n if (form.id) {\n const el = document.querySelector(\n `button[type=\"submit\"][form=\"${form.id}\"]`\n );\n if (el) {\n const button = el as HTMLButtonElement;\n params.set(button.name, button.value);\n }\n }\n\n this.revertDisabledButtons = disableAllButtons();\n showProgressBar();\n try {\n const resp = await axios(form.action, {\n method: form.method as Method,\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded;charset=UTF-8\",\n \"X-Authgear-XHR\": \"true\",\n },\n data: params,\n onUploadProgress: progressEventHandler,\n onDownloadProgress: progressEventHandler,\n });\n\n const { redirect_uri, action } = resp.data;\n\n clearCache();\n switch (action) {\n case \"redirect\":\n // Perform full redirect.\n window.location = redirect_uri;\n break;\n\n case \"replace\":\n case \"advance\":\n // We assume the URL returned by the server have query preserved.\n visit(redirect_uri, { action });\n break;\n }\n } catch (e: unknown) {\n handleAxiosError(e);\n // revert is only called for error branch because\n // The success branch also loads a new page.\n // Keeping the buttons in disabled state reduce flickering in the UI.\n if (this.revertDisabledButtons) {\n this.revertDisabledButtons();\n this.revertDisabledButtons = null;\n }\n } finally {\n hideProgressBar();\n }\n }\n\n connect() {\n const elems = document.querySelectorAll(\"form\");\n for (let i = 0; i < elems.length; i++) {\n if (elems[i].querySelector('[data-turbo=\"false\"]')) {\n continue;\n }\n this.forms.push(elems[i] as HTMLFormElement);\n }\n for (const form of this.forms) {\n form.addEventListener(\"submit\", this.onSubmitCapture, true);\n form.addEventListener(\"submit\", this.onSubmit);\n }\n\n document.addEventListener(\"turbo:before-cache\", this.beforeCache);\n }\n\n disconnect() {\n for (const form of this.forms) {\n form.removeEventListener(\"submit\", this.onSubmitCapture, true);\n form.removeEventListener(\"submit\", this.onSubmit);\n }\n\n document.removeEventListener(\"turbo:before-cache\", this.beforeCache);\n }\n}\n\n// NOTE: As turbo would first disconnect and connect head and then disconnect and connect body, if we put this controller in head and modify field value, it will then be covered.\nexport class RestoreFormController extends Controller {\n static values = { json: String };\n\n declare jsonValue: string;\n\n connect() {\n const content = this.jsonValue;\n if (content === \"\") {\n return;\n }\n\n // Clear the content to avoid restoring twice.\n this.jsonValue = \"\";\n\n const formDataJSON = JSON.parse(content);\n\n // Find the form.\n let form: HTMLFormElement | null = null;\n const xAction = formDataJSON[\"x_action\"];\n const elementsWithXAction = document.querySelectorAll(`[name=\"x_action\"]`);\n for (let i = 0; i < elementsWithXAction.length; i++) {\n const elem = elementsWithXAction[i];\n if (elem instanceof HTMLButtonElement && elem.value === xAction) {\n form = elem.form;\n break;\n }\n }\n if (form == null) {\n return;\n }\n if (form.getAttribute(\"data-restore-form\") === \"false\") {\n return;\n }\n\n for (let i = 0; i < form.elements.length; i++) {\n const elem = form.elements[i];\n if (\n elem instanceof HTMLInputElement ||\n elem instanceof HTMLSelectElement ||\n elem instanceof HTMLTextAreaElement\n ) {\n const value = formDataJSON[elem.name];\n if (value != null) {\n elem.value = value;\n }\n }\n }\n }\n}\n\n// RetainFormFormController exposes the input listener\n// to capture form on every key stroke.\n// It saves the form in sessionStorage on disconnect.\n// On connect, it revives the input controls by setting their value attribute.\nexport class RetainFormFormController extends Controller {\n static values = {\n id: String,\n };\n\n static targets = [\"input\"];\n\n declare idValue: string;\n declare inputTargets: HTMLInputElement[];\n\n retained: Record = {};\n\n input(e: CustomEvent) {\n const name: string | undefined | null = (e as any).params.name;\n const value: string | undefined | null = e.detail.value;\n if (typeof name === \"string\" && typeof value === \"string\") {\n this.retained[name] = value;\n }\n }\n\n getSessionStorageKey(id: string): string {\n return `restore-form-form-${id}`;\n }\n\n connect() {\n if (this.idValue !== \"\") {\n const key = this.getSessionStorageKey(this.idValue);\n const value = sessionStorage.getItem(key);\n if (value == null) {\n return;\n }\n sessionStorage.removeItem(key);\n this.retained = JSON.parse(value);\n for (const input of this.inputTargets) {\n for (const name in this.retained) {\n if (input.getAttribute(\"data-retain-form-form-name-param\") === name) {\n // NOTE(tung): Setting value attribute cause bfcache of chrome failing to restore\n // input.setAttribute(\"value\", this.retained[name]);\n input.value = this.retained[name];\n }\n }\n }\n }\n }\n\n disconnect() {\n // Before disconnect, collect all values once.\n this.collectAllValues();\n if (this.idValue !== \"\") {\n const key = this.getSessionStorageKey(this.idValue);\n sessionStorage.setItem(key, JSON.stringify(this.retained));\n }\n }\n\n private collectAllValues() {\n for (const input of this.inputTargets) {\n const name = input.getAttribute(\"data-retain-form-form-name-param\");\n const value = input.value;\n if (typeof name === \"string\" && typeof value === \"string\") {\n this.retained[name] = value;\n }\n }\n }\n}\n\n// RetainFormInputController is intended to be installed on\n// normal and forward the \"input\" event to RetainFormFormController.\nexport class RetainFormInputController extends Controller {\n input(e: InputEvent) {\n if (e.currentTarget instanceof HTMLInputElement) {\n this.dispatch(\"input\", {\n detail: {\n value: e.currentTarget.value,\n },\n });\n }\n }\n}\n","// Credit to https://developer.mozilla.org/en-US/docs/Glossary/Base64\n\nfunction b64ToUint6(nChr: number): number {\n return nChr > 64 && nChr < 91\n ? nChr - 65\n : nChr > 96 && nChr < 123\n ? nChr - 71\n : nChr > 47 && nChr < 58\n ? nChr + 4\n : nChr === 43\n ? 62\n : nChr === 47\n ? 63\n : 0;\n}\n\nexport function base64DecToArr(\n sBase64: string,\n nBlocksSize?: number\n): Uint8Array {\n var sB64Enc = sBase64.replace(/[^A-Za-z0-9\\+\\/]/g, \"\"),\n nInLen = sB64Enc.length,\n nOutLen = nBlocksSize\n ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize\n : (nInLen * 3 + 1) >> 2,\n taBytes = new Uint8Array(nOutLen);\n\n for (\n var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0;\n nInIdx < nInLen;\n nInIdx++\n ) {\n nMod4 = nInIdx & 3;\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4));\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;\n }\n nUint24 = 0;\n }\n }\n\n return taBytes;\n}\n\n/* Base64 string to array encoding */\n\nfunction uint6ToB64(nUint6: number) {\n return nUint6 < 26\n ? nUint6 + 65\n : nUint6 < 52\n ? nUint6 + 71\n : nUint6 < 62\n ? nUint6 - 4\n : nUint6 === 62\n ? 43\n : nUint6 === 63\n ? 47\n : 65;\n}\n\nexport function base64EncArr(aBytes: Uint8Array) {\n var nMod3 = 2,\n sB64Enc = \"\";\n\n for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {\n nMod3 = nIdx % 3;\n if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) {\n sB64Enc += \"\\r\\n\";\n }\n nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24);\n if (nMod3 === 2 || aBytes.length - nIdx === 1) {\n sB64Enc += String.fromCodePoint(\n uint6ToB64((nUint24 >>> 18) & 63),\n uint6ToB64((nUint24 >>> 12) & 63),\n uint6ToB64((nUint24 >>> 6) & 63),\n uint6ToB64(nUint24 & 63)\n );\n nUint24 = 0;\n }\n }\n\n return (\n sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) +\n (nMod3 === 2 ? \"\" : nMod3 === 1 ? \"=\" : \"==\")\n );\n}\n","export function base64URLToBase64(base64url: string): string {\n let base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n if (base64.length % 4 !== 0) {\n const count = 4 - (base64.length % 4);\n base64 += \"=\".repeat(count);\n }\n return base64;\n}\n\nexport function base64ToBase64URL(base64: string): string {\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nexport function trimNewline(str: string): string {\n return str.replace(/\\r/g, \"\").replace(/\\n/g, \"\");\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport function handleAxiosError(e: unknown) {\n const err = e as any;\n if (err.response != null) {\n setErrorMessage(\"data-server-error-message\");\n } else {\n setErrorMessage(\"data-network-error-message\");\n }\n\n console.error(err);\n}\n\nexport function setErrorMessage(id: string) {\n const e = new CustomEvent(\"alert-message:show-message\", {\n detail: {\n id,\n },\n });\n document.dispatchEvent(e);\n}\n\nexport class AlertMessageController extends Controller {\n static targets = [\"message\"];\n\n declare messageTarget: HTMLElement;\n\n // Dismiss the alert before cache the page.\n // See https://github.com/authgear/authgear-server/issues/1424\n beforeCache = () => {\n this.element.removeAttribute(\"data-error-message\");\n };\n\n updateMessage = (e: Event) => {\n const errorMessage = this.element.getAttribute(\n (e as CustomEvent).detail.id\n );\n if (errorMessage != null) {\n this.element.setAttribute(\"data-error-message\", errorMessage);\n this.displayMessage();\n }\n };\n\n displayMessage = () => {\n const errorMessage = this.element.getAttribute(\"data-error-message\");\n if (errorMessage != null) {\n this.messageTarget.innerHTML = errorMessage;\n }\n };\n\n connect() {\n document.addEventListener(\"turbo:before-cache\", this.beforeCache);\n document.addEventListener(\"alert-message:show-message\", this.updateMessage);\n this.displayMessage();\n }\n\n disconnect() {\n document.removeEventListener(\"turbo:before-cache\", this.beforeCache);\n document.removeEventListener(\n \"alert-message:show-message\",\n this.updateMessage\n );\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport axios from \"axios\";\nimport { handleAxiosError, showErrorMessage } from \"./messageBar\";\nimport { base64DecToArr, base64EncArr } from \"./base64\";\nimport { base64URLToBase64, trimNewline, base64ToBase64URL } from \"./base64url\";\nimport { RetryEventTarget } from \"./retry\";\nimport { setErrorMessage } from \"./authflowv2/alert-message\";\n\nfunction passkeyIsAvailable(): boolean {\n return (\n typeof window.PublicKeyCredential !== \"undefined\" &&\n typeof window.navigator.credentials !== \"undefined\"\n );\n}\n\nfunction deserializeCreationOptions(\n creationOptions: any\n): CredentialCreationOptions {\n const base64URLChallenge = creationOptions.publicKey.challenge;\n const challenge = base64DecToArr(base64URLToBase64(base64URLChallenge));\n creationOptions.publicKey.challenge = challenge;\n\n const base64URLUserID = creationOptions.publicKey.user.id;\n const userID = base64DecToArr(base64URLToBase64(base64URLUserID));\n creationOptions.publicKey.user.id = userID;\n\n if (creationOptions.publicKey.excludeCredentials != null) {\n for (const c of creationOptions.publicKey.excludeCredentials) {\n c.id = base64DecToArr(base64URLToBase64(c.id));\n }\n }\n return creationOptions;\n}\n\nfunction deserializeRequestOptions(\n requestOptions: any\n): CredentialRequestOptions {\n const base64URLChallenge = requestOptions.publicKey.challenge;\n const challenge = base64DecToArr(base64URLToBase64(base64URLChallenge));\n requestOptions.publicKey.challenge = challenge;\n if (requestOptions.publicKey.allowCredentials) {\n for (const c of requestOptions.publicKey.allowCredentials) {\n c.id = base64DecToArr(base64URLToBase64(c.id));\n }\n }\n return requestOptions;\n}\n\n// At runtime, we do not assume the return value of\n// window.navigator.credentials.get is instanceof PublicKeyCredential.\n// It is observed that on Firefox 133 (as of 2024-12-18), window.navigator.credentials.get\n// can return something of type Object, when 1Password extension is installed.\n//\n// Maybe this behavior is due to the fact that Firefox has no native support\n// for passkeys yet.\n// I have tried to search the issue list with\n// https://bugzilla.mozilla.org/buglist.cgi?product=Core&component=DOM%3A%20Web%20Authentication&resolution=---\n// but found no reported issues.\n//\n// Therefore, we use a type guard to assert the return value of\n// window.navigator.credentials.get looks like a PublicKeyCredential,\n// without checking the actual type.\n\ninterface PublicKeyCredentialWithAttestationResponse {\n id: string;\n type: string;\n response: AuthenticatorAttestationResponse;\n getClientExtensionResults(): AuthenticationExtensionsClientOutputs;\n}\n\nfunction isPublicKeyCredentialWithAttestationResponse(\n credential: unknown\n): credential is PublicKeyCredentialWithAttestationResponse {\n // For browsers that behave correctly, just use instanceof.\n if (credential instanceof PublicKeyCredential) {\n return true;\n }\n\n // Otherwise, we fallback to checking the required properties.\n\n if (credential == null) {\n return false;\n }\n if (typeof credential !== \"object\") {\n return false;\n }\n // I know it is better to write Object.prototype.hasOwnProperty.call(credential, \"id\"),\n // but TypeScript is not smart enough to type-inference it has .id afterwards.\n if (!(\"id\" in credential) || typeof credential.id !== \"string\") {\n return false;\n }\n if (!(\"type\" in credential) || typeof credential.type !== \"string\") {\n return false;\n }\n if (\n !(\"response\" in credential) ||\n typeof credential.response !== \"object\" ||\n credential.response == null\n ) {\n return false;\n }\n // Since getClientExtensionResults is a function, it is probably not a own property on credential.\n // So it is legit (and correct) to use the in operator here.\n if (\n !(\"getClientExtensionResults\" in credential) ||\n typeof credential.getClientExtensionResults !== \"function\"\n ) {\n return false;\n }\n return true;\n}\n\ninterface PublicKeyCredentialWithAssertionResponse {\n id: string;\n type: string;\n response: AuthenticatorAssertionResponse;\n getClientExtensionResults(): AuthenticationExtensionsClientOutputs;\n}\n\nfunction isPublicKeyCredentialWithAssertionResponse(\n credential: unknown\n): credential is PublicKeyCredentialWithAssertionResponse {\n // For browsers that behave correctly, just use instanceof.\n if (credential instanceof PublicKeyCredential) {\n return true;\n }\n\n // Otherwise, we fallback to checking the required properties.\n\n if (credential == null) {\n return false;\n }\n if (typeof credential !== \"object\") {\n return false;\n }\n // I know it is better to write Object.prototype.hasOwnProperty.call(credential, \"id\"),\n // but TypeScript is not smart enough to type-inference it has .id afterwards.\n if (!(\"id\" in credential) || typeof credential.id !== \"string\") {\n return false;\n }\n if (!(\"type\" in credential) || typeof credential.type !== \"string\") {\n return false;\n }\n if (\n !(\"response\" in credential) ||\n typeof credential.response !== \"object\" ||\n credential.response == null\n ) {\n return false;\n }\n // Since getClientExtensionResults is a function, it is probably not a own property on credential.\n // So it is legit (and correct) to use the in operator here.\n if (\n !(\"getClientExtensionResults\" in credential) ||\n typeof credential.getClientExtensionResults !== \"function\"\n ) {\n return false;\n }\n return true;\n}\n\nfunction serializeAttestationResponse(\n credential: PublicKeyCredentialWithAttestationResponse\n) {\n const response = credential.response;\n\n const attestationObject = trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.attestationObject)))\n );\n const clientDataJSON = trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.clientDataJSON)))\n );\n\n let transports: string[] = [];\n if (typeof response.getTransports === \"function\") {\n transports = response.getTransports();\n }\n\n const clientExtensionResults = credential.getClientExtensionResults();\n\n return {\n id: credential.id,\n rawId: credential.id,\n type: credential.type,\n response: {\n attestationObject,\n clientDataJSON,\n transports,\n },\n clientExtensionResults,\n };\n}\n\nfunction serializeAssertionResponse(\n credential: PublicKeyCredentialWithAssertionResponse\n) {\n const response = credential.response;\n const authenticatorData = trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.authenticatorData)))\n );\n const clientDataJSON = trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.clientDataJSON)))\n );\n const signature = trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.signature)))\n );\n const userHandle =\n response.userHandle == null\n ? undefined\n : trimNewline(\n base64ToBase64URL(base64EncArr(new Uint8Array(response.userHandle)))\n );\n const clientExtensionResults = credential.getClientExtensionResults();\n return {\n id: credential.id,\n rawId: credential.id,\n type: credential.type,\n response: {\n authenticatorData,\n clientDataJSON,\n signature,\n userHandle,\n },\n clientExtensionResults,\n };\n}\n\nfunction isEmptyAllowCredentialsError(err: unknown) {\n return err instanceof DOMException && /allowCredentials/i.test(err.message);\n}\n\nfunction isSafariCancel(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"NotAllowedError\" &&\n // \"This request has been cancelled by the user.\"\n /cancel/i.test(err.message)\n );\n}\n\nfunction isSafariTimeout(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"HierarchyRequestError\" &&\n // \"The operation would yield an incorrect node tree.\"\n /node tree/i.test(err.message)\n );\n}\n\nfunction isOperationFailError(err: unknown) {\n // This happens when the user chooses to use Android phone to scan QR code.\n // And the passkey is not found on that Android phone.\n // If security key is used, the error message is shown in the modal dialog and the dialog will not close.\n // Thus we cannot detect security key error.\n\n // This error also happens when using passkey api in webview\n return (\n err instanceof DOMException &&\n err.name === \"NotAllowedError\" &&\n // \"Operation failed.\"\n /operation.*fail/i.test(err.message)\n );\n}\n\nfunction isChromeCancelOrTimeout(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"NotAllowedError\" &&\n // \"The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.\"\n /time.*out/i.test(err.message)\n );\n}\n\nfunction isFirefoxCancel(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"AbortError\" &&\n // \"The operation was aborted. \"\n /operation.*abort/i.test(err.message)\n );\n}\n\nfunction isAbortControllerError(err: unknown) {\n return err instanceof DOMException && err.name === \"AbortError\";\n}\n\nfunction isFirefoxSecurityKeyError(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"InvalidStateError\" &&\n // \"An attempt was made to use an object that is not, or is no longer, usable\"\n /no.*usable/i.test(err.message)\n );\n}\n\nfunction isSafariDuplicateError(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"InvalidStateError\" &&\n // \"At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.\"\n /excludeCredentials/i.test(err.message)\n );\n}\n\nfunction isChromeDuplicateError(err: unknown) {\n return (\n err instanceof DOMException &&\n err.name === \"InvalidStateError\" &&\n // \"The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.\"\n /already register/i.test(err.message)\n );\n}\n\nfunction handleError(err: unknown) {\n console.error(err);\n\n const errorThatCanSimplyBeIgnored = [\n isSafariCancel,\n isSafariTimeout,\n isChromeCancelOrTimeout,\n isFirefoxCancel,\n // Firefox timeout was not observed.\n isAbortControllerError,\n ];\n for (const p of errorThatCanSimplyBeIgnored) {\n if (p(err)) {\n return;\n }\n }\n\n if (isOperationFailError(err)) {\n showErrorMessage(\"error-message-no-passkey\");\n return;\n }\n\n if (isFirefoxSecurityKeyError(err)) {\n showErrorMessage(\"error-message-no-passkey\");\n return;\n }\n\n if (isEmptyAllowCredentialsError(err)) {\n showErrorMessage(\"error-message-passkey-empty-allow-credentials\");\n }\n\n if (isSafariDuplicateError(err) || isChromeDuplicateError(err)) {\n showErrorMessage(\"error-message-passkey-duplicate\");\n }\n\n return false;\n}\n\n// We want to prompt the modal dialog to create passkey.\n// But navigator.credentials.create is user activation-gated API.\n// There is no way to check if we have user activation currently.\nexport class PasskeyCreationController extends Controller {\n static targets = [\"button\", \"submit\", \"input\"];\n\n declare buttonTarget: HTMLButtonElement;\n declare submitTarget: HTMLButtonElement;\n declare inputTarget: HTMLInputElement;\n\n connect() {\n // Disable the button if PublicKeyCredential is unavailable.\n if (!passkeyIsAvailable()) {\n this.buttonTarget.disabled = true;\n return;\n }\n }\n\n create(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n this._create();\n }\n\n async _create() {\n try {\n const resp = await axios(\"/_internals/passkey/creation_options\", {\n method: \"post\",\n });\n const options = deserializeCreationOptions(resp.data.result);\n try {\n const rawResponse = await window.navigator.credentials.create(options);\n if (isPublicKeyCredentialWithAttestationResponse(rawResponse)) {\n const response = serializeAttestationResponse(rawResponse);\n const responseString = JSON.stringify(response);\n this.inputTarget.value = responseString;\n // It seems that we should use form.submit() to submit the form.\n // but form.submit() does NOT trigger submit event,\n // which is essential for XHR form submission to work.\n // Therefore, we emulate form submission here by clicking the submit button.\n this.submitTarget.click();\n }\n } catch (e: unknown) {\n handleError(e);\n }\n } catch (e: unknown) {\n handleAxiosError(e);\n }\n }\n}\n\n// We want to prompt the modal dialog to let the user to choose passkey.\n// But navigator.credentials.get is user activation-gated API.\n// There is no way to check if we have user activation currently.\nexport class PasskeyRequestController extends Controller {\n static targets = [\"button\", \"submit\", \"input\"];\n static values = {\n auto: String,\n allowCredentials: String,\n };\n\n declare buttonTarget: HTMLButtonElement;\n declare submitTarget: HTMLButtonElement;\n declare inputTarget: HTMLInputElement;\n\n declare autoValue: string;\n declare allowCredentialsValue: string;\n\n connect() {\n // Disable the button if PublicKeyCredential is unavailable.\n if (!passkeyIsAvailable()) {\n this.buttonTarget.disabled = true;\n return;\n }\n\n if (this.autoValue === \"true\") {\n this._use();\n }\n }\n\n use(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n this._use();\n }\n\n async _use() {\n try {\n const params = new URLSearchParams();\n params.set(\"allow_credentials\", this.allowCredentialsValue);\n const resp = await axios(\"/_internals/passkey/request_options\", {\n method: \"post\",\n data: params,\n });\n const options = deserializeRequestOptions(resp.data.result);\n try {\n const rawResponse = await window.navigator.credentials.get(options);\n if (isPublicKeyCredentialWithAssertionResponse(rawResponse)) {\n const response = serializeAssertionResponse(rawResponse);\n const responseString = JSON.stringify(response);\n this.inputTarget.value = responseString;\n // It seems that we should use form.submit() to submit the form.\n // but form.submit() does NOT trigger submit event,\n // which is essential for XHR form submission to work.\n // Therefore, we emulate form submission here by clicking the submit button.\n this.submitTarget.click();\n }\n } catch (e: unknown) {\n handleError(e);\n }\n } catch (e: unknown) {\n handleAxiosError(e);\n }\n }\n}\n\nexport class AuthflowPasskeyErrorController extends Controller {\n connect(): void {\n document.addEventListener(\"passkey:error\", this.onPasskeyError);\n }\n\n disconnect(): void {\n document.removeEventListener(\"passkey:error\", this.onPasskeyError);\n }\n\n onPasskeyError = (e: Event) => {\n handleError((e as CustomEvent).detail);\n };\n}\n\nexport class AuthflowV2PasskeyErrorController extends Controller {\n connect(): void {\n document.addEventListener(\"passkey:error\", this.onPasskeyError);\n }\n\n disconnect(): void {\n document.removeEventListener(\"passkey:error\", this.onPasskeyError);\n }\n\n onPasskeyError = (event: Event) => {\n const err: unknown = (event as CustomEvent).detail;\n const errorThatCanSimplyBeIgnored = [\n isSafariCancel,\n isSafariTimeout,\n isChromeCancelOrTimeout,\n isFirefoxCancel,\n // Firefox timeout was not observed.\n isAbortControllerError,\n ];\n for (const p of errorThatCanSimplyBeIgnored) {\n if (p(err)) {\n return;\n }\n }\n let errMessage = \"data-passkey-not-supported\";\n if (isOperationFailError(err)) {\n errMessage = \"data-invalid-passkey-or-not-supported\";\n }\n\n if (isFirefoxSecurityKeyError(err)) {\n errMessage = \"data-no-passkey\";\n }\n\n if (isSafariDuplicateError(err) || isChromeDuplicateError(err)) {\n errMessage = \"data-passkey-duplicate\";\n }\n setErrorMessage(errMessage);\n };\n}\n\nexport class AuthflowPasskeyRequestController extends Controller {\n static targets = [\"button\", \"submit\", \"input\"];\n static values = {\n options: String,\n auto: String,\n };\n\n declare buttonTarget: HTMLButtonElement;\n declare submitTarget: HTMLButtonElement;\n declare inputTarget: HTMLInputElement;\n\n declare optionsValue: string;\n declare autoValue: string;\n declare hasButtonTarget: boolean;\n\n connect() {\n if (this.hasButtonTarget) {\n this.buttonTarget.disabled = false;\n // Disable the button if PublicKeyCredential is unavailable.\n if (!passkeyIsAvailable()) {\n this.buttonTarget.disabled = true;\n return;\n }\n }\n\n if (this.autoValue === \"true\") {\n this._use();\n }\n }\n\n use(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n this._use();\n }\n\n async _use() {\n if (!passkeyIsAvailable()) {\n document.dispatchEvent(\n new CustomEvent(\"passkey:error\", {\n detail: new Error(\"passkey is not available\"),\n })\n );\n return;\n }\n try {\n const optionsJSON = JSON.parse(this.optionsValue);\n const options = deserializeRequestOptions(optionsJSON);\n const rawResponse = await window.navigator.credentials.get(options);\n if (isPublicKeyCredentialWithAssertionResponse(rawResponse)) {\n const response = serializeAssertionResponse(rawResponse);\n const responseString = JSON.stringify(response);\n this.inputTarget.value = responseString;\n // It seems that we should use form.submit() to submit the form.\n // but form.submit() does NOT trigger submit event,\n // which is essential for XHR form submission to work.\n // Therefore, we emulate form submission here by clicking the submit button.\n this.submitTarget.click();\n }\n } catch (e: unknown) {\n document.dispatchEvent(\n new CustomEvent(\"passkey:error\", {\n detail: e,\n })\n );\n }\n }\n}\n\nexport class AuthflowPasskeyCreationController extends Controller {\n static targets = [\"button\", \"submit\", \"input\"];\n static values = {\n options: String,\n };\n\n declare buttonTarget: HTMLButtonElement;\n declare submitTarget: HTMLButtonElement;\n declare inputTarget: HTMLInputElement;\n declare hasButtonTarget: boolean;\n\n declare optionsValue: string;\n\n connect() {\n if (this.hasButtonTarget) {\n this.buttonTarget.disabled = false;\n // Disable the button if PublicKeyCredential is unavailable.\n if (!passkeyIsAvailable()) {\n this.buttonTarget.disabled = true;\n return;\n }\n }\n }\n\n create(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n this._create();\n }\n\n async _create() {\n if (!passkeyIsAvailable()) {\n document.dispatchEvent(\n new CustomEvent(\"passkey:error\", {\n detail: new Error(\"passkey is not available\"),\n })\n );\n return;\n }\n try {\n const optionsJSON = JSON.parse(this.optionsValue);\n const options = deserializeCreationOptions(optionsJSON);\n const rawResponse = await window.navigator.credentials.create(options);\n if (isPublicKeyCredentialWithAttestationResponse(rawResponse)) {\n const response = serializeAttestationResponse(rawResponse);\n const responseString = JSON.stringify(response);\n this.inputTarget.value = responseString;\n // It seems that we should use form.submit() to submit the form.\n // but form.submit() does NOT trigger submit event,\n // which is essential for XHR form submission to work.\n // Therefore, we emulate form submission here by clicking the submit button.\n this.submitTarget.click();\n }\n } catch (e: unknown) {\n document.dispatchEvent(\n new CustomEvent(\"passkey:error\", {\n detail: e,\n })\n );\n }\n }\n}\n\n// TODO(passkey): autofill is buggy on iOS 16 Beta 4.\n// The call navigator.credentials.get will have a high possibility of resulting in\n// DOMException with name NotAllowedError instantly.\n// The exception WILL cause subsequent call to navigator.credentials.get to fail as well.\n// So autofill is disabled for now.\n//\n// The lifecycle of the autofill\n//\n// setupAutofill() creates a pending promise to receive the result of the autofill.\n// The promise can be aborted with AbortController.\n// In disconnect(), we abort the promise.\n// In connect(), we call setupAutofill().\n// Since Stimulus will call connect(), we do not need to call setupAutofill if the promise is aborted.\nexport class PasskeyAutofillController extends Controller {\n static targets = [\"submit\", \"input\"];\n\n declare submitTarget: HTMLButtonElement;\n declare inputTarget: HTMLInputElement;\n\n abortController: AbortController | null = null;\n retryEventTarget: RetryEventTarget | null = null;\n\n connect() {\n if (!passkeyIsAvailable()) {\n return;\n }\n\n this.abortController = new AbortController();\n this.retryEventTarget = new RetryEventTarget({\n abortController: this.abortController,\n });\n this.retryEventTarget.addEventListener(\"retry\", () => {\n this.setupAutofill();\n });\n\n this.setupAutofill();\n }\n\n disconnect() {\n this.abortController?.abort();\n this.abortController = null;\n this.retryEventTarget = null;\n }\n\n async setupAutofill() {\n if (\n typeof PublicKeyCredential.isConditionalMediationAvailable === \"function\"\n ) {\n const available =\n await PublicKeyCredential.isConditionalMediationAvailable();\n\n if (available) {\n try {\n const params = new URLSearchParams();\n params.set(\"conditional\", \"true\");\n const resp = await axios(\"/_internals/passkey/request_options\", {\n method: \"post\",\n data: params,\n });\n this.retryEventTarget?.markSuccess();\n const options = deserializeRequestOptions(resp.data.result);\n const t0 = new Date().getTime();\n try {\n const signal = this.abortController?.signal;\n const rawResponse = await window.navigator.credentials.get({\n ...options,\n signal,\n });\n if (isPublicKeyCredentialWithAssertionResponse(rawResponse)) {\n const response = serializeAssertionResponse(rawResponse);\n const responseString = JSON.stringify(response);\n this.inputTarget.value = responseString;\n // It seems that we should use form.submit() to submit the form.\n // but form.submit() does NOT trigger submit event,\n // which is essential for XHR form submission to work.\n // Therefore, we emulate form submission here by clicking the submit button.\n this.submitTarget.click();\n }\n this.retryEventTarget?.scheduleRetry();\n } catch (e: unknown) {\n const t1 = new Date().getTime();\n if (\n e instanceof DOMException &&\n e.name === \"NotAllowedError\" &&\n t1 - t0 < 500\n ) {\n console.warn(\"passkey autofill weird error detected\", e);\n }\n if (e instanceof DOMException && e.name === \"AbortError\") {\n // Aborted. Let connect() to be called again.\n } else {\n this.retryEventTarget?.scheduleRetry();\n }\n handleError(e);\n }\n } catch (e: unknown) {\n handleAxiosError(e);\n this.retryEventTarget?.scheduleRetry();\n }\n }\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { DateTime } from \"luxon\";\n\nexport class LockoutController extends Controller {\n static targets = [\"locked\", \"unlocked\"];\n static values = {\n lockUntil: String,\n actionButtonSelector: String,\n };\n\n declare intervalHandle: number | null;\n declare lockUntilValue: string;\n declare actionButtonSelectorValue: string;\n declare lockedTargets: HTMLElement[];\n declare unlockedTargets: HTMLElement[];\n\n private isLocked: boolean | undefined = undefined;\n private wasActionButtonDisabled: boolean = false;\n\n stopTick() {\n if (this.intervalHandle != null) {\n window.clearInterval(this.intervalHandle);\n this.intervalHandle = null;\n this.wasActionButtonDisabled = false;\n }\n }\n\n setupTick() {\n this.isLocked = undefined;\n this.stopTick();\n const el = this.element as HTMLElement;\n const lockUntil = DateTime.fromISO(this.lockUntilValue);\n if (!this.lockUntilValue || !lockUntil.isValid) {\n return;\n }\n\n const tick = () => {\n const actionButtonEl = el.querySelector(this.actionButtonSelectorValue);\n const now = DateTime.now();\n\n const newIsLocked = now < lockUntil;\n if (newIsLocked === this.isLocked) {\n return;\n }\n this.isLocked = newIsLocked;\n if (actionButtonEl != null) {\n if (newIsLocked === true) {\n this.wasActionButtonDisabled = actionButtonEl?.getAttribute(\n \"disabled\"\n )\n ? true\n : false;\n (actionButtonEl as HTMLButtonElement).disabled = true;\n } else {\n (actionButtonEl as HTMLButtonElement).disabled =\n this.wasActionButtonDisabled;\n }\n }\n\n this.lockedTargets.forEach(\n (el) => ((el as HTMLElement).style.display = newIsLocked ? \"\" : \"none\")\n );\n this.unlockedTargets.forEach(\n (el) => ((el as HTMLElement).style.display = newIsLocked ? \"none\" : \"\")\n );\n\n if (!newIsLocked) {\n this.stopTick();\n }\n };\n tick();\n\n this.intervalHandle = window.setInterval(tick, 100);\n }\n\n connect(): void {\n this.setupTick();\n }\n\n disconnect() {\n this.stopTick();\n }\n}\n"],"names":["copyToClipboard","str","el","_CopyButtonController","Controller","button","copyLabel","copiedLabel","target","textContent","currentHandle","newHandle","CopyButtonController","_PasswordVisibilityToggleController","PasswordVisibilityToggleController","_ClickToSwitchController","ClickToSwitchController","PreventDoubleTapController","_AccountDeletionController","input","inputText","AccountDeletionController","_ResendButtonController","scheduledAt","cooldown","label","labelUnit","tick","timeElapsed","displaySeconds","ResendButtonController","handleAxiosError","e","err","showErrorMessage","response","session","id","setErrorMessage","hideErrorMessage","hidden","MessageBarController","_b","_a","disableAllButtons","buttons","original","i","disabled","state","hideProgressBar","loadingProgressBar","showProgressBar","progressEventHandler","progressEvent","percentage","width","destroyCropper","img","cropper","Cropper","initCropper","getCropper","_ImagePickerController","file","imgCropper","reader","src","maxDimensions","dimensionsOptions","imageData","cropBoxData","imageScale","croppedImageWidth","resultDimensions","blob","inputValue","formUpload","revert","body","axios","upload_url","formData","uploadRespBody","url","ImagePickerController","exponential","index","RetryEventTarget","options","_c","maxIndex","indexToMillis","oldIndex","newIndex","delay","refreshPage","visit","_AuthflowWebsocketController","AuthflowWebsocketController","TIMEOUT","_AuthflowPollingController","recur","_d","AuthflowPollingController","intlDateTimeFormatIsSupported","testDate","intlRelativeTimeFormatIsSupported","XHRSubmitFormController","form","params","value","name","submitButtons","resp","redirect_uri","action","clearCache","elems","_RestoreFormController","content","formDataJSON","xAction","elementsWithXAction","elem","RestoreFormController","_RetainFormFormController","key","RetainFormFormController","RetainFormInputController","b64ToUint6","nChr","base64DecToArr","sBase64","nBlocksSize","sB64Enc","nInLen","nOutLen","taBytes","nMod3","nMod4","nUint24","nOutIdx","nInIdx","uint6ToB64","nUint6","base64EncArr","aBytes","nLen","nIdx","base64URLToBase64","base64url","base64","count","base64ToBase64URL","trimNewline","_AlertMessageController","errorMessage","AlertMessageController","passkeyIsAvailable","deserializeCreationOptions","creationOptions","base64URLChallenge","challenge","base64URLUserID","userID","c","deserializeRequestOptions","requestOptions","isPublicKeyCredentialWithAttestationResponse","credential","isPublicKeyCredentialWithAssertionResponse","serializeAttestationResponse","attestationObject","clientDataJSON","transports","clientExtensionResults","serializeAssertionResponse","authenticatorData","signature","userHandle","isEmptyAllowCredentialsError","isSafariCancel","isSafariTimeout","isOperationFailError","isChromeCancelOrTimeout","isFirefoxCancel","isAbortControllerError","isFirefoxSecurityKeyError","isSafariDuplicateError","isChromeDuplicateError","handleError","errorThatCanSimplyBeIgnored","p","_PasskeyCreationController","rawResponse","responseString","PasskeyCreationController","_PasskeyRequestController","PasskeyRequestController","AuthflowPasskeyErrorController","AuthflowV2PasskeyErrorController","event","errMessage","_AuthflowPasskeyRequestController","optionsJSON","AuthflowPasskeyRequestController","_AuthflowPasskeyCreationController","AuthflowPasskeyCreationController","_PasskeyAutofillController","t0","signal","t1","_e","PasskeyAutofillController","_LockoutController","lockUntil","DateTime","actionButtonEl","newIsLocked","LockoutController"],"mappings":"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"}