import { useInsertScriptTags } from '@keycloakify/svelte/tools/useInsertScriptTags'; import { assert } from 'keycloakify/tools/assert'; import { waitForElementMountedOnDom } from 'keycloakify/tools/waitForElementMountedOnDom'; import type { KcContext } from '../KcContext'; import { onMount } from 'svelte'; import type { Readable } from 'svelte/store'; type KcContextLike = { url: { resourcesPath: string; }; isUserIdentified: 'true' | 'false'; challenge: string; userVerification: KcContext.WebauthnAuthenticate['userVerification']; rpId: string; createTimeout: number | string; }; assert(); assert(); type I18nLike = { msgStr: (key: 'webauthn-unsupported-browser-text') => string; isFetchingTranslations: boolean; }; export function useScript(params: { authButtonId: string; kcContext: KcContextLike; i18n: Readable }) { const { authButtonId, kcContext, i18n } = params; const { url, isUserIdentified, challenge, userVerification, rpId, createTimeout } = kcContext; onMount(() => { let hasInserted = false; const unsubscribe = i18n.subscribe(($i18n) => { if (hasInserted) { return; } const { msgStr, isFetchingTranslations } = $i18n; if (isFetchingTranslations) { return; } const { insertScriptTags } = useInsertScriptTags({ componentOrHookName: 'WebauthnAuthenticate', scriptTags: [ { type: 'module', textContent: () => ` import { authenticateByWebAuthn } from "${url.resourcesPath}/js/webauthnAuthenticate.js"; const authButton = document.getElementById('${authButtonId}'); authButton.addEventListener("click", function() { const input = { isUserIdentified : ${isUserIdentified}, challenge : ${JSON.stringify(challenge)}, userVerification : ${JSON.stringify(userVerification)}, rpId : ${JSON.stringify(rpId)}, createTimeout : ${JSON.stringify(createTimeout)}, errmsg : ${JSON.stringify(msgStr('webauthn-unsupported-browser-text'))} }; authenticateByWebAuthn(input); }, { once: true }); `, }, ], }); hasInserted = true; (async () => { await waitForElementMountedOnDom({ elementId: authButtonId, }); insertScriptTags(); })(); }); return () => unsubscribe(); }); }