@criipto/verify-react 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,6 +44,9 @@ const CriiptoVerifyContext = createContext({
|
|
|
44
44
|
loginHint: void 0
|
|
45
45
|
});
|
|
46
46
|
//#endregion
|
|
47
|
+
//#region package.json
|
|
48
|
+
var version = "5.0.2";
|
|
49
|
+
//#endregion
|
|
47
50
|
//#region src/i18n/en.ts
|
|
48
51
|
const en = {
|
|
49
52
|
loginWith: "Login with",
|
|
@@ -206,7 +209,6 @@ function getI18n(language) {
|
|
|
206
209
|
}
|
|
207
210
|
//#endregion
|
|
208
211
|
//#region src/utils.ts
|
|
209
|
-
const VERSION = typeof __VERSION__ === "undefined" ? "N/A" : __VERSION__;
|
|
210
212
|
const DKMITID_PREFIX = "urn:grn:authn:dk:mitid";
|
|
211
213
|
const FTN_PREFIX = "urn:grn:authn:fi";
|
|
212
214
|
function lowestMitIDValue(input) {
|
|
@@ -607,7 +609,7 @@ const CriiptoVerifyProvider = (props) => {
|
|
|
607
609
|
action,
|
|
608
610
|
message
|
|
609
611
|
}),
|
|
610
|
-
extraUrlParams: props.criiptoSdk !== void 0 ? { criipto_sdk: props.criiptoSdk } : { criipto_sdk: `@criipto/verify-react@${
|
|
612
|
+
extraUrlParams: props.criiptoSdk !== void 0 ? { criipto_sdk: props.criiptoSdk } : { criipto_sdk: `@criipto/verify-react@${version}` }
|
|
611
613
|
});
|
|
612
614
|
}, [
|
|
613
615
|
pkce,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["OAuth2Error","usePoll","searchParamsToPOJO","logo","QRCode","PollStrategy","ForegroundStrategy","ReloadStrategy","dkmitiderhverv","dkmitid","ftnmobile","ftn","itsme","sebankid","nobankid","novipps","sefrejaid","ukoneid","depersonalausweis","idin"],"sources":["../src/context.ts","../src/i18n/en.ts","../src/i18n/da.ts","../src/i18n/sv.ts","../src/i18n/nb.ts","../src/i18n/fi.ts","../src/i18n/de.ts","../src/i18n/nl.ts","../src/i18n/index.ts","../src/utils.ts","../src/memory-storage.ts","../src/provider.tsx","../src/device.ts","../src/components/SEBankIDSameDeviceButton/usePoll.ts","../src/components/SEBankIDSameDeviceButton/Poll.tsx","../src/hooks/usePageVisibility.ts","../src/components/SEBankIDSameDeviceButton/Foreground.tsx","../src/components/SEBankIDSameDeviceButton/shared.ts","../src/components/SEBankIDSameDeviceButton/Reload.tsx","../src/components/SEBankIDQRCode/logo@2x.png","../src/components/SEBankIDQRCode.tsx","../src/components/AuthButtonGroup.tsx","../src/components/Spinner/Spinner.tsx","../src/components/SEBankIDSameDeviceButton.tsx","../src/components/AuthMethodButton/logos/dkmitid.png","../src/components/AuthMethodButton/logos/dkmitiderhverv.png","../src/components/AuthMethodButton/logos/ftnmobile.png","../src/components/AuthMethodButton/logos/itsme.png","../src/components/AuthMethodButton/logos/nobankid.png","../src/components/AuthMethodButton/logos/novipps.png","../src/components/AuthMethodButton/logos/sebankid.png","../src/components/AuthMethodButton/logos/sefrejaid.png","../src/components/AuthMethodButton/logos/depersonalausweis.png","../src/components/AuthMethodButton/logos/ukoneid.png","../src/components/AuthMethodButton/logos/idin.png","../src/components/AuthMethodButton/logos/ftn.png","../src/components/AuthMethodButton/Logo.tsx","../src/components/Button.tsx","../src/components/AuthMethodButton.tsx","../src/components/AuthMethodSelector.tsx","../src/components/QRCode.tsx","../src/use-criipto-verify.ts"],"sourcesContent":["import CriiptoAuth, {\n OpenIDConfiguration,\n type AuthorizeUrlParamsOptional,\n type PKCE,\n type AuthorizeResponse,\n OAuth2Error,\n type PKCEPublicPart,\n} from '@criipto/auth-js';\nimport type { PopupAuthorizeParams, RedirectAuthorizeParams } from '@criipto/auth-js';\nimport { createContext } from 'react';\n\nexport type ResultSource =\n | 'QRCode'\n | 'SEBankIDQrCode'\n | 'SEBankIDSameDeviceButton'\n | 'redirect'\n | 'popup';\nexport type Result =\n | { id_token: string; state?: string; source?: ResultSource }\n | { code: string; state?: string; source?: ResultSource }\n | OAuth2Error\n | Error;\nexport const actions = ['confirm', 'accept', 'approve', 'sign', 'login'] as const;\nexport type Action = (typeof actions)[number];\nexport type Claims = {\n iss: string;\n aud: string;\n identityscheme: string;\n authenticationtype: string;\n sub: string;\n iat: number;\n exp: number;\n [key: string]: string | number;\n};\n\nexport interface CriiptoVerifyContextInterface {\n loginWithRedirect: (params?: RedirectAuthorizeParams) => Promise<void>;\n loginWithPopup: (params?: PopupAuthorizeParams) => Promise<void>;\n checkSession: () => Promise<void>;\n logout: (params?: { redirectUri?: string; state?: string }) => Promise<void>;\n fetchOpenIDConfiguration: () => Promise<OpenIDConfiguration>;\n buildAuthorizeUrl: (options?: AuthorizeUrlParamsOptional) => Promise<string>;\n initializePAR: (options?: AuthorizeUrlParamsOptional) => Promise<URL>;\n generatePKCE: () => Promise<PKCE | undefined>;\n buildOptions: (\n options?: AuthorizeUrlParamsOptional | RedirectAuthorizeParams,\n ) => AuthorizeUrlParamsOptional;\n handleResponse: (\n response: AuthorizeResponse | (Error | OAuth2Error),\n params?: { pkce?: PKCE; redirectUri?: string; source?: ResultSource },\n ) => Promise<void>;\n responseType: 'token' | 'code';\n completionStrategy: 'client' | 'openidprovider';\n result: Result | null;\n claims: Claims | null;\n domain: string;\n redirectUri?: string;\n action: Action;\n message?: string;\n pkce?: PKCE | PKCEPublicPart;\n store: Storage;\n isLoading: boolean;\n isInitializing: boolean;\n acrValues?: string[];\n uiLocales?: string;\n client: CriiptoAuth;\n loginHint?: string;\n}\n\n/**\n * @ignore\n */\nconst stub = (): never => {\n throw new Error('You forgot to wrap your component in <CriiptoVerifyProvider>.');\n};\n\n/**\n * @ignore\n */\nconst initialContext = {\n loginWithRedirect: stub,\n loginWithPopup: stub,\n checkSession: stub,\n logout: stub,\n fetchOpenIDConfiguration: stub,\n buildAuthorizeUrl: stub,\n initializePAR: stub,\n generatePKCE: stub,\n buildOptions: stub,\n handleResponse: stub,\n responseType: 'token' as 'token' | 'code',\n completionStrategy: 'client' as 'client' | 'openidprovider',\n result: null,\n claims: null,\n domain: '',\n action: 'login' as Action,\n pkce: undefined,\n store: null as any as Storage,\n isLoading: false,\n isInitializing: true,\n client: null as any as CriiptoAuth,\n loginHint: undefined,\n};\n\nconst CriiptoVerifyContext = createContext<CriiptoVerifyContextInterface>(initialContext);\n\nexport default CriiptoVerifyContext;\n","export const en = {\n loginWith: 'Login with',\n approveWith: 'Approve with',\n signWith: 'Sign with',\n confirmWith: 'Confirm with',\n acceptWith: 'Accept with',\n sameDevice: 'On this device',\n anotherDevice: 'With your SSN',\n anotherDeviceQR: 'On another device',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finnish Mobile Certificate',\n finnishBankID: 'Finnish Bank ID',\n swedishBankID: 'Swedish BankID',\n norwegianBankID: 'Norwegian BankID',\n biometrics: 'Biometrics',\n openAndScan: 'Open the BankID app on your mobile device and scan the QR code.',\n thisIsTheQR: 'This is a BankID QR Code. You can click it to view it in full screen.',\n completingLogin: 'Completing your login.',\n} as const;\n","import { type I18N } from '.';\n\nexport const da = {\n loginWith: 'Login med',\n approveWith: 'Godkend med',\n signWith: 'Underskriv med',\n confirmWith: 'Bekræft med',\n acceptWith: 'Accepter med',\n sameDevice: 'På denne enhed',\n anotherDevice: 'Med dit personnummer',\n anotherDeviceQR: 'På anden enhed',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finsk Mobilcertifikat',\n finnishBankID: 'Finsk Bank ID',\n swedishBankID: 'Svensk BankID',\n norwegianBankID: 'Norsk BankID',\n biometrics: 'Biometri',\n openAndScan: 'Åbn BankID appen på din telefon og scan QR koden.',\n thisIsTheQR: 'Dette er en BankID QR-kode. Du kan klikke på den for at se den i fuld skærm.',\n completingLogin: 'Fuldfører dit login.',\n} satisfies I18N;\n","import { type I18N } from '.';\n\nexport const sv = {\n loginWith: 'Logga in med',\n approveWith: 'Godkänn med',\n signWith: 'Signera med',\n confirmWith: 'Bekräfta med',\n acceptWith: 'Acceptera med',\n sameDevice: 'På denna enhet',\n anotherDevice: 'Med ditt personnummer',\n anotherDeviceQR: 'På annan enhet',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finskt Mobilcertifikat',\n finnishBankID: 'Finskt Bank ID',\n swedishBankID: 'Svenskt BankID',\n norwegianBankID: 'Norska BankID',\n biometrics: 'Biometri',\n openAndScan: 'Öppna BankID-appen på din mobila enhet och skanna QR-koden.',\n thisIsTheQR: 'Detta är en QR-kod från BankID. Du kan klicka på den för att visa den i fullskärm.',\n completingLogin: 'Slutför din inloggning.',\n} satisfies I18N;\n","import { type I18N } from '.';\n\nexport const nb = {\n loginWith: 'Logg inn med',\n approveWith: 'Godkjenne med',\n signWith: 'Signer med',\n confirmWith: 'Bekreft med',\n acceptWith: 'Aksepterer med',\n sameDevice: 'På denne enhet',\n anotherDevice: 'Med personnummeret ditt',\n anotherDeviceQR: 'På annan enhet',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finsk Mobilsertifikat',\n finnishBankID: 'Finsk Bank ID',\n swedishBankID: 'Svensk BankID',\n norwegianBankID: 'Norsk BankID',\n biometrics: 'Biometri',\n openAndScan: 'Åpne BankID-appen på mobilenheten din og skann QR-koden.',\n thisIsTheQR: 'Dette er en BankID QR-kode. Du kan klikke på den for å se den i fullskjerm.',\n completingLogin: 'Fullfører påloggingen.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const fi = {\n loginWith: 'Kirjaudu sisään',\n approveWith: 'Hyväksy',\n signWith: 'Allekirjoita',\n confirmWith: 'Vahvista',\n acceptWith: 'Hyväksy',\n sameDevice: 'Tällä laitteella',\n anotherDevice: 'Henkilötunnuksellasi',\n anotherDeviceQR: 'Toisella laitteella',\n mitidBusiness: 'MitID Businessilla',\n finnishMobileID: 'Suomalaisella Mobiilivarmenteella',\n finnishBankID: 'Suomalaisella BankID:llä',\n swedishBankID: 'Ruotsalaisella BankID:llä',\n norwegianBankID: 'Norjalaisella BankID:llä',\n biometrics: 'Biometrisella tunnistautumisella',\n openAndScan: 'Avaa BankID-sovellus mobiililaitteellasi ja skannaa QR-koodi.',\n thisIsTheQR: 'Tämä on BankID-QR-koodi. Voit napsauttaa sitä nähdäksesi sen koko näytöllä',\n completingLogin: 'Sisäänkirjautumista viimeistellään.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const de = {\n loginWith: 'Anmelden mit',\n approveWith: 'Genehmigen mit',\n signWith: 'Unterschreiben mit',\n confirmWith: 'Bestätigen mit',\n acceptWith: 'Akzeptieren mit',\n sameDevice: 'Auf diesem Gerät',\n anotherDevice: 'Mit Ihrer Sozialversicherungsnummer',\n anotherDeviceQR: 'Auf einem anderen Gerät',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finnischem Mobilfunkzertifikat',\n finnishBankID: 'Finnische BankID',\n swedishBankID: 'Schwedische BankID',\n norwegianBankID: 'Norwegische BankID',\n biometrics: 'Biometrie',\n openAndScan: 'Öffnen Sie die BankID-App auf Ihrem mobilen Endgerät und scannen Sie den QR-Code.',\n thisIsTheQR:\n 'Dies ist ein BankID QR-Code. Sie können darauf klicken, um ihn im Vollbildmodus anzuzeigen',\n completingLogin: 'Ihre Anmeldung wird abgeschlossen.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const nl = {\n loginWith: 'Inloggen met',\n approveWith: 'Goedkeuren met',\n signWith: 'Ondertekenen met',\n confirmWith: 'Bevestigen met',\n acceptWith: 'Accepteren met',\n sameDevice: 'Op dit apparaat',\n anotherDevice: 'Met uw SSN',\n anotherDeviceQR: 'Op een ander apparaat',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finse mobiel certificaat',\n finnishBankID: 'Finse BankID',\n swedishBankID: 'Zweedse BankID',\n norwegianBankID: 'Noorse BankID',\n biometrics: 'Biometrie',\n openAndScan: 'Open de BankID-app op uw mobiele apparaat en scan de QR-code.',\n thisIsTheQR:\n 'Dit is een BankID QR-code. U kunt erop klikken om het in een volledig scherm te bekijken',\n completingLogin: 'Uw login voltooien.',\n} satisfies I18N;\n","import { en } from './en';\nimport { da } from './da';\nimport { sv } from './sv';\nimport { nb } from './nb';\nimport { fi } from './fi';\nimport { de } from './de';\nimport { nl } from './nl';\nimport { assertUnreachable } from '../utils';\n\nexport type Language = 'en' | 'da' | 'sv' | 'nb' | 'fi' | 'de' | 'nl';\nexport type I18N = Record<keyof typeof en, string>;\n\nexport function getI18n(language: Language): I18N {\n switch (language) {\n case 'en':\n return en;\n case 'da':\n return da;\n case 'sv':\n return sv;\n case 'nb':\n return nb;\n case 'fi':\n return fi;\n case 'de':\n return de;\n case 'nl':\n return nl;\n default:\n assertUnreachable(language);\n }\n}\n","import type { Action } from './context';\nimport { getI18n, type Language } from './i18n';\n\ndeclare var __VERSION__: string;\nexport const VERSION = typeof __VERSION__ === 'undefined' ? 'N/A' : __VERSION__;\n\nexport const DKMITID_PREFIX = 'urn:grn:authn:dk:mitid';\nexport const DKMITID_BUSINESS = 'urn:grn:authn:dk:mitid:business';\nexport const FTN_PREFIX = 'urn:grn:authn:fi';\n\nexport function lowestMitIDValue(input: string[]): string | null {\n let dkmitidMethod: string | null = null;\n\n input.forEach((s) => {\n if (s.startsWith(DKMITID_PREFIX) && s !== DKMITID_BUSINESS) {\n if (!dkmitidMethod) {\n dkmitidMethod = s;\n } else {\n let newLevel = s.replace(DKMITID_PREFIX, '');\n let oldLevel = dkmitidMethod.replace(DKMITID_PREFIX, '');\n if (newLevel === ':low' && [':substantial', ':high'].includes(oldLevel)) {\n dkmitidMethod = s;\n } else if (newLevel === ':substantial' && oldLevel === ':high') {\n dkmitidMethod = s;\n }\n }\n }\n });\n\n return dkmitidMethod;\n}\n\nfunction autoTitleCase(input: string) {\n var segments = input.split(/:|-/).map((segment) => {\n segment = segment.replace(/id(\\s|$)/, 'ID');\n if (segment.length === 2) return segment.toUpperCase();\n return segment.substr(0, 1).toUpperCase() + segment.substr(1);\n });\n return segments.join(' ');\n}\n\nexport function assertUnreachable(x: never): never {\n throw new Error(\"Didn't expect to get here\");\n}\n\nexport function stringifyAction(language: Language, action: Action): string {\n const i18n = getI18n(language);\n\n switch (action) {\n case 'login':\n return i18n.loginWith;\n case 'approve':\n return i18n.approveWith;\n case 'sign':\n return i18n.signWith;\n case 'confirm':\n return i18n.confirmWith;\n case 'accept':\n return i18n.acceptWith;\n default:\n assertUnreachable(action);\n }\n}\n\nexport function acrValueToProviderPrefix(value: string) {\n value = value.replace('urn:grn:authn:', '');\n\n if (value.startsWith('fi')) {\n return 'fi';\n } else if (value.startsWith('itsme')) {\n return 'itsme';\n } else {\n return value.split(':').slice(0, 2).join(':');\n }\n}\n\nexport function acrValueToTitle(\n language: Language,\n value: string,\n { disambiguate }: { disambiguate: boolean },\n): { title: string; subtitle?: string } {\n const i18n = getI18n(language);\n value = value.replace('urn:grn:authn:', '');\n const provider = acrValueToProviderPrefix(value);\n\n if (provider === 'dk:mitid') {\n let suffix = value.replace('dk:mitid:', '');\n if (suffix === 'business') {\n return {\n title: i18n.mitidBusiness,\n };\n }\n\n return { title: 'MitID' };\n }\n if (value === 'fi:mobile-id') {\n return {\n title: i18n.finnishMobileID,\n };\n }\n if (value === 'fi:bank-id') {\n return {\n title: i18n.finnishBankID,\n };\n }\n if (provider === 'fi') {\n return { title: autoTitleCase(value).replace('FI', 'FTN') };\n }\n if (provider === 'itsme') {\n return { title: autoTitleCase(value).replace('me', 'ME') };\n }\n if (provider === 'se:bankid') {\n let subtitle: string | undefined = undefined;\n let suffix = value.replace('se:bankid:', '');\n let title = 'BankID';\n\n if (suffix === 'same-device') {\n subtitle = i18n.sameDevice;\n }\n if (suffix === 'another-device') {\n subtitle = i18n.anotherDevice;\n }\n if (suffix === 'another-device:qr') {\n subtitle = i18n.anotherDeviceQR;\n }\n if (disambiguate) {\n title = i18n.swedishBankID;\n }\n\n return { title, subtitle };\n }\n if (provider === 'no:bankid') {\n let subtitle: string | undefined = undefined;\n let title = 'BankID';\n if (value.endsWith(':substantial')) {\n subtitle = i18n.biometrics;\n }\n if (disambiguate) {\n title = i18n.norwegianBankID;\n }\n return { title, subtitle };\n }\n if (provider === 'no:vipps') {\n return { title: autoTitleCase(value).replace('NO ', '') };\n }\n if (provider === 'se:frejaid') {\n return { title: 'FrejaID' };\n }\n if (provider === 'uk:oneid') {\n return { title: 'OneID' };\n }\n if (provider === 'de:personalausweis') {\n return { title: 'Personalausweis' };\n }\n\n return { title: autoTitleCase(value) };\n}\n\nexport function filterAcrValues(input: string[]) {\n let original = input.slice();\n let dkmitidMethod: string | null = lowestMitIDValue(input);\n let reduced = input.slice();\n\n if (dkmitidMethod) {\n reduced = input\n .filter((s) => !s.startsWith(DKMITID_PREFIX) || s === DKMITID_BUSINESS)\n .concat([dkmitidMethod])\n .sort((a, b) => original.indexOf(a) - original.indexOf(b));\n }\n\n if (input.includes(`${FTN_PREFIX}:all`)) {\n if (!reduced.includes(`${FTN_PREFIX}:bank-id`)) reduced.push(`${FTN_PREFIX}:bank-id`);\n if (!reduced.includes(`${FTN_PREFIX}:mobile-id`)) reduced.push(`${FTN_PREFIX}:mobile-id`);\n reduced = reduced.filter((s) => s !== `${FTN_PREFIX}:all`);\n }\n return reduced;\n}\n\nexport function isSingle(acrValue: string, acrValues: string[]) {\n const provider = acrValueToProviderPrefix(acrValue);\n const count = acrValues.reduce(\n (memo, acrValue) => memo + (acrValueToProviderPrefix(acrValue) === provider ? 1 : 0),\n 0,\n );\n return count === 1;\n}\n\nconst ambigousProviders = ['se:bankid', 'no:bankid'];\n/**\n * A provider is considered ambiguous iff:\n * 1. It is in the list of ambiguous providers\n * 2. There is another ambiguous provider in the arc values list\n */\nexport function isAmbiguous(acrValue: string, acrValues: string[]) {\n const provider = acrValueToProviderPrefix(acrValue);\n const isProviderAmbiguous = ambigousProviders.includes(provider);\n const otherAmbiguousProvider =\n acrValues.find((otherAcrValue) => {\n const otherProvider = acrValueToProviderPrefix(otherAcrValue);\n return provider != otherProvider && ambigousProviders.includes(otherProvider);\n }) != null;\n\n return isProviderAmbiguous && otherAmbiguousProvider;\n}\n\nexport function trySessionStorage() {\n try {\n if (typeof sessionStorage === 'undefined') {\n return null;\n }\n return sessionStorage;\n } catch (err) {\n /**\n * Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.\n * (if storage is disabled in the browser)\n */\n return null;\n }\n}\n","export function createMemoryStorage(): Storage {\n let store: { [key: string]: string } = {};\n\n return {\n getItem(key: string) {\n return store[key] || null;\n },\n setItem(key: string, value: any) {\n store[key] = value.toString();\n },\n removeItem(key: string) {\n delete store[key];\n },\n clear() {\n store = {};\n },\n key(index) {\n return Object.keys(store)[index];\n },\n get length() {\n return Object.keys(store).length;\n },\n };\n}\n","import React, { useMemo, useState, useCallback, useEffect } from 'react';\nimport CriiptoAuth, {\n type AuthorizeUrlParamsOptional,\n clearPKCEState,\n generatePKCE,\n OAuth2Error,\n OpenIDConfiguration,\n type PKCE,\n type PKCEPublicPart,\n type Prompt,\n parseAuthorizeResponseFromLocation,\n} from '@criipto/auth-js';\n\nimport CriiptoVerifyContext, {\n type CriiptoVerifyContextInterface,\n type Action,\n type Result,\n type Claims,\n actions,\n type ResultSource,\n} from './context';\nimport type { AuthorizeResponse, RedirectAuthorizeParams, ResponseType } from '@criipto/auth-js';\n\nimport { filterAcrValues, trySessionStorage, VERSION } from './utils';\nimport jwtDecode from 'jwt-decode';\nimport { createMemoryStorage } from './memory-storage';\n\nconst SESSION_KEY = `@criipto-verify-react/session`;\n\nexport interface CriiptoVerifyProviderOptions {\n domain: string;\n clientID: string;\n /**\n * @deprecated Development use only\n */\n protocol?: 'https' | 'http';\n\n redirectUri?: string;\n children: React.ReactNode;\n pkce?: PKCEPublicPart;\n state?: string;\n nonce?: string;\n prompt?: Prompt;\n scope?: string;\n uiLocales?: string;\n loginHint?: string;\n /**\n * Enables storage and automatic fetch of tokens\n * by utilizing browser storage and SSO silent logins.\n * Make sure \"SSO for OAuth2\" is enabled on your Criipto Domain.\n * Only works for `response: 'token'` (default)\n */\n sessionStore?: Storage;\n /**\n * Will ammend the login_hint parameter with `action:{action}` which will adjust texsts in certain flows.\n * Default: 'login'\n */\n action?: Action;\n /**\n * Will ammend the login_hint parameter with `message:{base64(message)}` which will set a login/aprove message where available (Danish MitID).\n */\n message?: string;\n /**\n * Note: In most cases modifying this setting **is not needed**. Defaults will work with almost all React SPA cases.\n * By default @criipto/verify-react will do PKCE on your behalf and return a jwt token.\n * However if you wish you can disable this and get the raw `code` response by setting `response` to 'code'.\n */\n response?: 'token' | 'code';\n /*\n * Note: In most cases modifying this setting **is not needed**. Defaults will work with almost all React SPA cases.\n * By default @criipto/verify-react will do as much as work on your behalf\n * by interpreting URL parameters and responses with `useCriiptoVerify()` via the default value 'client'.\n * If you wish to only render a UI and redirect to the Criipto IDP for server side code exchange, you can choose 'openidprovider'.\n */\n completionStrategy?: 'client' | 'openidprovider';\n\n /**\n * @deprecated Criipto internal use\n */\n criiptoSdk?: null | string;\n /**\n * @deprecated Criipto internal use\n */\n responseType?: ResponseType | 'code id_token';\n /**\n * @deprecated Criipto internal use\n */\n responseMode?: 'query' | 'form_post' | 'fragment' | 'json' | 'post_message';\n}\n\nexport const ACTION_SUPPORTING_ACR_VALUES = [\n 'urn:grn:authn:dk:mitid:low',\n 'urn:grn:authn:dk:mitid:substantial',\n 'urn:grn:authn:dk:mitid:high',\n 'urn:grn:authn:se:bankid:same-device',\n 'urn:grn:authn:se:bankid:another-device:qr',\n];\n\nexport const MESSAGE_SUPPORTING_ACR_VALUES = [\n 'urn:grn:authn:dk:mitid:low',\n 'urn:grn:authn:dk:mitid:substantial',\n 'urn:grn:authn:dk:mitid:high',\n 'urn:grn:authn:se:bankid:same-device',\n 'urn:grn:authn:se:bankid:another-device:qr',\n];\n\nexport function buildLoginHint(\n loginHint: string | undefined | null,\n params: { options?: AuthorizeUrlParamsOptional; action?: Action; message?: string },\n) {\n const { options, action, message } = params;\n const acrValues = options?.acrValues\n ? Array.isArray(options?.acrValues)\n ? options?.acrValues\n : [options?.acrValues]\n : [];\n let hints = (loginHint ? loginHint.split(' ') : [])\n .concat(options?.loginHint ? options?.loginHint.split(' ') : [])\n .filter((hint) => !hint.startsWith('message:') && !hint.startsWith('action:'));\n if (action) {\n hints = hints.filter((h) => !h.startsWith('action:'));\n if (acrValues.length === 1) {\n if (ACTION_SUPPORTING_ACR_VALUES.includes(acrValues[0])) {\n hints.push(`action:${action}`);\n }\n } else if (acrValues.length >= 2) {\n if (acrValues.some((v) => ACTION_SUPPORTING_ACR_VALUES.includes(v))) {\n hints.push(`action:${action}`);\n }\n } else {\n hints.push(`action:${action}`);\n }\n }\n\n if (message) {\n if (acrValues.length === 1) {\n if (MESSAGE_SUPPORTING_ACR_VALUES.includes(acrValues[0])) {\n hints.push(`message:${btoa(message)}`);\n }\n } else if (acrValues.length >= 2) {\n if (acrValues.some((v) => MESSAGE_SUPPORTING_ACR_VALUES.includes(v))) {\n hints.push(`message:${btoa(message)}`);\n }\n } else {\n hints.push(`message:${btoa(message)}`);\n }\n }\n\n return hints.length ? hints.join(' ') : undefined;\n}\n\nfunction parseAction(input?: string): Action | undefined {\n if (!input) return;\n\n const segments = input.split(' ');\n const actionCandidate = segments.find((s) => s.startsWith('action:'));\n if (!actionCandidate) return;\n const action = actionCandidate.replace('action:', '');\n if (actions.includes(action as any)) return action as Action;\n return;\n}\n\nfunction tryBase64Decode(input: string) {\n try {\n return atob(input);\n } catch {\n return null;\n }\n}\nfunction parseMessage(input?: string): string | undefined {\n if (!input) return;\n const segments = input.split(' ');\n const messageCandidate = segments.find((s) => s.startsWith('message:'));\n if (!messageCandidate) return;\n\n const message = messageCandidate.replace('message:', '');\n return tryBase64Decode(message) ?? message;\n}\n\nfunction defaultRedirectUri(input?: string): string {\n if (input) return input;\n if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {\n return window.location.origin + window.location.pathname;\n }\n\n throw new Error('Unable to determine default redirect uri, please provide a redirectUri');\n}\n\nconst pkceStore = (() => {\n const sessionStorage = trySessionStorage();\n if (sessionStorage === null) {\n console.warn(\n 'Creating memory store for PKCE values as no sessionStorage is available. Authentication may be broken.',\n );\n return createMemoryStorage();\n }\n return sessionStorage;\n})();\n\nconst CriiptoVerifyProvider = (props: CriiptoVerifyProviderOptions): React.ReactElement => {\n const client = useMemo(\n () =>\n new CriiptoAuth({\n domain: props.domain,\n clientID: props.clientID,\n store: pkceStore,\n redirectUri: defaultRedirectUri(props.redirectUri),\n protocol: props.protocol,\n }),\n [props.domain, props.clientID, props.redirectUri, props.protocol],\n );\n\n const [configuration, setConfiguration] = useState<OpenIDConfiguration | null>(null);\n useEffect(() => {\n let isSubscribed = true;\n (async () => {\n const configuration = await client.fetchOpenIDConfiguration();\n if (isSubscribed) setConfiguration(configuration);\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [client]);\n\n const [result, setResult] = useState<Result | null>(null);\n\n // Verify that domain and client id are valid; surface failures as the hook's `error`.\n useEffect(() => {\n let isSubscribed = true;\n (async () => {\n try {\n await client.fetchCriiptoConfiguration();\n } catch (error) {\n if (!isSubscribed) return;\n const err = error instanceof Error ? error : new Error(String(error));\n setResult((prev) => prev ?? err);\n }\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [client]);\n const claims = useMemo(() => {\n if (!result) return null;\n if (!('id_token' in result)) return null;\n return jwtDecode<Claims>(result.id_token);\n }, [result]);\n const [isLoading, setIsLoading] = useState(false);\n const [isInitializing, setIsInitializing] = useState(true);\n const [pkce, setPKCE] = useState<PKCE | PKCEPublicPart | undefined>(props.pkce);\n const responseType = props.response || 'token';\n const completionStrategy = props.completionStrategy || 'client';\n const uiLocales = props.uiLocales;\n const loginHint = props.loginHint;\n const action = props.action ?? parseAction(loginHint) ?? 'login';\n const message = props.message ?? parseMessage(loginHint);\n const sessionStore = props.sessionStore;\n\n const refreshPKCE = async () => {\n if (props.pkce) return props.pkce;\n if (responseType !== 'token' || completionStrategy !== 'client') {\n clearPKCEState(pkceStore);\n setPKCE(undefined);\n return undefined;\n }\n\n clearPKCEState(pkceStore);\n\n const pkce = await generatePKCE();\n setPKCE(pkce);\n return pkce;\n };\n\n const buildOptions = useCallback(\n (\n options?: AuthorizeUrlParamsOptional | RedirectAuthorizeParams,\n ): AuthorizeUrlParamsOptional => {\n return {\n redirectUri: defaultRedirectUri(props.redirectUri),\n responseType: (props.responseType ?? 'code') as ResponseType,\n responseMode: props.responseMode,\n ...(options || {}),\n state: props.state ?? options?.state,\n nonce: props.nonce ?? options?.nonce,\n prompt: props.prompt ?? options?.prompt,\n scope: props.scope ?? options?.scope,\n uiLocales: uiLocales ?? options?.uiLocales,\n pkce: options?.pkce ?? pkce,\n loginHint: buildLoginHint(props.loginHint, { options, action, message }),\n extraUrlParams:\n props.criiptoSdk !== undefined\n ? {\n criipto_sdk: props.criiptoSdk,\n }\n : {\n criipto_sdk: `@criipto/verify-react@${VERSION}`,\n },\n };\n },\n [\n pkce,\n props.state,\n props.nonce,\n props.prompt,\n props.scope,\n uiLocales,\n action,\n message,\n props.redirectUri,\n props.criiptoSdk,\n props.loginHint,\n props.responseMode,\n props.responseType,\n ],\n );\n\n const buildAuthorizeUrl = useCallback(\n async (options?: AuthorizeUrlParamsOptional) => {\n return await client.buildAuthorizeUrl(client.buildAuthorizeParams(buildOptions(options)));\n },\n [client, buildOptions],\n );\n\n const initializePAR = useCallback(\n async (options?: AuthorizeUrlParamsOptional) => {\n return (\n await client.pushAuthorizationRequest(client.buildAuthorizeParams(buildOptions(options)))\n ).authorizeUrl;\n },\n [client, buildOptions],\n );\n\n const handleResponse = useCallback(\n async (\n response: AuthorizeResponse | (Error | OAuth2Error),\n params: { pkce?: PKCE; redirectUri?: string; source?: ResultSource } = {},\n ) => {\n if (response instanceof OAuth2Error) {\n setResult(response);\n } else if (response instanceof Error) {\n setResult(response);\n } else if (params.pkce && responseType === 'token') {\n let _redirectUri = params.redirectUri || defaultRedirectUri(props.redirectUri);\n if (!_redirectUri)\n throw new Error(\n 'redirectUri must be configured globally or per authentication component',\n );\n\n await client\n .processResponse(response, {\n code_verifier: params.pkce.code_verifier,\n redirect_uri: _redirectUri,\n })\n .then((response) => {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: params.source });\n else if (response?.id_token) {\n setResult({\n id_token: response.id_token,\n state: response.state,\n source: params.source,\n });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else setResult(null);\n })\n .catch((err: OAuth2Error) => {\n setResult(err);\n });\n } else {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: params.source });\n else if (response?.id_token) {\n setResult({ id_token: response.id_token, state: response.state, source: params.source });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else if (response?.error)\n setResult(new OAuth2Error(response.error, response.error_description, response.state));\n else setResult(null);\n }\n\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n },\n [refreshPKCE, responseType, setResult, client, sessionStore, props.redirectUri],\n );\n\n const checkSession = useCallback(async () => {\n return client\n .checkSession({ redirectUri: defaultRedirectUri(props.redirectUri) })\n .then((response) => {\n if (response?.code) setResult({ code: response.code });\n else if (response?.id_token) {\n setResult({ id_token: response.id_token });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else setResult(null);\n });\n }, [sessionStore, client, props.redirectUri]);\n\n const logout = useCallback(\n async (params?: { redirectUri?: string; state?: string }) => {\n sessionStore?.removeItem(SESSION_KEY);\n await client.logout({\n redirectUri: params?.redirectUri ?? defaultRedirectUri(props.redirectUri),\n state: params?.state,\n });\n },\n [sessionStore, client, props.redirectUri],\n );\n\n const context = useMemo<CriiptoVerifyContextInterface>(() => {\n return {\n loginWithRedirect: async (params) => {\n const pkce = await refreshPKCE();\n await client.redirect.authorize(buildOptions({ ...params, pkce }));\n },\n loginWithPopup: async (params) => {\n return client.popup\n .authorize(buildOptions(params))\n .then((response) => {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: 'popup' });\n else if (response?.id_token)\n setResult({ id_token: response.id_token, state: response.state, source: 'popup' });\n else setResult(null);\n })\n .catch((err: OAuth2Error) => {\n setResult(err);\n });\n },\n checkSession,\n logout,\n fetchOpenIDConfiguration: () => client.fetchOpenIDConfiguration(),\n buildAuthorizeUrl,\n initializePAR,\n generatePKCE: async () => {\n if (responseType !== 'token' || completionStrategy !== 'client') return;\n return await generatePKCE();\n },\n buildOptions,\n handleResponse,\n responseType,\n completionStrategy,\n result,\n claims,\n domain: client.domain,\n redirectUri: defaultRedirectUri(props.redirectUri),\n action,\n message,\n pkce,\n store: pkceStore,\n isLoading,\n isInitializing,\n acrValues: configuration ? filterAcrValues(configuration.acr_values_supported) : undefined,\n client,\n uiLocales,\n loginHint,\n };\n }, [\n client,\n props.redirectUri,\n responseType,\n completionStrategy,\n result,\n claims,\n action,\n message,\n pkce,\n props.state,\n props.prompt,\n isLoading,\n isInitializing,\n handleResponse,\n logout,\n configuration,\n uiLocales,\n checkSession,\n loginHint,\n ]);\n\n useEffect(() => {\n setIsInitializing(false);\n if (!client.redirect.hasMatch()) {\n refreshPKCE(); // Fresh request, setup PKCE\n return;\n }\n\n let isSubscribed = true;\n setIsLoading(true);\n\n const params = parseAuthorizeResponseFromLocation(window.location);\n if (params.code && responseType === 'code') {\n setIsLoading(false);\n setResult({ code: params.code, source: 'redirect', state: params.state });\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n return;\n }\n\n (async () => {\n await Promise.resolve(); // wait for the initial cleanup in Strict mode - avoids double mutation\n if (!isSubscribed) return;\n\n try {\n const response = await client.redirect.match();\n if (!isSubscribed) return;\n\n if (response?.code) {\n setResult({ code: response.code, source: 'redirect', state: response.state });\n } else if (response?.id_token) {\n setResult({ id_token: response.id_token, source: 'redirect', state: response.state });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n resetRedirectState(window);\n } else setResult(null);\n } catch (err: any) {\n if (!isSubscribed) return;\n if (err instanceof OAuth2Error) {\n setResult(err);\n } else if (err instanceof Error) {\n setResult(err);\n } else {\n setResult(new Error(err?.toString() ?? 'Unknown error ocurred'));\n }\n } finally {\n if (!isSubscribed) return;\n setIsLoading(false);\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n }\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [props.pkce, responseType]);\n\n /*\n * Fetch claims from session store if available\n */\n useEffect(() => {\n if (!sessionStore || claims) return;\n if (!claims) {\n // No result available, fetch from session store\n const token = sessionStore.getItem(SESSION_KEY);\n if (!token) return;\n\n setResult({ id_token: token });\n return;\n }\n }, [sessionStore, claims]);\n\n /*\n * Unset result if claims are expired\n */\n useEffect(() => {\n if (!claims) return;\n if (!sessionStore) return;\n\n const interval = setInterval(() => {\n const now = Date.now();\n if (claims.exp < now / 1000) {\n setResult(null);\n sessionStore?.removeItem(SESSION_KEY);\n return;\n }\n }, 5000);\n\n return () => clearInterval(interval);\n }, [sessionStore, claims, result]);\n\n /**\n * Fresh page load SSO check\n */\n useEffect(() => {\n setIsInitializing(false);\n if (!sessionStore) return;\n if (client.redirect.hasMatch()) return; // Do not issue SSO check if we're just being redirected back to\n if (sessionStore.getItem(SESSION_KEY)) return;\n let isSubscribed = true;\n\n setIsLoading(true);\n checkSession()\n .catch((err) => {\n console.error('session silent check error', err);\n })\n .finally(() => {\n if (isSubscribed) setIsLoading(false);\n });\n\n return () => {\n isSubscribed = false;\n };\n }, [sessionStore, client]);\n\n return (\n <CriiptoVerifyContext.Provider value={context}>{props.children}</CriiptoVerifyContext.Provider>\n );\n};\n\nexport default CriiptoVerifyProvider;\n\nexport function resetRedirectState(window: Window) {\n const url = new URL(window.location.href);\n url.searchParams.delete('code');\n url.searchParams.delete('state');\n\n window.history.replaceState({}, window.document.title, url.pathname + url.search);\n}\n","import { UAParser } from '@ua-parser-js/pro-enterprise';\n\nfunction testUA(userAgent: string, pattern: RegExp) {\n return pattern.test(navigator.userAgent);\n}\nexport function isiOS(userAgent: string) {\n return testUA(userAgent, /iPad|iPhone|iPod/) && !(window as any).MSStream;\n}\n\nexport function isiOSSafari(userAgent: string) {\n return isiOS(userAgent) && !testUA(userAgent, / CriOS\\/[.0-9]*/);\n}\n\nexport function isAndroid(userAgent: string) {\n return testUA(userAgent, /Android/);\n}\n\nexport type MobileOS = 'ios' | 'android';\n\nexport function getMobileOS(userAgent: string): MobileOS | null {\n if (isiOS(userAgent)) return 'ios';\n if (isAndroid(userAgent)) return 'android';\n\n return null;\n}\n\nexport function getUserAgent(userAgent?: string) {\n if (!userAgent) return null;\n return UAParser(userAgent);\n}\n","import { useEffect } from 'react';\n\nexport interface UsePollProps {\n shouldPoll: boolean;\n pollUrl: string;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => void;\n}\n\nexport function usePoll({ shouldPoll, pollUrl, onComplete, onError }: UsePollProps) {\n useEffect(() => {\n if (!shouldPoll) return;\n let isSubscribed = true;\n let timeout: string | undefined;\n const poll = async () => {\n if (!isSubscribed) return;\n const response = await fetch(pollUrl);\n\n if (response.status === 202) {\n setTimeout(poll, 1000);\n return;\n } else if (response.status >= 400) {\n if (!isSubscribed) return;\n const error = await response.text();\n onError(error);\n return;\n } else {\n if (!isSubscribed) return;\n const { targetUrl } = await response.json();\n onComplete(targetUrl);\n return;\n }\n };\n\n setTimeout(poll, 1000);\n return () => {\n isSubscribed = false;\n if (timeout) clearTimeout(timeout);\n };\n }, [shouldPoll, pollUrl]);\n}\n","import React, { useContext, useState } from 'react';\nimport CriiptoVerifyContext from '../../context';\nimport type { Links } from './shared';\nimport { usePoll } from './usePoll';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n}\n\n/*\n * Desktop: Polling scenario\n */\nexport default function SEBankIDSameDevicePoll(props: Props) {\n const { links, onError, onComplete, onInitiate } = props;\n const [initiated, setInitiated] = useState(false);\n const { domain } = useContext(CriiptoVerifyContext);\n\n usePoll({\n ...props,\n shouldPoll: initiated,\n pollUrl: links.pollUrl,\n });\n const handleInitiate = () => {\n onInitiate();\n setInitiated(true);\n };\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","import React, { useRef, useState, useEffect } from 'react';\n\nexport default function usePageVisibility(onVisible?: () => void, deps: React.DependencyList = []) {\n const visibilityState = useRef(document.visibilityState);\n const [state, setState] = useState(visibilityState.current);\n\n useEffect(() => {\n document.addEventListener('visibilitychange', _handleVisibilityChange);\n\n return () => {\n document.removeEventListener('visibilitychange', _handleVisibilityChange);\n };\n }, deps);\n\n const _handleVisibilityChange = () => {\n const nextState = document.visibilityState;\n if (visibilityState.current === 'hidden' && nextState === 'visible') {\n if (onVisible) onVisible();\n }\n\n visibilityState.current = nextState;\n setState(visibilityState.current);\n };\n\n return state;\n}\n","import React, { useCallback, useEffect, useState } from 'react';\nimport usePageVisibility from '../../hooks/usePageVisibility';\nimport type { Links } from './shared';\nimport { usePoll } from './usePoll';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n}\n\n/*\n * Android + iOS Chrome: Background/Foreground scenario\n */\nexport default function SEBankIDSameDeviceForeground(props: Props) {\n const { links, onInitiate, onLog } = props;\n const [initiated, setInitiated] = useState(false);\n\n // Polling might complete while the browser is in the background, but we don't want to invoke the\n // complete callbacks before the browser is focused. So we store the result here.\n const [result, setResult] = useState<{ result: string } | { error: string } | null>(null);\n\n const onComplete = useCallback((completeUrl: string) => setResult({ result: completeUrl }), []);\n const onError = useCallback((error: string) => setResult({ error: error }), []);\n\n const visibility = usePageVisibility(() => {\n onLog('ForegroundStrategy', 'onForeground', initiated.toString());\n }, [initiated]);\n\n useEffect(() => {\n if (result && visibility === 'visible') {\n if ('result' in result) {\n props.onComplete(result.result);\n } else if ('error' in result) {\n props.onError(result.error);\n }\n // Clear result, so we don't call error / complete several times, if visibility changes\n setResult(null);\n }\n }, [result, visibility]);\n\n usePoll({\n shouldPoll: initiated,\n pollUrl: links.pollUrl,\n onComplete,\n onError,\n });\n\n const handleInitiate = () => {\n onLog('ForegroundStrategy', 'handleInitiate');\n onInitiate();\n setInitiated(true);\n };\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","import type { PKCE } from '@criipto/auth-js';\nimport { createMemoryStorage } from '../../memory-storage';\nimport { trySessionStorage } from '../../utils';\n\nexport interface Links {\n cancelUrl: string;\n completeUrl: string;\n pollUrl: string;\n launchLinks: {\n customFileHandlerUrl: string;\n universalLink: string;\n };\n}\n\nexport interface State {\n pkce: PKCE | undefined;\n redirectUri: string;\n links: Links;\n}\n\nconst STATE_KEY = '@criipto/verify-react:sebankid:state';\n\nconst stateStore = (() => {\n const sessionStorage = trySessionStorage();\n if (sessionStorage === null) {\n console.warn(\n 'Creating memory store for PKCE values as no sessionStorage is available. Authentication may be broken.',\n );\n return createMemoryStorage();\n }\n return sessionStorage;\n})();\n\nexport function hydrateState(): State | undefined {\n const rawState = stateStore.getItem(STATE_KEY);\n if (rawState) {\n return JSON.parse(rawState) as State;\n }\n\n return undefined;\n}\n\nexport const autoHydratedState = hydrateState();\n\nexport function clearState() {\n stateStore.removeItem(STATE_KEY);\n}\n\nexport function saveState(input: State): void {\n stateStore.setItem(STATE_KEY, JSON.stringify(input));\n}\n","import type { PKCE } from '@criipto/auth-js';\nimport React, { useEffect, useState } from 'react';\nimport { type Links, saveState, hydrateState, clearState } from './shared';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n pkce: PKCE | undefined;\n redirectUri: string;\n}\n\n/*\n * iOS Safari: Page reload on switch back scenario\n */\n\nexport default function SEBankIDSameDeviceReload(props: Props) {\n const { links, onError, onComplete, onInitiate, onLog, pkce, redirectUri } = props;\n\n const handleInitiate = () => {\n onLog('ReloadStrategy', 'handleInitiate');\n\n saveState({\n links,\n redirectUri,\n pkce,\n });\n\n onInitiate();\n };\n\n useEffect(() => {\n const hydratedState = hydrateState();\n if (!hydratedState) return;\n clearState();\n onComplete(hydratedState.links.completeUrl);\n }, []);\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","\"data:image/png;base64,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\"","import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { type AuthorizeResponse, OAuth2Error, type PKCE } from '@criipto/auth-js';\nimport QRCode from 'qrcode';\nimport { type Language } from '../i18n';\n\nimport CriiptoVerifyContext from '../context';\n\nimport logo from './SEBankIDQRCode/logo@2x.png';\nimport './SEBankIDQRCode/SEBankIDQRCode.css';\nimport { getI18n } from '../i18n';\n\ninterface Props {\n redirectUri?: string;\n qrMargin?: number;\n /**\n * Impacts the help text\n */\n language?: Language;\n children?: (props: {\n qrElement: React.ReactElement;\n /**\n * Can be rendered instead of `qrElement` if you only wish to render the qr code with no additional content.\n * Combine with `qrMargin`.\n */\n imageElement: React.ReactElement;\n /**\n * Will be true once the user has completed login in the app and the rest of the login flow is being processed\n */\n isCompleting: boolean;\n /**\n * The user has clicked on the qr image element to trigger fullscreen view per https://developers.bankid.com/getting-started/qr-code#accessibility\n */\n fullscreen: boolean;\n error: OAuth2Error | Error | null;\n retry: () => void;\n }) => React.ReactElement;\n\n /** Render fallback element while loading */\n fallback?: React.ReactElement;\n}\n\ninterface QrResponse {\n initialQrCode: string;\n pollUrl: string;\n}\ninterface PollResponse {\n qrCode?: string;\n targetUrl?: string;\n}\n\nfunction searchParamsToPOJO(input: URLSearchParams) {\n return Array.from(input.keys()).reduce((memo: { [key: string]: string }, key) => {\n memo[key] = input.get(key)!;\n return memo;\n }, {});\n}\n\nexport default function SEBankIDQrCode(props: Props) {\n const wrapperRef = useRef<HTMLButtonElement>(null);\n const {\n buildAuthorizeUrl,\n completionStrategy,\n handleResponse,\n generatePKCE,\n redirectUri: defaultRedirectURi,\n uiLocales,\n } = useContext(CriiptoVerifyContext);\n const language = (props.language ?? uiLocales ?? 'en') as Language;\n const redirectUri = props.redirectUri || defaultRedirectURi;\n const [qrCode, setQrCode] = useState<string | null>(null);\n const [pollUrl, setPollUrl] = useState<string | null>(null);\n const [error, setError] = useState<OAuth2Error | Error | null>(null);\n const [pkce, setPKCE] = useState<PKCE | undefined>(undefined);\n const [isCompleting, setCompleting] = useState(false);\n const [fullscreen, setFullscreen] = useState(false);\n\n const refresh = useCallback(async () => {\n setError(null);\n setQrCode(null);\n setPollUrl(null);\n setPKCE(undefined);\n\n const pkce = await generatePKCE();\n\n buildAuthorizeUrl({\n acrValues: 'urn:grn:authn:se:bankid:another-device:qr',\n responseMode: 'json',\n pkce,\n redirectUri,\n prompt: 'login', // Triggering SSO at this point would be a mistake\n })\n .then((url) => {\n return fetch(url).then((response) => response.json() as Promise<QrResponse>);\n })\n .then((response) => {\n setPKCE(pkce);\n setQrCode(response.initialQrCode);\n setPollUrl(response.pollUrl);\n })\n .catch(console.error);\n }, [buildAuthorizeUrl, redirectUri]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const handleRetry = () => {\n setCompleting(false);\n refresh();\n };\n\n const handleError = useCallback(\n (error: string) => {\n /* Timeout error */\n if (error === 'Collect failed: startFailed' || error === '\"Collect failed: startFailed\"') {\n handleRetry();\n return;\n }\n setError(new Error(error));\n handleResponse(new Error(error), {\n pkce,\n redirectUri,\n source: 'SEBankIDQrCode',\n });\n },\n [pkce, redirectUri],\n );\n\n const handleComplete = useCallback(\n async (completeUrl: string) => {\n setCompleting(true);\n const required = { pkce };\n const parsed = await parseCompleteUrl(completeUrl);\n\n if (parsed instanceof Error) {\n return handleError(parsed.message);\n }\n\n const { location, response } = parsed;\n\n if (completionStrategy === 'openidprovider') {\n window.location.href = location;\n return;\n }\n await handleResponse(response, {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDQrCode',\n });\n },\n [completionStrategy, pkce],\n );\n\n /**\n * Render QR codes\n */\n const qrDataURL = useDraw(qrCode, {\n width: fullscreen\n ? (window.innerHeight ?? wrapperRef.current?.offsetWidth)\n : wrapperRef.current?.offsetWidth,\n // 2 is half of the default 4, less margin is required in fullscreen\n qrMargin: props.qrMargin ?? (fullscreen ? 2 : undefined),\n });\n\n /**\n * Poll for response\n */\n usePoll(pollUrl, {\n enabled: !isCompleting,\n onQrCode: setQrCode,\n onComplete: handleComplete,\n onError: handleError,\n });\n\n const i18n = getI18n(language);\n\n const imageElement = (\n <button\n aria-label={i18n.thisIsTheQR}\n ref={wrapperRef}\n className=\"criipto-se-bankid-qr-canvas\"\n onClick={() => setFullscreen((val) => !val)}\n >\n {qrDataURL ? <img src={qrDataURL} /> : null}\n </button>\n );\n\n const qrElement = (\n <div className=\"criipto-se-bankid-qr\">\n <aside className=\"criipto-se-bankid-qr--help-text\">\n {isCompleting ? i18n.completingLogin : i18n.openAndScan}\n <img src={logo} />\n </aside>\n\n {imageElement}\n </div>\n );\n\n if (!qrCode && props.fallback) {\n return props.fallback;\n }\n\n if (props.children) {\n return props.children({\n qrElement,\n imageElement,\n error,\n isCompleting,\n retry: () => handleRetry(),\n fullscreen,\n });\n }\n\n if (fullscreen) {\n return (\n <dialog className=\"criipto-se-bankid-qr-fullscreen\" open>\n {imageElement}\n </dialog>\n );\n }\n\n return qrElement;\n}\n\nSEBankIDQrCode.acr_values = 'urn:grn:authn:se:bankid:another-device:qr';\n\ntype UseDrawOptions = {\n width?: number;\n qrMargin?: number;\n};\nexport function useDraw(qrCode: string | null, options: UseDrawOptions) {\n const { width, qrMargin } = options;\n const [dataURL, setDataURL] = useState<string | null>(null);\n\n useEffect(() => {\n if (!qrCode) return;\n\n let isSubscribed = true;\n (async () => {\n const qrImage = await QRCode.toDataURL(qrCode, {\n errorCorrectionLevel: 'low',\n scale: 10,\n width,\n margin: qrMargin ?? 4,\n });\n\n if (!isSubscribed) return;\n setDataURL(qrImage);\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [qrCode, qrMargin, width]);\n\n return dataURL;\n}\n\ntype UsePollOptions = {\n enabled: boolean;\n onQrCode: (code: string) => void;\n onComplete: (url: string) => void;\n onError: (error: string) => void;\n};\nexport function usePoll(pollUrl: string | null, options: UsePollOptions) {\n const { onQrCode, onComplete, onError, enabled } = options;\n useEffect(() => {\n if (!pollUrl) return;\n if (!enabled) return;\n\n const delay = 2500;\n let timeout: any;\n let isSubscribed = true;\n const poll = async () => {\n if (!isSubscribed) return;\n const response = await fetch(pollUrl);\n\n if (!isSubscribed) return;\n if (response.status < 400) {\n const payload = (await response.json()) as PollResponse;\n if (payload.qrCode) onQrCode(payload.qrCode);\n if (payload.targetUrl) {\n onComplete(payload.targetUrl);\n return;\n }\n } else {\n const text = await response.text();\n onError(text);\n }\n\n if (response.status === 202) {\n timeout = setTimeout(poll, delay);\n }\n };\n\n timeout = setTimeout(poll, delay);\n return () => {\n isSubscribed = false;\n clearTimeout(timeout);\n };\n }, [pollUrl, onQrCode, onComplete, onError, enabled]);\n}\n\nexport async function parseCompleteUrl(\n completeUrl: string,\n): Promise<{ location: string; response: AuthorizeResponse } | Error> {\n /**\n * Handle verify response inconsistencies\n */\n if (completeUrl.includes('error=')) {\n const url = new URL(completeUrl);\n const completeParams = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n\n return { location: completeUrl, response: completeParams };\n }\n\n const completeResponse = await fetch(completeUrl);\n if (completeResponse.status >= 400) {\n return new Error(await completeResponse.text());\n }\n\n const { location }: { location: string } = await completeResponse.json();\n const url = new URL(location);\n const params = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n return { location: location, response: params };\n}\n","import React, { createContext, useState } from 'react';\nimport {\n AuthMethodButtonContainer,\n type AuthMethodButtonContainerProps,\n AuthMethodButtonComponent,\n type AuthMethodButtonComponentProps,\n} from './AuthMethodButton';\nimport SEBankIDQrCode from './SEBankIDQRCode';\n\ninterface AuthButtonGroupContextInterface {\n multiple: boolean;\n acrValues: string[];\n disabled: boolean;\n setDisabled: (disabled: boolean) => void;\n}\nconst initialContext: AuthButtonGroupContextInterface = {\n multiple: false,\n acrValues: [],\n disabled: false,\n setDisabled: () => {},\n};\nexport const AuthButtonGroupContext =\n createContext<AuthButtonGroupContextInterface>(initialContext);\n\nexport default function AuthButtonGroup(props: { children: React.ReactNode }) {\n const acrValues = React.Children.toArray(props.children).flatMap((child) => {\n if (!child || typeof child !== 'object') return [];\n if ('type' in child) {\n if (child.type === AuthMethodButtonContainer) {\n const props = child.props as AuthMethodButtonContainerProps;\n return props.acrValue ? [props.acrValue] : [];\n }\n if (child.type === AuthMethodButtonComponent) {\n const props = child.props as AuthMethodButtonComponentProps;\n return props.acrValue ? [props.acrValue] : [];\n }\n if (child.type === SEBankIDQrCode) {\n return ['urn:grn:authn:se:bankid:another-device:qr'];\n }\n }\n return [];\n });\n const [disabled, setDisabled] = useState(false);\n\n const context: AuthButtonGroupContextInterface = {\n multiple: acrValues.length > 1,\n acrValues,\n disabled,\n setDisabled,\n };\n return (\n <AuthButtonGroupContext.Provider value={context}>\n {props.children}\n </AuthButtonGroupContext.Provider>\n );\n}\n","import type { ReactElement } from 'react';\nimport './Spinner.css';\n\nexport function Spinner(): ReactElement {\n return <div className=\"criipto-eid-loader\"></div>;\n}\n","import type { PKCE, AuthorizeResponse } from '@criipto/auth-js';\nimport React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport CriiptoVerifyContext from '../context';\nimport { getUserAgent } from '../device';\n\nimport PollStrategy from './SEBankIDSameDeviceButton/Poll';\nimport ForegroundStrategy from './SEBankIDSameDeviceButton/Foreground';\nimport ReloadStrategy from './SEBankIDSameDeviceButton/Reload';\n\nimport { autoHydratedState, type Links } from './SEBankIDSameDeviceButton/shared';\nimport { AuthButtonGroupContext } from './AuthButtonGroup';\nimport classNames from 'classnames';\nimport { Spinner } from './Spinner/Spinner';\n\ninterface Props {\n className: string;\n children: React.ReactNode;\n logo: React.ReactNode;\n fallback: React.ReactElement;\n redirectUri?: string;\n userAgent?: string;\n disabled?: boolean;\n}\n\nfunction searchParamsToPOJO(input: URLSearchParams) {\n return Array.from(input.keys()).reduce((memo: { [key: string]: string }, key) => {\n memo[key] = input.get(key)!;\n return memo;\n }, {});\n}\n\ntype Resume = 'Foreground' | 'Reload' | 'Poll';\ntype LinkType = 'universal' | 'scheme';\nexport function determineStrategy(\n input: string | undefined,\n loginHint?: string,\n): {\n resume: Resume;\n linkType: LinkType;\n redirect: boolean;\n} {\n const userAgent = getUserAgent(input);\n const mobileOS =\n userAgent?.os.name === 'iOS'\n ? 'iOS'\n : userAgent?.os.name === 'Android'\n ? 'android'\n : userAgent?.browser.name === 'Samsung Internet'\n ? 'android'\n : null;\n const iOSSafari =\n mobileOS === 'iOS' && userAgent?.browser.name?.includes('Safari') ? true : false;\n const androidChrome =\n mobileOS === 'android' && userAgent?.browser.name === 'Mobile Chrome' ? true : false;\n const redirect = iOSSafari && !loginHint?.includes('appswitch:resumeUrl:disable');\n\n const resume: Resume = mobileOS ? (iOSSafari && redirect ? 'Reload' : 'Foreground') : 'Poll';\n\n const linkType = mobileOS === 'iOS' || androidChrome ? 'universal' : 'scheme';\n\n return { resume, linkType, redirect };\n}\n\nexport class NotDoneError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotDoneError';\n }\n}\n\nasync function fetchComplete(completeUrl: string) {\n const completeResponse = await fetch(completeUrl);\n if (completeResponse.status >= 400) {\n const errorMessage = await completeResponse.text();\n const notDone = errorMessage.includes('Native-app driven authentication is not done');\n if (notDone) return new NotDoneError(errorMessage);\n return new Error(errorMessage);\n }\n\n const { location }: { location: string } = await completeResponse.json();\n return { location };\n}\nexport default function SEBankIDSameDeviceButton(props: Props) {\n const { loginHint } = useContext(CriiptoVerifyContext);\n const group = useContext(AuthButtonGroupContext);\n\n const rawUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : props.userAgent;\n const strategy = useMemo(\n () => determineStrategy(rawUserAgent, loginHint),\n [rawUserAgent, loginHint],\n );\n\n const [href, setHref] = useState<null | string>();\n const [links, setLinks] = useState<Links | null>(autoHydratedState?.links ?? null);\n const [pkce, setPKCE] = useState<PKCE | undefined>(autoHydratedState?.pkce ?? undefined);\n const [error, setError] = useState<string | null>(null);\n const [log, setLog] = useState<(string | string[])[]>([]);\n const [initiated, setInitiated] = useState(autoHydratedState ? true : false);\n const {\n buildAuthorizeUrl,\n completionStrategy,\n generatePKCE,\n handleResponse,\n redirectUri: defaultRedirectURi,\n domain,\n } = useContext(CriiptoVerifyContext);\n const redirectUri = props.redirectUri || defaultRedirectURi;\n\n const disabled = props.disabled || group.disabled || initiated;\n\n const reset = () => {\n setPKCE(undefined);\n setLinks(null);\n };\n\n const handleLog = (...statements: string[]) => {\n setLog((logs) => logs.concat([statements]));\n };\n\n const handleComplete = useCallback(\n async (completeUrl: string) => {\n const required = { pkce };\n reset();\n\n const result =\n completeUrl.startsWith(`https://${domain}`) || completeUrl.startsWith(`http://${domain}`)\n ? await fetchComplete(completeUrl)\n : {\n location: completeUrl,\n };\n if (result instanceof NotDoneError && strategy.resume === 'Reload') {\n await handleResponse(\n {\n error: 'access_denied',\n },\n {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n },\n );\n return;\n }\n if (result instanceof Error) {\n setError(result.message);\n return;\n }\n const { location } = result;\n if (completionStrategy === 'openidprovider') {\n window.location.href = location;\n return;\n }\n const url = new URL(location);\n const params = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n\n await handleResponse(params, {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n });\n },\n [completionStrategy, pkce, domain, strategy],\n );\n\n const refresh = useCallback(async () => {\n handleLog('SEBankID: Refresh authorize url');\n const pkce = await generatePKCE();\n\n buildAuthorizeUrl({\n acrValues: 'urn:grn:authn:se:bankid:same-device',\n // When used on a mobile device, we might have already set appswitch login hints\n loginHint: loginHint?.includes('appswitch:') ? undefined : 'appswitch:browser',\n responseMode: 'json',\n pkce,\n redirectUri,\n prompt: 'login', // Triggering SSO at this point would be a mistake\n })\n .then((url) => {\n return fetch(url).then((response) => response.json() as Promise<Links>);\n })\n .then((links) => {\n setPKCE(pkce || undefined);\n setLinks(links);\n\n const redirect = strategy.redirect ? window.location.href : 'null';\n const newUrl = new URL(\n strategy.linkType === 'universal'\n ? links.launchLinks.universalLink\n : links.launchLinks.customFileHandlerUrl,\n );\n newUrl.searchParams.set('redirect', redirect);\n const newHref = newUrl.href;\n\n handleLog(window.location.href);\n handleLog(newHref);\n setHref(newHref);\n })\n .catch((err) => {\n setInitiated(false);\n });\n }, [buildAuthorizeUrl, redirectUri, strategy]);\n\n // Generate URL on first button render\n useEffect(() => {\n if (initiated) return;\n refresh();\n }, [refresh, initiated]);\n\n // Continously fetch new autostart token if UI is open for a long time\n useEffect(() => {\n if (initiated) return;\n\n const interval = setInterval(() => {\n if (initiated) return;\n refresh();\n }, 25000);\n return () => clearInterval(interval);\n }, [refresh, initiated]);\n\n // Track when the button is clicked to stop refreshing URL\n const handleInitiate = () => {\n group.setDisabled(true);\n handleLog('Initiated');\n setInitiated(true);\n setError(null);\n };\n\n const handleError = async (error: string) => {\n group.setDisabled(false);\n setInitiated(false);\n setError(error);\n\n if (error === 'access_denied' || error === '\"access_denied\"') {\n await handleResponse(\n {\n error: 'access_denied',\n },\n {\n pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n },\n );\n }\n };\n\n const element = href ? (\n <a\n className={classNames(props.className, { 'criipto-eid-btn--disabled': disabled })}\n href={href}\n onClick={handleInitiate}\n >\n {initiated ? (\n <div className=\"criipto-eid-logo\">\n <Spinner />\n </div>\n ) : (\n props.logo\n )}\n {props.children}\n </a>\n ) : (\n props.fallback\n );\n\n return (\n <React.Fragment>\n {links ? (\n <React.Fragment>\n {strategy.resume === 'Poll' ? (\n <PollStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n >\n {element}\n </PollStrategy>\n ) : strategy.resume === 'Foreground' ? (\n <ForegroundStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n >\n {element}\n </ForegroundStrategy>\n ) : strategy.resume === 'Reload' ? (\n <ReloadStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n redirectUri={redirectUri!}\n pkce={pkce}\n >\n {element}\n </ReloadStrategy>\n ) : (\n element\n )}\n </React.Fragment>\n ) : (\n element\n )}\n {error && <p>{error}</p>}\n {/* {log && (\n <pre>\n {JSON.stringify(log, null, 2)}\n </pre>\n )} */}\n </React.Fragment>\n );\n}\n","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALAAAABICAYAAABWdn8qAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAsKADAAQAAAABAAAASAAAAACoGQzqAAADbUlEQVR4Ae2agVHbMBSGSa8DMIJH6Ab1BmWEdgLSCWImgE4AjNAJmhE6gkdgg/R/xXAc957tEMeWrE93hvCkSL8+/XlIdi4uKBCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCJxG4HA4NLrWUupTaAjC9wBEc0q/qb33U2qC0PNKYPf6ihchAQwcolm8olYG3S6uInEBGDjtBdrJxJdpS1xWHQZelv/Q6GZethI9lD731K2p6q8m83viCZm5roM+b4L4+/AYc26VhR83m43NgbJmAlro6C7E/dTz1liVLreMHct9sx/8M7bPl3bqhrsQLzD4vTgBO9BdLa4iQQHsgRNclEDSrUxs2xbKGwIY+A2MRF620vHoaKkU2zrxokMYOM3lbyTryZF2rSxcOfFiQxg4waXXHYdWsn450mwLMfmB1BknmxAGTnep7iTNy8J2oKvTlT2vMgw8L+/RoykLm3m9LGx93HOge0aJgZ85pPozysKVBG9TFT2nLgw8J+0jxxrIwhzoxLMUA0dPpfSfeFSpj/TelM2jLHypQW6nHCjHvkoxcI5r819zl4Wj71Zc6eNXZzu5CYRj4AkgnrsLmdiy8D4Yp+gsjIEDVyQYjrLwF2XhYg90GDhBp3qSlIX3inuPmK35Tia2PXFxhe8Dj1vydlyzs7eyTPtN13uz2t9W1+gqqhRjYGWwJveVtQOdMq093PC+CG+31R7Ups19nsfoZwtxDK0E2nYfxNaRYlnYM7bTdD0hDJznWv4IZNv97iqoW2UYA2e4rMrCe8m2yytF3VbDwJ4F8ohZFn5ypBb1cAMDOw7IIdQd1qJvqxWzF8bAObg11ninqtaprhX76sRXF8LAGS+psrBtIcIDXcZTGy0dA49GlWbDgQNdmqInVIWBJ4S5YFdRFl5Q0jxDY+B5OJ91lO5Ad3PWQRLtHAMnujAfkGUHOu+22ge6yuctGDiftepV2h3ofvY2WmElBl7RosrED5rOfkVTGpwKBh5ElF2DovbCGDg7f/YL7m6rRU/o+t9MLQQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAuMI/AMbHRP0yohB0QAAAABJRU5ErkJggg==\"","import React from 'react';\nimport dkmitid from './logos/dkmitid.png';\nimport dkmitiderhverv from './logos/dkmitiderhverv.png';\nimport ftnmobile from './logos/ftnmobile.png';\nimport itsme from './logos/itsme.png';\nimport nobankid from './logos/nobankid.png';\nimport novipps from './logos/novipps.png';\nimport sebankid from './logos/sebankid.png';\nimport sefrejaid from './logos/sefrejaid.png';\nimport depersonalausweis from './logos/depersonalausweis.png';\nimport ukoneid from './logos/ukoneid.png';\nimport idin from './logos/idin.png';\nimport ftn from './logos/ftn.png';\n\nexport interface AuthMethodButtonLogoProps {\n acrValue: string;\n /**\n * base64 image string, e.x. data:image/png;base64,\n * or a ReactElement\n */\n logo?: React.ReactElement | string;\n}\nexport default function AuthMethodButtonLogo(props: AuthMethodButtonLogoProps) {\n const logo =\n typeof props.logo === 'string' ? (\n <img src={props.logo} alt=\"\" />\n ) : (\n (props.logo ??\n (acrValueToLogo(props.acrValue) ? (\n <img src={acrValueToLogo(props.acrValue)} alt=\"\" />\n ) : (\n <span> </span>\n )))\n );\n\n if (logo) return <div className=\"criipto-eid-logo\">{logo}</div>;\n return null;\n}\n\nfunction acrValueToLogo(value: string) {\n if (value.startsWith('urn:grn:authn:dk:mitid:business')) {\n return dkmitiderhverv;\n }\n if (value.startsWith('urn:grn:authn:dk:mitid')) {\n return dkmitid;\n }\n if (value.startsWith('urn:grn:authn:fi:mobile')) {\n return ftnmobile;\n }\n if (value.startsWith('urn:grn:authn:fi')) {\n return ftn;\n }\n if (value.startsWith('urn:grn:authn:itsme')) {\n return itsme;\n }\n if (value.startsWith('urn:grn:authn:se:bankid')) {\n return sebankid;\n }\n if (value.startsWith('urn:grn:authn:no:bankid')) {\n return nobankid;\n }\n if (value.startsWith('urn:grn:authn:no:vipps')) {\n return novipps;\n }\n if (value.startsWith('urn:grn:authn:se:frejaid')) {\n return sefrejaid;\n }\n if (value.startsWith('urn:grn:authn:uk:oneid')) {\n return ukoneid;\n }\n if (value.startsWith('urn:grn:authn:de:personalausweis')) {\n return depersonalausweis;\n }\n if (value.startsWith('urn:grn:authn:nl:idin')) {\n return idin;\n }\n}\n","import React from 'react';\nimport classNames from 'classnames';\n\ninterface ButtonProps {\n className?: string;\n children: React.ReactNode;\n onClick?: React.MouseEventHandler;\n disabled?: boolean;\n}\nexport function AnchorButton(props: AnchorButtonProps) {\n return (\n <a\n className={classNames(`criipto-verify-button`, props.className)}\n href={props.href}\n aria-disabled={props.disabled}\n onClick={props.onClick}\n >\n {props.children}\n </a>\n );\n}\n\ninterface AnchorButtonProps extends ButtonProps {\n href: string;\n}\nexport function Button(props: ButtonProps) {\n return (\n <button\n className={classNames(`criipto-verify-button`, props.className)}\n type=\"button\"\n disabled={props.disabled}\n onClick={props.onClick}\n >\n {props.children}\n </button>\n );\n}\n","import React, { useContext, useEffect, useState } from 'react';\n\nimport './AuthMethodButton/AuthMethodButton.css';\nimport CriiptoVerifyContext, { type Action } from '../context';\nimport SEBankIDSameDeviceButton from './SEBankIDSameDeviceButton';\nimport { savePKCEState } from '@criipto/auth-js';\nimport AuthMethodButtonLogo, { type AuthMethodButtonLogoProps } from './AuthMethodButton/Logo';\nimport { AnchorButton, Button } from './Button';\nimport { acrValueToTitle, isAmbiguous, isSingle, stringifyAction } from '../utils';\nimport { AuthButtonGroupContext } from './AuthButtonGroup';\nimport { type Language } from '../i18n';\nimport { Spinner } from './Spinner/Spinner';\nimport classNames from 'classnames';\n\nexport type PopupParams = {\n acrValue: string;\n onHide: () => void;\n};\nexport type PopupOption = boolean | ((options: PopupParams) => boolean | React.ReactElement);\n\nexport interface AuthMethodButtonComponentProps {\n acrValue: string;\n href?: string;\n onClick?: React.MouseEventHandler;\n children?: React.ReactNode;\n 'data-testid'?: string;\n className?: string;\n /**\n * base64 image string, e.x. data:image/png;base64,\n * or a ReactElement\n */\n logo?: AuthMethodButtonLogoProps['logo'];\n /**\n * Impacts the button text rendered if no text is provided via props.children\n */\n language?: Language;\n /**\n * Impacts the button text rendered if no text is provided via props.children\n */\n action?: Action;\n disabled?: boolean;\n loading?: boolean;\n}\n\n/**\n * Display only components, does no state management and triggers no login flows on it's own\n */\nexport function AuthMethodButtonComponent(props: AuthMethodButtonComponentProps) {\n const { acrValue, href } = props;\n const group = useContext(AuthButtonGroupContext);\n const standalone = !group.multiple || isSingle(props.acrValue, group.acrValues);\n const language = (props.language ?? 'en') as Language;\n const action = (props.action ?? 'login') as Action;\n\n const disabled = (props.disabled || group.disabled) && !props.loading;\n const className = classNames(`criipto-eid-btn`, acrValueToClassName(acrValue), props.className, {\n 'criipto-eid-btn--disabled': disabled,\n 'criipto-eid-btn--loading': props.loading,\n });\n\n const { title, subtitle } = acrValueToTitle(language, acrValue, {\n disambiguate: isAmbiguous(acrValue, group.acrValues),\n });\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title} \n {standalone ? null : lowercaseFirst(subtitle)}\n </React.Fragment>\n );\n\n const inner = (\n <React.Fragment>\n <AuthMethodButtonLogo acrValue={acrValue} logo={props.loading ? <Spinner /> : props.logo} />\n <span>{contents}</span>\n </React.Fragment>\n );\n\n const commonProps = {\n ...props,\n className,\n disabled,\n };\n const button = href ? (\n <React.Fragment>\n <AnchorButton {...commonProps} href={href}>\n {inner}\n </AnchorButton>\n </React.Fragment>\n ) : (\n <React.Fragment>\n <Button {...commonProps}>{inner}</Button>\n </React.Fragment>\n );\n\n return button;\n}\n\nexport type AuthMethodButtonContainerProps = AuthMethodButtonComponentProps & {\n redirectUri?: string;\n popup?: PopupOption;\n\n /**\n * Will ammend the login_hint parameter with `message:{base64(message)}` which will set a login/aprove message where available (Danish MitID).\n */\n message?: string;\n\n userAgent?: string;\n};\n\nexport function AuthMethodButtonContainer(props: AuthMethodButtonContainerProps) {\n const { acrValue } = props;\n const group = useContext(AuthButtonGroupContext);\n const standalone = !group.multiple || isSingle(props.acrValue, group.acrValues);\n const context = useContext(CriiptoVerifyContext);\n const { initializePAR } = context;\n const language = (props.language ?? context.uiLocales ?? 'en') as Language;\n const action = (props.action ?? context.action ?? 'login') as Action;\n const className = `criipto-eid-btn ${acrValueToClassName(acrValue)}${\n props.className ? ` ${props.className}` : ''\n }`;\n const [backdrop, setBackdrop] = useState<React.ReactElement | null>(null);\n const [loading, setLoading] = useState<boolean>(props.loading ?? false);\n useEffect(() => {\n setLoading(props.loading ?? false);\n }, [props.loading]);\n\n const redirectUri = props.redirectUri || context.redirectUri;\n\n const handleClick: React.MouseEventHandler = (event) => {\n if (props.href) return;\n\n if (context.pkce && 'code_verifier' in context.pkce) {\n // just-in-time saving of PKCE, in case of man-in-the-browser\n savePKCEState(context.store, {\n response_type: 'id_token',\n pkce_code_verifier: context.pkce.code_verifier,\n redirect_uri: redirectUri!,\n });\n }\n\n if (props.popup) {\n let willPopup =\n typeof props.popup === 'function'\n ? props.popup({\n acrValue,\n onHide: () => setBackdrop(null),\n })\n : props.popup === true;\n\n if (willPopup !== false) {\n event.preventDefault();\n\n if (typeof willPopup === 'boolean') {\n context.loginWithPopup({\n acrValues: [acrValue],\n redirectUri: redirectUri,\n backdrop: true,\n });\n } else {\n setBackdrop(willPopup);\n context.loginWithPopup({\n acrValues: [acrValue],\n redirectUri: redirectUri,\n backdrop: false,\n });\n }\n }\n }\n\n if (props.onClick) props.onClick(event);\n\n if (!event.isDefaultPrevented()) {\n setLoading(true);\n group.setDisabled(true);\n initializePAR({\n redirectUri,\n acrValues: acrValue,\n loginHint: '',\n })\n .then((authorizeUrl) => {\n window.location.href = authorizeUrl.toString();\n })\n .catch((error) => {\n setLoading(false);\n group.setDisabled(false);\n context.handleResponse(error);\n });\n }\n };\n\n const { title, subtitle } = acrValueToTitle(language, acrValue, {\n disambiguate: isAmbiguous(acrValue, group.acrValues),\n });\n\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title} \n {standalone ? null : lowercaseFirst(subtitle)}\n </React.Fragment>\n );\n\n const button = (\n <React.Fragment>\n <AuthMethodButtonComponent\n {...props}\n className={className}\n onClick={handleClick}\n loading={loading}\n />\n {backdrop}\n </React.Fragment>\n );\n\n if (!props.href && acrValue === 'urn:grn:authn:se:bankid:same-device') {\n return (\n <SEBankIDSameDeviceButton\n redirectUri={props.redirectUri}\n fallback={button}\n className={className}\n userAgent={props.userAgent}\n logo={<AuthMethodButtonLogo acrValue={acrValue} logo={props.logo} />}\n disabled={props.disabled}\n >\n <span>{contents}</span>\n </SEBankIDSameDeviceButton>\n );\n }\n\n return button;\n}\n\nfunction acrValueToClassName(value: string) {\n value = value.replace('urn:grn:authn:', '');\n const segments = value.split(':');\n const classNames = segments.reduce((memo: string[], segment: string) => {\n if (memo.length) {\n return memo.concat([`${memo[memo.length - 1]}-${segment}`]);\n } else {\n return memo.concat([segment]);\n }\n }, []);\n\n return classNames.map((className) => `criipto-eid-btn--${className}`).join(' ');\n}\n\nfunction lowercaseFirst(input?: string) {\n if (!input) return input;\n return input.substring(0, 1).toLowerCase() + input.substr(1, input.length);\n}\n","import { useContext } from 'react';\nimport CriiptoVerifyContext from '../context';\nimport { getUserAgent } from '../device';\nimport { filterAcrValues } from '../utils';\nimport { type Language } from '../i18n';\nimport { AuthMethodButtonContainer, type AuthMethodButtonContainerProps } from './AuthMethodButton';\n\nimport './AuthMethodSelector/AuthMethodSelector.css';\nimport SEBankIDQrCode from './SEBankIDQRCode';\nimport AuthButtonGroup from './AuthButtonGroup';\n\ninterface AuthMethodSelectorProps {\n acrValues?: string[];\n language?: Language;\n onSelect?: (acrValue: string) => void;\n redirectUri?: string;\n popup?: AuthMethodButtonContainerProps['popup'];\n userAgent?: string;\n}\n\nexport default function AuthMethodSelector(props: AuthMethodSelectorProps) {\n const { action, uiLocales, acrValues: configurationAcrValues } = useContext(CriiptoVerifyContext);\n const language = props.language || (uiLocales as Language) || 'en';\n\n const acrValues = filterAcrValues(props.acrValues ?? configurationAcrValues ?? []);\n const onlySweden =\n !!acrValues.length && acrValues.every((s) => s.startsWith('urn:grn:authn:se:bankid:'));\n\n if (onlySweden) {\n return <Sweden {...props} acrValues={acrValues} />;\n }\n\n return (\n <div className=\"criipto-eid-selector\">\n <AuthButtonGroup>\n {acrValues.map((acrValue) => (\n <AuthMethodButtonContainer\n acrValue={acrValue}\n key={acrValue}\n onClick={props.onSelect ? () => props.onSelect!(acrValue) : undefined}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ))}\n </AuthButtonGroup>\n </div>\n );\n}\n\ntype SwedenProps = Omit<AuthMethodSelectorProps, 'acrValues'> & {\n acrValues: string[];\n};\n\nexport function Sweden(props: SwedenProps) {\n const { acrValues } = props;\n const { action, uiLocales } = useContext(CriiptoVerifyContext);\n const language = props.language || (uiLocales as Language) || 'en';\n const hasQR = acrValues.includes(SEBankIDQrCode.acr_values);\n const filteredAcrValues = acrValues.filter((s) => s !== SEBankIDQrCode.acr_values);\n\n const userAgent = getUserAgent(\n typeof navigator !== 'undefined' ? navigator.userAgent : props.userAgent,\n );\n const mobileOS =\n userAgent?.os.name === 'iOS' ? 'iOS' : userAgent?.os.name === 'Android' ? 'android' : null;\n const showQR = hasQR && !mobileOS;\n\n return (\n <div className=\"criipto-eid-selector\">\n <AuthButtonGroup>\n {filteredAcrValues.map((acrValue) => (\n <AuthMethodButtonContainer\n acrValue={acrValue}\n key={acrValue}\n onClick={props.onSelect ? () => props.onSelect!(acrValue) : undefined}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ))}\n {showQR ? (\n <SEBankIDQrCode\n language={language}\n redirectUri={props.redirectUri}\n fallback={\n <AuthMethodButtonContainer\n acrValue={SEBankIDQrCode.acr_values}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n }\n />\n ) : hasQR && mobileOS ? (\n <AuthMethodButtonContainer\n acrValue={SEBankIDQrCode.acr_values}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ) : null}\n </AuthButtonGroup>\n </div>\n );\n}\n","import {\n OAuth2Error,\n savePKCEState,\n UserCancelledError,\n type CriiptoConfiguration,\n} from '@criipto/auth-js';\n\nimport React, {\n useContext,\n useRef,\n useEffect,\n useLayoutEffect,\n useState,\n useCallback,\n} from 'react';\nimport CriiptoVerifyContext from '../context';\n\n// Inlined types less readable (for library developers) but improves intellisense for consumers\nconst QRCode: React.FC<{\n margin?: number;\n className?: string;\n acrValues?: string[];\n children: (props: {\n qrElement: React.ReactElement;\n /**\n * Will be true once the QR code has been scanned\n */\n isAcknowledged: boolean;\n /**\n * Will be true if the user cancels the login on his mobile device\n */\n isCancelled: boolean;\n /**\n * Whether or not QR codes are enabled for this Criipto Applicaiton\n */\n isEnabled: boolean | undefined;\n error: OAuth2Error | Error | null;\n retry: () => void;\n /**\n * A method for triggering a full screen redirect to authentication (useful if user is on mobile device already)\n */\n redirect: () => Promise<void>;\n }) => React.ReactElement;\n}> = (props) => {\n const { children, margin, className } = props;\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n client,\n buildOptions,\n buildAuthorizeUrl,\n handleResponse,\n pkce,\n store,\n acrValues: configurationAcrValues,\n } = useContext(CriiptoVerifyContext);\n const [requestId, setRequestId] = useState(() => Math.random().toString());\n const [isAcknowledged, setAcknowledged] = useState(false);\n const [isCancelled, setCancelled] = useState(false);\n const [error, setError] = useState<OAuth2Error | Error | null>(null);\n const [criiptoConfiguration, setCriiptoConfiguration] = useState<CriiptoConfiguration | null>(\n null,\n );\n const isEnabled = criiptoConfiguration?.client.qr_enabled;\n\n const acrValues = props.acrValues ?? configurationAcrValues ?? [];\n\n useEffect(() => {\n let isSubsribed = true;\n\n client.fetchCriiptoConfiguration().then((c) => {\n if (!isSubsribed) return;\n setCriiptoConfiguration(c);\n });\n\n return () => {\n isSubsribed = false;\n };\n }, [client]);\n\n const redirect = useCallback(async () => {\n if (!criiptoConfiguration) return;\n const intermediaryUrl = (\n criiptoConfiguration.client.qr_intermediary_url ?? criiptoConfiguration.qr_intermediary_url\n )\n .replace('/{id}', '')\n .replace('{id}', '');\n const authorizeUrl = new URL(\n await buildAuthorizeUrl({\n acrValues,\n }),\n );\n const authorizeParams = new URLSearchParams(authorizeUrl.search);\n authorizeParams.set('domain', authorizeUrl.host);\n authorizeUrl.host = new URL(intermediaryUrl).host;\n authorizeUrl.port = new URL(intermediaryUrl).port;\n authorizeUrl.pathname = new URL(intermediaryUrl).pathname + '/authorize';\n authorizeUrl.search = authorizeParams.toString();\n\n if (pkce && 'code_verifier' in pkce) {\n // just-in-time saving of PKCE, in case of man-in-the-browser\n savePKCEState(store, {\n response_type: 'id_token',\n pkce_code_verifier: pkce.code_verifier,\n redirect_uri: authorizeParams.get('redirect_uri')!,\n });\n }\n\n window.location.href = authorizeUrl.toString();\n }, [buildAuthorizeUrl, criiptoConfiguration, acrValues]);\n\n const authorize = useCallback(() => {\n return client.qr.authorize(elementRef.current!, {\n ...buildOptions({ acrValues }),\n margin,\n });\n }, [client, buildOptions, margin, acrValues]);\n\n useLayoutEffect(() => {\n if (!elementRef.current) return;\n if (error) return;\n if (!isEnabled) return;\n\n const promise = authorize();\n\n promise.onAcknowledged = () => {\n setAcknowledged(true);\n };\n\n promise\n .then((response) => {\n if (promise.cancelled) return;\n handleResponse(response, {\n pkce: pkce && 'code_verifier' in pkce ? pkce : undefined,\n source: 'QRCode',\n });\n })\n .catch((err) => {\n if (err instanceof UserCancelledError) {\n setCancelled(true);\n return;\n }\n\n if (promise.cancelled) return;\n\n setError(err);\n handleResponse(err, { source: 'QRCode' });\n });\n\n return () => {\n promise.cancel();\n };\n }, [authorize, pkce, handleResponse, requestId, error, isEnabled]);\n\n const handleRetry = () => {\n setAcknowledged(false);\n setCancelled(false);\n setError(null);\n setRequestId(Math.random().toString());\n };\n\n const qrElement = <div ref={elementRef} className={className} />;\n return children({\n qrElement,\n isAcknowledged,\n isCancelled,\n isEnabled: criiptoConfiguration?.client.qr_enabled,\n error,\n retry: handleRetry,\n redirect,\n });\n};\nexport default QRCode;\n","import { useContext } from 'react';\nimport CriiptoVerifyContext from './context';\n\nexport default function useCriiptoVerify() {\n const {\n result,\n claims,\n loginWithRedirect,\n loginWithPopup,\n acrValues,\n isLoading,\n isInitializing,\n logout,\n checkSession,\n } = useContext(CriiptoVerifyContext);\n\n return {\n result,\n /**\n * The claims of the decoded id_token (if available)\n */\n claims,\n /**\n * Set when the provider failed to fetch configuration (e.g. invalid `domain`/`clientID`,\n * or CORS), or when an authentication attempt failed (e.g. user cancellation, OAuth2 errors\n * from the IdP). Always render this in your UI — failures are otherwise silent.\n *\n * `OAuth2Error` for IdP-returned errors, `Error` for everything else.\n */\n error: result && ('error' in result || result instanceof Error) ? result : null,\n loginWithRedirect,\n loginWithPopup,\n acrValues,\n /**\n * Will be true when performing token exchange after redirect or during an initial SSO check\n */\n isLoading,\n /**\n * Will be true until the first set of useEffect hooks have been called\n */\n isInitializing,\n /**\n * Check if there is an existing SSO session.\n */\n checkSession,\n /**\n * Clear local session store and logout of any existing SSO session\n */\n logout,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["OAuth2Error","usePoll","searchParamsToPOJO","logo","QRCode","PollStrategy","ForegroundStrategy","ReloadStrategy","dkmitiderhverv","dkmitid","ftnmobile","ftn","itsme","sebankid","nobankid","novipps","sefrejaid","ukoneid","depersonalausweis","idin"],"sources":["../src/context.ts","../package.json","../src/i18n/en.ts","../src/i18n/da.ts","../src/i18n/sv.ts","../src/i18n/nb.ts","../src/i18n/fi.ts","../src/i18n/de.ts","../src/i18n/nl.ts","../src/i18n/index.ts","../src/utils.ts","../src/memory-storage.ts","../src/provider.tsx","../src/device.ts","../src/components/SEBankIDSameDeviceButton/usePoll.ts","../src/components/SEBankIDSameDeviceButton/Poll.tsx","../src/hooks/usePageVisibility.ts","../src/components/SEBankIDSameDeviceButton/Foreground.tsx","../src/components/SEBankIDSameDeviceButton/shared.ts","../src/components/SEBankIDSameDeviceButton/Reload.tsx","../src/components/SEBankIDQRCode/logo@2x.png","../src/components/SEBankIDQRCode.tsx","../src/components/AuthButtonGroup.tsx","../src/components/Spinner/Spinner.tsx","../src/components/SEBankIDSameDeviceButton.tsx","../src/components/AuthMethodButton/logos/dkmitid.png","../src/components/AuthMethodButton/logos/dkmitiderhverv.png","../src/components/AuthMethodButton/logos/ftnmobile.png","../src/components/AuthMethodButton/logos/itsme.png","../src/components/AuthMethodButton/logos/nobankid.png","../src/components/AuthMethodButton/logos/novipps.png","../src/components/AuthMethodButton/logos/sebankid.png","../src/components/AuthMethodButton/logos/sefrejaid.png","../src/components/AuthMethodButton/logos/depersonalausweis.png","../src/components/AuthMethodButton/logos/ukoneid.png","../src/components/AuthMethodButton/logos/idin.png","../src/components/AuthMethodButton/logos/ftn.png","../src/components/AuthMethodButton/Logo.tsx","../src/components/Button.tsx","../src/components/AuthMethodButton.tsx","../src/components/AuthMethodSelector.tsx","../src/components/QRCode.tsx","../src/use-criipto-verify.ts"],"sourcesContent":["import CriiptoAuth, {\n OpenIDConfiguration,\n type AuthorizeUrlParamsOptional,\n type PKCE,\n type AuthorizeResponse,\n OAuth2Error,\n type PKCEPublicPart,\n} from '@criipto/auth-js';\nimport type { PopupAuthorizeParams, RedirectAuthorizeParams } from '@criipto/auth-js';\nimport { createContext } from 'react';\n\nexport type ResultSource =\n | 'QRCode'\n | 'SEBankIDQrCode'\n | 'SEBankIDSameDeviceButton'\n | 'redirect'\n | 'popup';\nexport type Result =\n | { id_token: string; state?: string; source?: ResultSource }\n | { code: string; state?: string; source?: ResultSource }\n | OAuth2Error\n | Error;\nexport const actions = ['confirm', 'accept', 'approve', 'sign', 'login'] as const;\nexport type Action = (typeof actions)[number];\nexport type Claims = {\n iss: string;\n aud: string;\n identityscheme: string;\n authenticationtype: string;\n sub: string;\n iat: number;\n exp: number;\n [key: string]: string | number;\n};\n\nexport interface CriiptoVerifyContextInterface {\n loginWithRedirect: (params?: RedirectAuthorizeParams) => Promise<void>;\n loginWithPopup: (params?: PopupAuthorizeParams) => Promise<void>;\n checkSession: () => Promise<void>;\n logout: (params?: { redirectUri?: string; state?: string }) => Promise<void>;\n fetchOpenIDConfiguration: () => Promise<OpenIDConfiguration>;\n buildAuthorizeUrl: (options?: AuthorizeUrlParamsOptional) => Promise<string>;\n initializePAR: (options?: AuthorizeUrlParamsOptional) => Promise<URL>;\n generatePKCE: () => Promise<PKCE | undefined>;\n buildOptions: (\n options?: AuthorizeUrlParamsOptional | RedirectAuthorizeParams,\n ) => AuthorizeUrlParamsOptional;\n handleResponse: (\n response: AuthorizeResponse | (Error | OAuth2Error),\n params?: { pkce?: PKCE; redirectUri?: string; source?: ResultSource },\n ) => Promise<void>;\n responseType: 'token' | 'code';\n completionStrategy: 'client' | 'openidprovider';\n result: Result | null;\n claims: Claims | null;\n domain: string;\n redirectUri?: string;\n action: Action;\n message?: string;\n pkce?: PKCE | PKCEPublicPart;\n store: Storage;\n isLoading: boolean;\n isInitializing: boolean;\n acrValues?: string[];\n uiLocales?: string;\n client: CriiptoAuth;\n loginHint?: string;\n}\n\n/**\n * @ignore\n */\nconst stub = (): never => {\n throw new Error('You forgot to wrap your component in <CriiptoVerifyProvider>.');\n};\n\n/**\n * @ignore\n */\nconst initialContext = {\n loginWithRedirect: stub,\n loginWithPopup: stub,\n checkSession: stub,\n logout: stub,\n fetchOpenIDConfiguration: stub,\n buildAuthorizeUrl: stub,\n initializePAR: stub,\n generatePKCE: stub,\n buildOptions: stub,\n handleResponse: stub,\n responseType: 'token' as 'token' | 'code',\n completionStrategy: 'client' as 'client' | 'openidprovider',\n result: null,\n claims: null,\n domain: '',\n action: 'login' as Action,\n pkce: undefined,\n store: null as any as Storage,\n isLoading: false,\n isInitializing: true,\n client: null as any as CriiptoAuth,\n loginHint: undefined,\n};\n\nconst CriiptoVerifyContext = createContext<CriiptoVerifyContextInterface>(initialContext);\n\nexport default CriiptoVerifyContext;\n","","export const en = {\n loginWith: 'Login with',\n approveWith: 'Approve with',\n signWith: 'Sign with',\n confirmWith: 'Confirm with',\n acceptWith: 'Accept with',\n sameDevice: 'On this device',\n anotherDevice: 'With your SSN',\n anotherDeviceQR: 'On another device',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finnish Mobile Certificate',\n finnishBankID: 'Finnish Bank ID',\n swedishBankID: 'Swedish BankID',\n norwegianBankID: 'Norwegian BankID',\n biometrics: 'Biometrics',\n openAndScan: 'Open the BankID app on your mobile device and scan the QR code.',\n thisIsTheQR: 'This is a BankID QR Code. You can click it to view it in full screen.',\n completingLogin: 'Completing your login.',\n} as const;\n","import { type I18N } from '.';\n\nexport const da = {\n loginWith: 'Login med',\n approveWith: 'Godkend med',\n signWith: 'Underskriv med',\n confirmWith: 'Bekræft med',\n acceptWith: 'Accepter med',\n sameDevice: 'På denne enhed',\n anotherDevice: 'Med dit personnummer',\n anotherDeviceQR: 'På anden enhed',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finsk Mobilcertifikat',\n finnishBankID: 'Finsk Bank ID',\n swedishBankID: 'Svensk BankID',\n norwegianBankID: 'Norsk BankID',\n biometrics: 'Biometri',\n openAndScan: 'Åbn BankID appen på din telefon og scan QR koden.',\n thisIsTheQR: 'Dette er en BankID QR-kode. Du kan klikke på den for at se den i fuld skærm.',\n completingLogin: 'Fuldfører dit login.',\n} satisfies I18N;\n","import { type I18N } from '.';\n\nexport const sv = {\n loginWith: 'Logga in med',\n approveWith: 'Godkänn med',\n signWith: 'Signera med',\n confirmWith: 'Bekräfta med',\n acceptWith: 'Acceptera med',\n sameDevice: 'På denna enhet',\n anotherDevice: 'Med ditt personnummer',\n anotherDeviceQR: 'På annan enhet',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finskt Mobilcertifikat',\n finnishBankID: 'Finskt Bank ID',\n swedishBankID: 'Svenskt BankID',\n norwegianBankID: 'Norska BankID',\n biometrics: 'Biometri',\n openAndScan: 'Öppna BankID-appen på din mobila enhet och skanna QR-koden.',\n thisIsTheQR: 'Detta är en QR-kod från BankID. Du kan klicka på den för att visa den i fullskärm.',\n completingLogin: 'Slutför din inloggning.',\n} satisfies I18N;\n","import { type I18N } from '.';\n\nexport const nb = {\n loginWith: 'Logg inn med',\n approveWith: 'Godkjenne med',\n signWith: 'Signer med',\n confirmWith: 'Bekreft med',\n acceptWith: 'Aksepterer med',\n sameDevice: 'På denne enhet',\n anotherDevice: 'Med personnummeret ditt',\n anotherDeviceQR: 'På annan enhet',\n mitidBusiness: 'MitID Erhverv',\n finnishMobileID: 'Finsk Mobilsertifikat',\n finnishBankID: 'Finsk Bank ID',\n swedishBankID: 'Svensk BankID',\n norwegianBankID: 'Norsk BankID',\n biometrics: 'Biometri',\n openAndScan: 'Åpne BankID-appen på mobilenheten din og skann QR-koden.',\n thisIsTheQR: 'Dette er en BankID QR-kode. Du kan klikke på den for å se den i fullskjerm.',\n completingLogin: 'Fullfører påloggingen.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const fi = {\n loginWith: 'Kirjaudu sisään',\n approveWith: 'Hyväksy',\n signWith: 'Allekirjoita',\n confirmWith: 'Vahvista',\n acceptWith: 'Hyväksy',\n sameDevice: 'Tällä laitteella',\n anotherDevice: 'Henkilötunnuksellasi',\n anotherDeviceQR: 'Toisella laitteella',\n mitidBusiness: 'MitID Businessilla',\n finnishMobileID: 'Suomalaisella Mobiilivarmenteella',\n finnishBankID: 'Suomalaisella BankID:llä',\n swedishBankID: 'Ruotsalaisella BankID:llä',\n norwegianBankID: 'Norjalaisella BankID:llä',\n biometrics: 'Biometrisella tunnistautumisella',\n openAndScan: 'Avaa BankID-sovellus mobiililaitteellasi ja skannaa QR-koodi.',\n thisIsTheQR: 'Tämä on BankID-QR-koodi. Voit napsauttaa sitä nähdäksesi sen koko näytöllä',\n completingLogin: 'Sisäänkirjautumista viimeistellään.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const de = {\n loginWith: 'Anmelden mit',\n approveWith: 'Genehmigen mit',\n signWith: 'Unterschreiben mit',\n confirmWith: 'Bestätigen mit',\n acceptWith: 'Akzeptieren mit',\n sameDevice: 'Auf diesem Gerät',\n anotherDevice: 'Mit Ihrer Sozialversicherungsnummer',\n anotherDeviceQR: 'Auf einem anderen Gerät',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finnischem Mobilfunkzertifikat',\n finnishBankID: 'Finnische BankID',\n swedishBankID: 'Schwedische BankID',\n norwegianBankID: 'Norwegische BankID',\n biometrics: 'Biometrie',\n openAndScan: 'Öffnen Sie die BankID-App auf Ihrem mobilen Endgerät und scannen Sie den QR-Code.',\n thisIsTheQR:\n 'Dies ist ein BankID QR-Code. Sie können darauf klicken, um ihn im Vollbildmodus anzuzeigen',\n completingLogin: 'Ihre Anmeldung wird abgeschlossen.',\n} satisfies I18N;\n","import type { I18N } from '.';\n\nexport const nl = {\n loginWith: 'Inloggen met',\n approveWith: 'Goedkeuren met',\n signWith: 'Ondertekenen met',\n confirmWith: 'Bevestigen met',\n acceptWith: 'Accepteren met',\n sameDevice: 'Op dit apparaat',\n anotherDevice: 'Met uw SSN',\n anotherDeviceQR: 'Op een ander apparaat',\n mitidBusiness: 'MitID Business',\n finnishMobileID: 'Finse mobiel certificaat',\n finnishBankID: 'Finse BankID',\n swedishBankID: 'Zweedse BankID',\n norwegianBankID: 'Noorse BankID',\n biometrics: 'Biometrie',\n openAndScan: 'Open de BankID-app op uw mobiele apparaat en scan de QR-code.',\n thisIsTheQR:\n 'Dit is een BankID QR-code. U kunt erop klikken om het in een volledig scherm te bekijken',\n completingLogin: 'Uw login voltooien.',\n} satisfies I18N;\n","import { en } from './en';\nimport { da } from './da';\nimport { sv } from './sv';\nimport { nb } from './nb';\nimport { fi } from './fi';\nimport { de } from './de';\nimport { nl } from './nl';\nimport { assertUnreachable } from '../utils';\n\nexport type Language = 'en' | 'da' | 'sv' | 'nb' | 'fi' | 'de' | 'nl';\nexport type I18N = Record<keyof typeof en, string>;\n\nexport function getI18n(language: Language): I18N {\n switch (language) {\n case 'en':\n return en;\n case 'da':\n return da;\n case 'sv':\n return sv;\n case 'nb':\n return nb;\n case 'fi':\n return fi;\n case 'de':\n return de;\n case 'nl':\n return nl;\n default:\n assertUnreachable(language);\n }\n}\n","import type { Action } from './context';\nimport { getI18n, type Language } from './i18n';\n\nexport const DKMITID_PREFIX = 'urn:grn:authn:dk:mitid';\nexport const DKMITID_BUSINESS = 'urn:grn:authn:dk:mitid:business';\nexport const FTN_PREFIX = 'urn:grn:authn:fi';\n\nexport function lowestMitIDValue(input: string[]): string | null {\n let dkmitidMethod: string | null = null;\n\n input.forEach((s) => {\n if (s.startsWith(DKMITID_PREFIX) && s !== DKMITID_BUSINESS) {\n if (!dkmitidMethod) {\n dkmitidMethod = s;\n } else {\n let newLevel = s.replace(DKMITID_PREFIX, '');\n let oldLevel = dkmitidMethod.replace(DKMITID_PREFIX, '');\n if (newLevel === ':low' && [':substantial', ':high'].includes(oldLevel)) {\n dkmitidMethod = s;\n } else if (newLevel === ':substantial' && oldLevel === ':high') {\n dkmitidMethod = s;\n }\n }\n }\n });\n\n return dkmitidMethod;\n}\n\nfunction autoTitleCase(input: string) {\n var segments = input.split(/:|-/).map((segment) => {\n segment = segment.replace(/id(\\s|$)/, 'ID');\n if (segment.length === 2) return segment.toUpperCase();\n return segment.substr(0, 1).toUpperCase() + segment.substr(1);\n });\n return segments.join(' ');\n}\n\nexport function assertUnreachable(x: never): never {\n throw new Error(\"Didn't expect to get here\");\n}\n\nexport function stringifyAction(language: Language, action: Action): string {\n const i18n = getI18n(language);\n\n switch (action) {\n case 'login':\n return i18n.loginWith;\n case 'approve':\n return i18n.approveWith;\n case 'sign':\n return i18n.signWith;\n case 'confirm':\n return i18n.confirmWith;\n case 'accept':\n return i18n.acceptWith;\n default:\n assertUnreachable(action);\n }\n}\n\nexport function acrValueToProviderPrefix(value: string) {\n value = value.replace('urn:grn:authn:', '');\n\n if (value.startsWith('fi')) {\n return 'fi';\n } else if (value.startsWith('itsme')) {\n return 'itsme';\n } else {\n return value.split(':').slice(0, 2).join(':');\n }\n}\n\nexport function acrValueToTitle(\n language: Language,\n value: string,\n { disambiguate }: { disambiguate: boolean },\n): { title: string; subtitle?: string } {\n const i18n = getI18n(language);\n value = value.replace('urn:grn:authn:', '');\n const provider = acrValueToProviderPrefix(value);\n\n if (provider === 'dk:mitid') {\n let suffix = value.replace('dk:mitid:', '');\n if (suffix === 'business') {\n return {\n title: i18n.mitidBusiness,\n };\n }\n\n return { title: 'MitID' };\n }\n if (value === 'fi:mobile-id') {\n return {\n title: i18n.finnishMobileID,\n };\n }\n if (value === 'fi:bank-id') {\n return {\n title: i18n.finnishBankID,\n };\n }\n if (provider === 'fi') {\n return { title: autoTitleCase(value).replace('FI', 'FTN') };\n }\n if (provider === 'itsme') {\n return { title: autoTitleCase(value).replace('me', 'ME') };\n }\n if (provider === 'se:bankid') {\n let subtitle: string | undefined = undefined;\n let suffix = value.replace('se:bankid:', '');\n let title = 'BankID';\n\n if (suffix === 'same-device') {\n subtitle = i18n.sameDevice;\n }\n if (suffix === 'another-device') {\n subtitle = i18n.anotherDevice;\n }\n if (suffix === 'another-device:qr') {\n subtitle = i18n.anotherDeviceQR;\n }\n if (disambiguate) {\n title = i18n.swedishBankID;\n }\n\n return { title, subtitle };\n }\n if (provider === 'no:bankid') {\n let subtitle: string | undefined = undefined;\n let title = 'BankID';\n if (value.endsWith(':substantial')) {\n subtitle = i18n.biometrics;\n }\n if (disambiguate) {\n title = i18n.norwegianBankID;\n }\n return { title, subtitle };\n }\n if (provider === 'no:vipps') {\n return { title: autoTitleCase(value).replace('NO ', '') };\n }\n if (provider === 'se:frejaid') {\n return { title: 'FrejaID' };\n }\n if (provider === 'uk:oneid') {\n return { title: 'OneID' };\n }\n if (provider === 'de:personalausweis') {\n return { title: 'Personalausweis' };\n }\n\n return { title: autoTitleCase(value) };\n}\n\nexport function filterAcrValues(input: string[]) {\n let original = input.slice();\n let dkmitidMethod: string | null = lowestMitIDValue(input);\n let reduced = input.slice();\n\n if (dkmitidMethod) {\n reduced = input\n .filter((s) => !s.startsWith(DKMITID_PREFIX) || s === DKMITID_BUSINESS)\n .concat([dkmitidMethod])\n .sort((a, b) => original.indexOf(a) - original.indexOf(b));\n }\n\n if (input.includes(`${FTN_PREFIX}:all`)) {\n if (!reduced.includes(`${FTN_PREFIX}:bank-id`)) reduced.push(`${FTN_PREFIX}:bank-id`);\n if (!reduced.includes(`${FTN_PREFIX}:mobile-id`)) reduced.push(`${FTN_PREFIX}:mobile-id`);\n reduced = reduced.filter((s) => s !== `${FTN_PREFIX}:all`);\n }\n return reduced;\n}\n\nexport function isSingle(acrValue: string, acrValues: string[]) {\n const provider = acrValueToProviderPrefix(acrValue);\n const count = acrValues.reduce(\n (memo, acrValue) => memo + (acrValueToProviderPrefix(acrValue) === provider ? 1 : 0),\n 0,\n );\n return count === 1;\n}\n\nconst ambigousProviders = ['se:bankid', 'no:bankid'];\n/**\n * A provider is considered ambiguous iff:\n * 1. It is in the list of ambiguous providers\n * 2. There is another ambiguous provider in the arc values list\n */\nexport function isAmbiguous(acrValue: string, acrValues: string[]) {\n const provider = acrValueToProviderPrefix(acrValue);\n const isProviderAmbiguous = ambigousProviders.includes(provider);\n const otherAmbiguousProvider =\n acrValues.find((otherAcrValue) => {\n const otherProvider = acrValueToProviderPrefix(otherAcrValue);\n return provider != otherProvider && ambigousProviders.includes(otherProvider);\n }) != null;\n\n return isProviderAmbiguous && otherAmbiguousProvider;\n}\n\nexport function trySessionStorage() {\n try {\n if (typeof sessionStorage === 'undefined') {\n return null;\n }\n return sessionStorage;\n } catch (err) {\n /**\n * Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.\n * (if storage is disabled in the browser)\n */\n return null;\n }\n}\n","export function createMemoryStorage(): Storage {\n let store: { [key: string]: string } = {};\n\n return {\n getItem(key: string) {\n return store[key] || null;\n },\n setItem(key: string, value: any) {\n store[key] = value.toString();\n },\n removeItem(key: string) {\n delete store[key];\n },\n clear() {\n store = {};\n },\n key(index) {\n return Object.keys(store)[index];\n },\n get length() {\n return Object.keys(store).length;\n },\n };\n}\n","import React, { useMemo, useState, useCallback, useEffect } from 'react';\nimport CriiptoAuth, {\n type AuthorizeUrlParamsOptional,\n clearPKCEState,\n generatePKCE,\n OAuth2Error,\n OpenIDConfiguration,\n type PKCE,\n type PKCEPublicPart,\n type Prompt,\n parseAuthorizeResponseFromLocation,\n} from '@criipto/auth-js';\n\nimport CriiptoVerifyContext, {\n type CriiptoVerifyContextInterface,\n type Action,\n type Result,\n type Claims,\n actions,\n type ResultSource,\n} from './context';\nimport type { AuthorizeResponse, RedirectAuthorizeParams, ResponseType } from '@criipto/auth-js';\n\nimport { version } from '../package.json';\nimport { filterAcrValues, trySessionStorage } from './utils';\nimport jwtDecode from 'jwt-decode';\nimport { createMemoryStorage } from './memory-storage';\n\nconst SESSION_KEY = `@criipto-verify-react/session`;\n\nexport interface CriiptoVerifyProviderOptions {\n domain: string;\n clientID: string;\n /**\n * @deprecated Development use only\n */\n protocol?: 'https' | 'http';\n\n redirectUri?: string;\n children: React.ReactNode;\n pkce?: PKCEPublicPart;\n state?: string;\n nonce?: string;\n prompt?: Prompt;\n scope?: string;\n uiLocales?: string;\n loginHint?: string;\n /**\n * Enables storage and automatic fetch of tokens\n * by utilizing browser storage and SSO silent logins.\n * Make sure \"SSO for OAuth2\" is enabled on your Criipto Domain.\n * Only works for `response: 'token'` (default)\n */\n sessionStore?: Storage;\n /**\n * Will ammend the login_hint parameter with `action:{action}` which will adjust texsts in certain flows.\n * Default: 'login'\n */\n action?: Action;\n /**\n * Will ammend the login_hint parameter with `message:{base64(message)}` which will set a login/aprove message where available (Danish MitID).\n */\n message?: string;\n /**\n * Note: In most cases modifying this setting **is not needed**. Defaults will work with almost all React SPA cases.\n * By default @criipto/verify-react will do PKCE on your behalf and return a jwt token.\n * However if you wish you can disable this and get the raw `code` response by setting `response` to 'code'.\n */\n response?: 'token' | 'code';\n /*\n * Note: In most cases modifying this setting **is not needed**. Defaults will work with almost all React SPA cases.\n * By default @criipto/verify-react will do as much as work on your behalf\n * by interpreting URL parameters and responses with `useCriiptoVerify()` via the default value 'client'.\n * If you wish to only render a UI and redirect to the Criipto IDP for server side code exchange, you can choose 'openidprovider'.\n */\n completionStrategy?: 'client' | 'openidprovider';\n\n /**\n * @deprecated Criipto internal use\n */\n criiptoSdk?: null | string;\n /**\n * @deprecated Criipto internal use\n */\n responseType?: ResponseType | 'code id_token';\n /**\n * @deprecated Criipto internal use\n */\n responseMode?: 'query' | 'form_post' | 'fragment' | 'json' | 'post_message';\n}\n\nexport const ACTION_SUPPORTING_ACR_VALUES = [\n 'urn:grn:authn:dk:mitid:low',\n 'urn:grn:authn:dk:mitid:substantial',\n 'urn:grn:authn:dk:mitid:high',\n 'urn:grn:authn:se:bankid:same-device',\n 'urn:grn:authn:se:bankid:another-device:qr',\n];\n\nexport const MESSAGE_SUPPORTING_ACR_VALUES = [\n 'urn:grn:authn:dk:mitid:low',\n 'urn:grn:authn:dk:mitid:substantial',\n 'urn:grn:authn:dk:mitid:high',\n 'urn:grn:authn:se:bankid:same-device',\n 'urn:grn:authn:se:bankid:another-device:qr',\n];\n\nexport function buildLoginHint(\n loginHint: string | undefined | null,\n params: { options?: AuthorizeUrlParamsOptional; action?: Action; message?: string },\n) {\n const { options, action, message } = params;\n const acrValues = options?.acrValues\n ? Array.isArray(options?.acrValues)\n ? options?.acrValues\n : [options?.acrValues]\n : [];\n let hints = (loginHint ? loginHint.split(' ') : [])\n .concat(options?.loginHint ? options?.loginHint.split(' ') : [])\n .filter((hint) => !hint.startsWith('message:') && !hint.startsWith('action:'));\n if (action) {\n hints = hints.filter((h) => !h.startsWith('action:'));\n if (acrValues.length === 1) {\n if (ACTION_SUPPORTING_ACR_VALUES.includes(acrValues[0])) {\n hints.push(`action:${action}`);\n }\n } else if (acrValues.length >= 2) {\n if (acrValues.some((v) => ACTION_SUPPORTING_ACR_VALUES.includes(v))) {\n hints.push(`action:${action}`);\n }\n } else {\n hints.push(`action:${action}`);\n }\n }\n\n if (message) {\n if (acrValues.length === 1) {\n if (MESSAGE_SUPPORTING_ACR_VALUES.includes(acrValues[0])) {\n hints.push(`message:${btoa(message)}`);\n }\n } else if (acrValues.length >= 2) {\n if (acrValues.some((v) => MESSAGE_SUPPORTING_ACR_VALUES.includes(v))) {\n hints.push(`message:${btoa(message)}`);\n }\n } else {\n hints.push(`message:${btoa(message)}`);\n }\n }\n\n return hints.length ? hints.join(' ') : undefined;\n}\n\nfunction parseAction(input?: string): Action | undefined {\n if (!input) return;\n\n const segments = input.split(' ');\n const actionCandidate = segments.find((s) => s.startsWith('action:'));\n if (!actionCandidate) return;\n const action = actionCandidate.replace('action:', '');\n if (actions.includes(action as any)) return action as Action;\n return;\n}\n\nfunction tryBase64Decode(input: string) {\n try {\n return atob(input);\n } catch {\n return null;\n }\n}\nfunction parseMessage(input?: string): string | undefined {\n if (!input) return;\n const segments = input.split(' ');\n const messageCandidate = segments.find((s) => s.startsWith('message:'));\n if (!messageCandidate) return;\n\n const message = messageCandidate.replace('message:', '');\n return tryBase64Decode(message) ?? message;\n}\n\nfunction defaultRedirectUri(input?: string): string {\n if (input) return input;\n if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {\n return window.location.origin + window.location.pathname;\n }\n\n throw new Error('Unable to determine default redirect uri, please provide a redirectUri');\n}\n\nconst pkceStore = (() => {\n const sessionStorage = trySessionStorage();\n if (sessionStorage === null) {\n console.warn(\n 'Creating memory store for PKCE values as no sessionStorage is available. Authentication may be broken.',\n );\n return createMemoryStorage();\n }\n return sessionStorage;\n})();\n\nconst CriiptoVerifyProvider = (props: CriiptoVerifyProviderOptions): React.ReactElement => {\n const client = useMemo(\n () =>\n new CriiptoAuth({\n domain: props.domain,\n clientID: props.clientID,\n store: pkceStore,\n redirectUri: defaultRedirectUri(props.redirectUri),\n protocol: props.protocol,\n }),\n [props.domain, props.clientID, props.redirectUri, props.protocol],\n );\n\n const [configuration, setConfiguration] = useState<OpenIDConfiguration | null>(null);\n useEffect(() => {\n let isSubscribed = true;\n (async () => {\n const configuration = await client.fetchOpenIDConfiguration();\n if (isSubscribed) setConfiguration(configuration);\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [client]);\n\n const [result, setResult] = useState<Result | null>(null);\n\n // Verify that domain and client id are valid; surface failures as the hook's `error`.\n useEffect(() => {\n let isSubscribed = true;\n (async () => {\n try {\n await client.fetchCriiptoConfiguration();\n } catch (error) {\n if (!isSubscribed) return;\n const err = error instanceof Error ? error : new Error(String(error));\n setResult((prev) => prev ?? err);\n }\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [client]);\n const claims = useMemo(() => {\n if (!result) return null;\n if (!('id_token' in result)) return null;\n return jwtDecode<Claims>(result.id_token);\n }, [result]);\n const [isLoading, setIsLoading] = useState(false);\n const [isInitializing, setIsInitializing] = useState(true);\n const [pkce, setPKCE] = useState<PKCE | PKCEPublicPart | undefined>(props.pkce);\n const responseType = props.response || 'token';\n const completionStrategy = props.completionStrategy || 'client';\n const uiLocales = props.uiLocales;\n const loginHint = props.loginHint;\n const action = props.action ?? parseAction(loginHint) ?? 'login';\n const message = props.message ?? parseMessage(loginHint);\n const sessionStore = props.sessionStore;\n\n const refreshPKCE = async () => {\n if (props.pkce) return props.pkce;\n if (responseType !== 'token' || completionStrategy !== 'client') {\n clearPKCEState(pkceStore);\n setPKCE(undefined);\n return undefined;\n }\n\n clearPKCEState(pkceStore);\n\n const pkce = await generatePKCE();\n setPKCE(pkce);\n return pkce;\n };\n\n const buildOptions = useCallback(\n (\n options?: AuthorizeUrlParamsOptional | RedirectAuthorizeParams,\n ): AuthorizeUrlParamsOptional => {\n return {\n redirectUri: defaultRedirectUri(props.redirectUri),\n responseType: (props.responseType ?? 'code') as ResponseType,\n responseMode: props.responseMode,\n ...(options || {}),\n state: props.state ?? options?.state,\n nonce: props.nonce ?? options?.nonce,\n prompt: props.prompt ?? options?.prompt,\n scope: props.scope ?? options?.scope,\n uiLocales: uiLocales ?? options?.uiLocales,\n pkce: options?.pkce ?? pkce,\n loginHint: buildLoginHint(props.loginHint, { options, action, message }),\n extraUrlParams:\n props.criiptoSdk !== undefined\n ? {\n criipto_sdk: props.criiptoSdk,\n }\n : {\n criipto_sdk: `@criipto/verify-react@${version}`,\n },\n };\n },\n [\n pkce,\n props.state,\n props.nonce,\n props.prompt,\n props.scope,\n uiLocales,\n action,\n message,\n props.redirectUri,\n props.criiptoSdk,\n props.loginHint,\n props.responseMode,\n props.responseType,\n ],\n );\n\n const buildAuthorizeUrl = useCallback(\n async (options?: AuthorizeUrlParamsOptional) => {\n return await client.buildAuthorizeUrl(client.buildAuthorizeParams(buildOptions(options)));\n },\n [client, buildOptions],\n );\n\n const initializePAR = useCallback(\n async (options?: AuthorizeUrlParamsOptional) => {\n return (\n await client.pushAuthorizationRequest(client.buildAuthorizeParams(buildOptions(options)))\n ).authorizeUrl;\n },\n [client, buildOptions],\n );\n\n const handleResponse = useCallback(\n async (\n response: AuthorizeResponse | (Error | OAuth2Error),\n params: { pkce?: PKCE; redirectUri?: string; source?: ResultSource } = {},\n ) => {\n if (response instanceof OAuth2Error) {\n setResult(response);\n } else if (response instanceof Error) {\n setResult(response);\n } else if (params.pkce && responseType === 'token') {\n let _redirectUri = params.redirectUri || defaultRedirectUri(props.redirectUri);\n if (!_redirectUri)\n throw new Error(\n 'redirectUri must be configured globally or per authentication component',\n );\n\n await client\n .processResponse(response, {\n code_verifier: params.pkce.code_verifier,\n redirect_uri: _redirectUri,\n })\n .then((response) => {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: params.source });\n else if (response?.id_token) {\n setResult({\n id_token: response.id_token,\n state: response.state,\n source: params.source,\n });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else setResult(null);\n })\n .catch((err: OAuth2Error) => {\n setResult(err);\n });\n } else {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: params.source });\n else if (response?.id_token) {\n setResult({ id_token: response.id_token, state: response.state, source: params.source });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else if (response?.error)\n setResult(new OAuth2Error(response.error, response.error_description, response.state));\n else setResult(null);\n }\n\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n },\n [refreshPKCE, responseType, setResult, client, sessionStore, props.redirectUri],\n );\n\n const checkSession = useCallback(async () => {\n return client\n .checkSession({ redirectUri: defaultRedirectUri(props.redirectUri) })\n .then((response) => {\n if (response?.code) setResult({ code: response.code });\n else if (response?.id_token) {\n setResult({ id_token: response.id_token });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n } else setResult(null);\n });\n }, [sessionStore, client, props.redirectUri]);\n\n const logout = useCallback(\n async (params?: { redirectUri?: string; state?: string }) => {\n sessionStore?.removeItem(SESSION_KEY);\n await client.logout({\n redirectUri: params?.redirectUri ?? defaultRedirectUri(props.redirectUri),\n state: params?.state,\n });\n },\n [sessionStore, client, props.redirectUri],\n );\n\n const context = useMemo<CriiptoVerifyContextInterface>(() => {\n return {\n loginWithRedirect: async (params) => {\n const pkce = await refreshPKCE();\n await client.redirect.authorize(buildOptions({ ...params, pkce }));\n },\n loginWithPopup: async (params) => {\n return client.popup\n .authorize(buildOptions(params))\n .then((response) => {\n if (response?.code)\n setResult({ code: response.code, state: response.state, source: 'popup' });\n else if (response?.id_token)\n setResult({ id_token: response.id_token, state: response.state, source: 'popup' });\n else setResult(null);\n })\n .catch((err: OAuth2Error) => {\n setResult(err);\n });\n },\n checkSession,\n logout,\n fetchOpenIDConfiguration: () => client.fetchOpenIDConfiguration(),\n buildAuthorizeUrl,\n initializePAR,\n generatePKCE: async () => {\n if (responseType !== 'token' || completionStrategy !== 'client') return;\n return await generatePKCE();\n },\n buildOptions,\n handleResponse,\n responseType,\n completionStrategy,\n result,\n claims,\n domain: client.domain,\n redirectUri: defaultRedirectUri(props.redirectUri),\n action,\n message,\n pkce,\n store: pkceStore,\n isLoading,\n isInitializing,\n acrValues: configuration ? filterAcrValues(configuration.acr_values_supported) : undefined,\n client,\n uiLocales,\n loginHint,\n };\n }, [\n client,\n props.redirectUri,\n responseType,\n completionStrategy,\n result,\n claims,\n action,\n message,\n pkce,\n props.state,\n props.prompt,\n isLoading,\n isInitializing,\n handleResponse,\n logout,\n configuration,\n uiLocales,\n checkSession,\n loginHint,\n ]);\n\n useEffect(() => {\n setIsInitializing(false);\n if (!client.redirect.hasMatch()) {\n refreshPKCE(); // Fresh request, setup PKCE\n return;\n }\n\n let isSubscribed = true;\n setIsLoading(true);\n\n const params = parseAuthorizeResponseFromLocation(window.location);\n if (params.code && responseType === 'code') {\n setIsLoading(false);\n setResult({ code: params.code, source: 'redirect', state: params.state });\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n return;\n }\n\n (async () => {\n await Promise.resolve(); // wait for the initial cleanup in Strict mode - avoids double mutation\n if (!isSubscribed) return;\n\n try {\n const response = await client.redirect.match();\n if (!isSubscribed) return;\n\n if (response?.code) {\n setResult({ code: response.code, source: 'redirect', state: response.state });\n } else if (response?.id_token) {\n setResult({ id_token: response.id_token, source: 'redirect', state: response.state });\n sessionStore?.setItem(SESSION_KEY, response.id_token);\n resetRedirectState(window);\n } else setResult(null);\n } catch (err: any) {\n if (!isSubscribed) return;\n if (err instanceof OAuth2Error) {\n setResult(err);\n } else if (err instanceof Error) {\n setResult(err);\n } else {\n setResult(new Error(err?.toString() ?? 'Unknown error ocurred'));\n }\n } finally {\n if (!isSubscribed) return;\n setIsLoading(false);\n refreshPKCE(); // Clear out session storage and recreate PKCE values if being used\n }\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [props.pkce, responseType]);\n\n /*\n * Fetch claims from session store if available\n */\n useEffect(() => {\n if (!sessionStore || claims) return;\n if (!claims) {\n // No result available, fetch from session store\n const token = sessionStore.getItem(SESSION_KEY);\n if (!token) return;\n\n setResult({ id_token: token });\n return;\n }\n }, [sessionStore, claims]);\n\n /*\n * Unset result if claims are expired\n */\n useEffect(() => {\n if (!claims) return;\n if (!sessionStore) return;\n\n const interval = setInterval(() => {\n const now = Date.now();\n if (claims.exp < now / 1000) {\n setResult(null);\n sessionStore?.removeItem(SESSION_KEY);\n return;\n }\n }, 5000);\n\n return () => clearInterval(interval);\n }, [sessionStore, claims, result]);\n\n /**\n * Fresh page load SSO check\n */\n useEffect(() => {\n setIsInitializing(false);\n if (!sessionStore) return;\n if (client.redirect.hasMatch()) return; // Do not issue SSO check if we're just being redirected back to\n if (sessionStore.getItem(SESSION_KEY)) return;\n let isSubscribed = true;\n\n setIsLoading(true);\n checkSession()\n .catch((err) => {\n console.error('session silent check error', err);\n })\n .finally(() => {\n if (isSubscribed) setIsLoading(false);\n });\n\n return () => {\n isSubscribed = false;\n };\n }, [sessionStore, client]);\n\n return (\n <CriiptoVerifyContext.Provider value={context}>{props.children}</CriiptoVerifyContext.Provider>\n );\n};\n\nexport default CriiptoVerifyProvider;\n\nexport function resetRedirectState(window: Window) {\n const url = new URL(window.location.href);\n url.searchParams.delete('code');\n url.searchParams.delete('state');\n\n window.history.replaceState({}, window.document.title, url.pathname + url.search);\n}\n","import { UAParser } from '@ua-parser-js/pro-enterprise';\n\nfunction testUA(userAgent: string, pattern: RegExp) {\n return pattern.test(navigator.userAgent);\n}\nexport function isiOS(userAgent: string) {\n return testUA(userAgent, /iPad|iPhone|iPod/) && !(window as any).MSStream;\n}\n\nexport function isiOSSafari(userAgent: string) {\n return isiOS(userAgent) && !testUA(userAgent, / CriOS\\/[.0-9]*/);\n}\n\nexport function isAndroid(userAgent: string) {\n return testUA(userAgent, /Android/);\n}\n\nexport type MobileOS = 'ios' | 'android';\n\nexport function getMobileOS(userAgent: string): MobileOS | null {\n if (isiOS(userAgent)) return 'ios';\n if (isAndroid(userAgent)) return 'android';\n\n return null;\n}\n\nexport function getUserAgent(userAgent?: string) {\n if (!userAgent) return null;\n return UAParser(userAgent);\n}\n","import { useEffect } from 'react';\n\nexport interface UsePollProps {\n shouldPoll: boolean;\n pollUrl: string;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => void;\n}\n\nexport function usePoll({ shouldPoll, pollUrl, onComplete, onError }: UsePollProps) {\n useEffect(() => {\n if (!shouldPoll) return;\n let isSubscribed = true;\n let timeout: string | undefined;\n const poll = async () => {\n if (!isSubscribed) return;\n const response = await fetch(pollUrl);\n\n if (response.status === 202) {\n setTimeout(poll, 1000);\n return;\n } else if (response.status >= 400) {\n if (!isSubscribed) return;\n const error = await response.text();\n onError(error);\n return;\n } else {\n if (!isSubscribed) return;\n const { targetUrl } = await response.json();\n onComplete(targetUrl);\n return;\n }\n };\n\n setTimeout(poll, 1000);\n return () => {\n isSubscribed = false;\n if (timeout) clearTimeout(timeout);\n };\n }, [shouldPoll, pollUrl]);\n}\n","import React, { useContext, useState } from 'react';\nimport CriiptoVerifyContext from '../../context';\nimport type { Links } from './shared';\nimport { usePoll } from './usePoll';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n}\n\n/*\n * Desktop: Polling scenario\n */\nexport default function SEBankIDSameDevicePoll(props: Props) {\n const { links, onError, onComplete, onInitiate } = props;\n const [initiated, setInitiated] = useState(false);\n const { domain } = useContext(CriiptoVerifyContext);\n\n usePoll({\n ...props,\n shouldPoll: initiated,\n pollUrl: links.pollUrl,\n });\n const handleInitiate = () => {\n onInitiate();\n setInitiated(true);\n };\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","import React, { useRef, useState, useEffect } from 'react';\n\nexport default function usePageVisibility(onVisible?: () => void, deps: React.DependencyList = []) {\n const visibilityState = useRef(document.visibilityState);\n const [state, setState] = useState(visibilityState.current);\n\n useEffect(() => {\n document.addEventListener('visibilitychange', _handleVisibilityChange);\n\n return () => {\n document.removeEventListener('visibilitychange', _handleVisibilityChange);\n };\n }, deps);\n\n const _handleVisibilityChange = () => {\n const nextState = document.visibilityState;\n if (visibilityState.current === 'hidden' && nextState === 'visible') {\n if (onVisible) onVisible();\n }\n\n visibilityState.current = nextState;\n setState(visibilityState.current);\n };\n\n return state;\n}\n","import React, { useCallback, useEffect, useState } from 'react';\nimport usePageVisibility from '../../hooks/usePageVisibility';\nimport type { Links } from './shared';\nimport { usePoll } from './usePoll';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n}\n\n/*\n * Android + iOS Chrome: Background/Foreground scenario\n */\nexport default function SEBankIDSameDeviceForeground(props: Props) {\n const { links, onInitiate, onLog } = props;\n const [initiated, setInitiated] = useState(false);\n\n // Polling might complete while the browser is in the background, but we don't want to invoke the\n // complete callbacks before the browser is focused. So we store the result here.\n const [result, setResult] = useState<{ result: string } | { error: string } | null>(null);\n\n const onComplete = useCallback((completeUrl: string) => setResult({ result: completeUrl }), []);\n const onError = useCallback((error: string) => setResult({ error: error }), []);\n\n const visibility = usePageVisibility(() => {\n onLog('ForegroundStrategy', 'onForeground', initiated.toString());\n }, [initiated]);\n\n useEffect(() => {\n if (result && visibility === 'visible') {\n if ('result' in result) {\n props.onComplete(result.result);\n } else if ('error' in result) {\n props.onError(result.error);\n }\n // Clear result, so we don't call error / complete several times, if visibility changes\n setResult(null);\n }\n }, [result, visibility]);\n\n usePoll({\n shouldPoll: initiated,\n pollUrl: links.pollUrl,\n onComplete,\n onError,\n });\n\n const handleInitiate = () => {\n onLog('ForegroundStrategy', 'handleInitiate');\n onInitiate();\n setInitiated(true);\n };\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","import type { PKCE } from '@criipto/auth-js';\nimport { createMemoryStorage } from '../../memory-storage';\nimport { trySessionStorage } from '../../utils';\n\nexport interface Links {\n cancelUrl: string;\n completeUrl: string;\n pollUrl: string;\n launchLinks: {\n customFileHandlerUrl: string;\n universalLink: string;\n };\n}\n\nexport interface State {\n pkce: PKCE | undefined;\n redirectUri: string;\n links: Links;\n}\n\nconst STATE_KEY = '@criipto/verify-react:sebankid:state';\n\nconst stateStore = (() => {\n const sessionStorage = trySessionStorage();\n if (sessionStorage === null) {\n console.warn(\n 'Creating memory store for PKCE values as no sessionStorage is available. Authentication may be broken.',\n );\n return createMemoryStorage();\n }\n return sessionStorage;\n})();\n\nexport function hydrateState(): State | undefined {\n const rawState = stateStore.getItem(STATE_KEY);\n if (rawState) {\n return JSON.parse(rawState) as State;\n }\n\n return undefined;\n}\n\nexport const autoHydratedState = hydrateState();\n\nexport function clearState() {\n stateStore.removeItem(STATE_KEY);\n}\n\nexport function saveState(input: State): void {\n stateStore.setItem(STATE_KEY, JSON.stringify(input));\n}\n","import type { PKCE } from '@criipto/auth-js';\nimport React, { useEffect, useState } from 'react';\nimport { type Links, saveState, hydrateState, clearState } from './shared';\n\ninterface Props {\n children: React.ReactElement;\n links: Links;\n onError: (error: string) => void;\n onComplete: (completeUrl: string) => Promise<void>;\n onInitiate: () => void;\n onLog: (...statements: string[]) => void;\n pkce: PKCE | undefined;\n redirectUri: string;\n}\n\n/*\n * iOS Safari: Page reload on switch back scenario\n */\n\nexport default function SEBankIDSameDeviceReload(props: Props) {\n const { links, onError, onComplete, onInitiate, onLog, pkce, redirectUri } = props;\n\n const handleInitiate = () => {\n onLog('ReloadStrategy', 'handleInitiate');\n\n saveState({\n links,\n redirectUri,\n pkce,\n });\n\n onInitiate();\n };\n\n useEffect(() => {\n const hydratedState = hydrateState();\n if (!hydratedState) return;\n clearState();\n onComplete(hydratedState.links.completeUrl);\n }, []);\n\n return React.cloneElement(props.children, {\n ...(props.children.props as any),\n onClick: handleInitiate,\n });\n}\n","\"data:image/png;base64,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\"","import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { type AuthorizeResponse, OAuth2Error, type PKCE } from '@criipto/auth-js';\nimport QRCode from 'qrcode';\nimport { type Language } from '../i18n';\n\nimport CriiptoVerifyContext from '../context';\n\nimport logo from './SEBankIDQRCode/logo@2x.png';\nimport './SEBankIDQRCode/SEBankIDQRCode.css';\nimport { getI18n } from '../i18n';\n\ninterface Props {\n redirectUri?: string;\n qrMargin?: number;\n /**\n * Impacts the help text\n */\n language?: Language;\n children?: (props: {\n qrElement: React.ReactElement;\n /**\n * Can be rendered instead of `qrElement` if you only wish to render the qr code with no additional content.\n * Combine with `qrMargin`.\n */\n imageElement: React.ReactElement;\n /**\n * Will be true once the user has completed login in the app and the rest of the login flow is being processed\n */\n isCompleting: boolean;\n /**\n * The user has clicked on the qr image element to trigger fullscreen view per https://developers.bankid.com/getting-started/qr-code#accessibility\n */\n fullscreen: boolean;\n error: OAuth2Error | Error | null;\n retry: () => void;\n }) => React.ReactElement;\n\n /** Render fallback element while loading */\n fallback?: React.ReactElement;\n}\n\ninterface QrResponse {\n initialQrCode: string;\n pollUrl: string;\n}\ninterface PollResponse {\n qrCode?: string;\n targetUrl?: string;\n}\n\nfunction searchParamsToPOJO(input: URLSearchParams) {\n return Array.from(input.keys()).reduce((memo: { [key: string]: string }, key) => {\n memo[key] = input.get(key)!;\n return memo;\n }, {});\n}\n\nexport default function SEBankIDQrCode(props: Props) {\n const wrapperRef = useRef<HTMLButtonElement>(null);\n const {\n buildAuthorizeUrl,\n completionStrategy,\n handleResponse,\n generatePKCE,\n redirectUri: defaultRedirectURi,\n uiLocales,\n } = useContext(CriiptoVerifyContext);\n const language = (props.language ?? uiLocales ?? 'en') as Language;\n const redirectUri = props.redirectUri || defaultRedirectURi;\n const [qrCode, setQrCode] = useState<string | null>(null);\n const [pollUrl, setPollUrl] = useState<string | null>(null);\n const [error, setError] = useState<OAuth2Error | Error | null>(null);\n const [pkce, setPKCE] = useState<PKCE | undefined>(undefined);\n const [isCompleting, setCompleting] = useState(false);\n const [fullscreen, setFullscreen] = useState(false);\n\n const refresh = useCallback(async () => {\n setError(null);\n setQrCode(null);\n setPollUrl(null);\n setPKCE(undefined);\n\n const pkce = await generatePKCE();\n\n buildAuthorizeUrl({\n acrValues: 'urn:grn:authn:se:bankid:another-device:qr',\n responseMode: 'json',\n pkce,\n redirectUri,\n prompt: 'login', // Triggering SSO at this point would be a mistake\n })\n .then((url) => {\n return fetch(url).then((response) => response.json() as Promise<QrResponse>);\n })\n .then((response) => {\n setPKCE(pkce);\n setQrCode(response.initialQrCode);\n setPollUrl(response.pollUrl);\n })\n .catch(console.error);\n }, [buildAuthorizeUrl, redirectUri]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const handleRetry = () => {\n setCompleting(false);\n refresh();\n };\n\n const handleError = useCallback(\n (error: string) => {\n /* Timeout error */\n if (error === 'Collect failed: startFailed' || error === '\"Collect failed: startFailed\"') {\n handleRetry();\n return;\n }\n setError(new Error(error));\n handleResponse(new Error(error), {\n pkce,\n redirectUri,\n source: 'SEBankIDQrCode',\n });\n },\n [pkce, redirectUri],\n );\n\n const handleComplete = useCallback(\n async (completeUrl: string) => {\n setCompleting(true);\n const required = { pkce };\n const parsed = await parseCompleteUrl(completeUrl);\n\n if (parsed instanceof Error) {\n return handleError(parsed.message);\n }\n\n const { location, response } = parsed;\n\n if (completionStrategy === 'openidprovider') {\n window.location.href = location;\n return;\n }\n await handleResponse(response, {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDQrCode',\n });\n },\n [completionStrategy, pkce],\n );\n\n /**\n * Render QR codes\n */\n const qrDataURL = useDraw(qrCode, {\n width: fullscreen\n ? (window.innerHeight ?? wrapperRef.current?.offsetWidth)\n : wrapperRef.current?.offsetWidth,\n // 2 is half of the default 4, less margin is required in fullscreen\n qrMargin: props.qrMargin ?? (fullscreen ? 2 : undefined),\n });\n\n /**\n * Poll for response\n */\n usePoll(pollUrl, {\n enabled: !isCompleting,\n onQrCode: setQrCode,\n onComplete: handleComplete,\n onError: handleError,\n });\n\n const i18n = getI18n(language);\n\n const imageElement = (\n <button\n aria-label={i18n.thisIsTheQR}\n ref={wrapperRef}\n className=\"criipto-se-bankid-qr-canvas\"\n onClick={() => setFullscreen((val) => !val)}\n >\n {qrDataURL ? <img src={qrDataURL} /> : null}\n </button>\n );\n\n const qrElement = (\n <div className=\"criipto-se-bankid-qr\">\n <aside className=\"criipto-se-bankid-qr--help-text\">\n {isCompleting ? i18n.completingLogin : i18n.openAndScan}\n <img src={logo} />\n </aside>\n\n {imageElement}\n </div>\n );\n\n if (!qrCode && props.fallback) {\n return props.fallback;\n }\n\n if (props.children) {\n return props.children({\n qrElement,\n imageElement,\n error,\n isCompleting,\n retry: () => handleRetry(),\n fullscreen,\n });\n }\n\n if (fullscreen) {\n return (\n <dialog className=\"criipto-se-bankid-qr-fullscreen\" open>\n {imageElement}\n </dialog>\n );\n }\n\n return qrElement;\n}\n\nSEBankIDQrCode.acr_values = 'urn:grn:authn:se:bankid:another-device:qr';\n\ntype UseDrawOptions = {\n width?: number;\n qrMargin?: number;\n};\nexport function useDraw(qrCode: string | null, options: UseDrawOptions) {\n const { width, qrMargin } = options;\n const [dataURL, setDataURL] = useState<string | null>(null);\n\n useEffect(() => {\n if (!qrCode) return;\n\n let isSubscribed = true;\n (async () => {\n const qrImage = await QRCode.toDataURL(qrCode, {\n errorCorrectionLevel: 'low',\n scale: 10,\n width,\n margin: qrMargin ?? 4,\n });\n\n if (!isSubscribed) return;\n setDataURL(qrImage);\n })();\n\n return () => {\n isSubscribed = false;\n };\n }, [qrCode, qrMargin, width]);\n\n return dataURL;\n}\n\ntype UsePollOptions = {\n enabled: boolean;\n onQrCode: (code: string) => void;\n onComplete: (url: string) => void;\n onError: (error: string) => void;\n};\nexport function usePoll(pollUrl: string | null, options: UsePollOptions) {\n const { onQrCode, onComplete, onError, enabled } = options;\n useEffect(() => {\n if (!pollUrl) return;\n if (!enabled) return;\n\n const delay = 2500;\n let timeout: any;\n let isSubscribed = true;\n const poll = async () => {\n if (!isSubscribed) return;\n const response = await fetch(pollUrl);\n\n if (!isSubscribed) return;\n if (response.status < 400) {\n const payload = (await response.json()) as PollResponse;\n if (payload.qrCode) onQrCode(payload.qrCode);\n if (payload.targetUrl) {\n onComplete(payload.targetUrl);\n return;\n }\n } else {\n const text = await response.text();\n onError(text);\n }\n\n if (response.status === 202) {\n timeout = setTimeout(poll, delay);\n }\n };\n\n timeout = setTimeout(poll, delay);\n return () => {\n isSubscribed = false;\n clearTimeout(timeout);\n };\n }, [pollUrl, onQrCode, onComplete, onError, enabled]);\n}\n\nexport async function parseCompleteUrl(\n completeUrl: string,\n): Promise<{ location: string; response: AuthorizeResponse } | Error> {\n /**\n * Handle verify response inconsistencies\n */\n if (completeUrl.includes('error=')) {\n const url = new URL(completeUrl);\n const completeParams = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n\n return { location: completeUrl, response: completeParams };\n }\n\n const completeResponse = await fetch(completeUrl);\n if (completeResponse.status >= 400) {\n return new Error(await completeResponse.text());\n }\n\n const { location }: { location: string } = await completeResponse.json();\n const url = new URL(location);\n const params = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n return { location: location, response: params };\n}\n","import React, { createContext, useState } from 'react';\nimport {\n AuthMethodButtonContainer,\n type AuthMethodButtonContainerProps,\n AuthMethodButtonComponent,\n type AuthMethodButtonComponentProps,\n} from './AuthMethodButton';\nimport SEBankIDQrCode from './SEBankIDQRCode';\n\ninterface AuthButtonGroupContextInterface {\n multiple: boolean;\n acrValues: string[];\n disabled: boolean;\n setDisabled: (disabled: boolean) => void;\n}\nconst initialContext: AuthButtonGroupContextInterface = {\n multiple: false,\n acrValues: [],\n disabled: false,\n setDisabled: () => {},\n};\nexport const AuthButtonGroupContext =\n createContext<AuthButtonGroupContextInterface>(initialContext);\n\nexport default function AuthButtonGroup(props: { children: React.ReactNode }) {\n const acrValues = React.Children.toArray(props.children).flatMap((child) => {\n if (!child || typeof child !== 'object') return [];\n if ('type' in child) {\n if (child.type === AuthMethodButtonContainer) {\n const props = child.props as AuthMethodButtonContainerProps;\n return props.acrValue ? [props.acrValue] : [];\n }\n if (child.type === AuthMethodButtonComponent) {\n const props = child.props as AuthMethodButtonComponentProps;\n return props.acrValue ? [props.acrValue] : [];\n }\n if (child.type === SEBankIDQrCode) {\n return ['urn:grn:authn:se:bankid:another-device:qr'];\n }\n }\n return [];\n });\n const [disabled, setDisabled] = useState(false);\n\n const context: AuthButtonGroupContextInterface = {\n multiple: acrValues.length > 1,\n acrValues,\n disabled,\n setDisabled,\n };\n return (\n <AuthButtonGroupContext.Provider value={context}>\n {props.children}\n </AuthButtonGroupContext.Provider>\n );\n}\n","import type { ReactElement } from 'react';\nimport './Spinner.css';\n\nexport function Spinner(): ReactElement {\n return <div className=\"criipto-eid-loader\"></div>;\n}\n","import type { PKCE, AuthorizeResponse } from '@criipto/auth-js';\nimport React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport CriiptoVerifyContext from '../context';\nimport { getUserAgent } from '../device';\n\nimport PollStrategy from './SEBankIDSameDeviceButton/Poll';\nimport ForegroundStrategy from './SEBankIDSameDeviceButton/Foreground';\nimport ReloadStrategy from './SEBankIDSameDeviceButton/Reload';\n\nimport { autoHydratedState, type Links } from './SEBankIDSameDeviceButton/shared';\nimport { AuthButtonGroupContext } from './AuthButtonGroup';\nimport classNames from 'classnames';\nimport { Spinner } from './Spinner/Spinner';\n\ninterface Props {\n className: string;\n children: React.ReactNode;\n logo: React.ReactNode;\n fallback: React.ReactElement;\n redirectUri?: string;\n userAgent?: string;\n disabled?: boolean;\n}\n\nfunction searchParamsToPOJO(input: URLSearchParams) {\n return Array.from(input.keys()).reduce((memo: { [key: string]: string }, key) => {\n memo[key] = input.get(key)!;\n return memo;\n }, {});\n}\n\ntype Resume = 'Foreground' | 'Reload' | 'Poll';\ntype LinkType = 'universal' | 'scheme';\nexport function determineStrategy(\n input: string | undefined,\n loginHint?: string,\n): {\n resume: Resume;\n linkType: LinkType;\n redirect: boolean;\n} {\n const userAgent = getUserAgent(input);\n const mobileOS =\n userAgent?.os.name === 'iOS'\n ? 'iOS'\n : userAgent?.os.name === 'Android'\n ? 'android'\n : userAgent?.browser.name === 'Samsung Internet'\n ? 'android'\n : null;\n const iOSSafari =\n mobileOS === 'iOS' && userAgent?.browser.name?.includes('Safari') ? true : false;\n const androidChrome =\n mobileOS === 'android' && userAgent?.browser.name === 'Mobile Chrome' ? true : false;\n const redirect = iOSSafari && !loginHint?.includes('appswitch:resumeUrl:disable');\n\n const resume: Resume = mobileOS ? (iOSSafari && redirect ? 'Reload' : 'Foreground') : 'Poll';\n\n const linkType = mobileOS === 'iOS' || androidChrome ? 'universal' : 'scheme';\n\n return { resume, linkType, redirect };\n}\n\nexport class NotDoneError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotDoneError';\n }\n}\n\nasync function fetchComplete(completeUrl: string) {\n const completeResponse = await fetch(completeUrl);\n if (completeResponse.status >= 400) {\n const errorMessage = await completeResponse.text();\n const notDone = errorMessage.includes('Native-app driven authentication is not done');\n if (notDone) return new NotDoneError(errorMessage);\n return new Error(errorMessage);\n }\n\n const { location }: { location: string } = await completeResponse.json();\n return { location };\n}\nexport default function SEBankIDSameDeviceButton(props: Props) {\n const { loginHint } = useContext(CriiptoVerifyContext);\n const group = useContext(AuthButtonGroupContext);\n\n const rawUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : props.userAgent;\n const strategy = useMemo(\n () => determineStrategy(rawUserAgent, loginHint),\n [rawUserAgent, loginHint],\n );\n\n const [href, setHref] = useState<null | string>();\n const [links, setLinks] = useState<Links | null>(autoHydratedState?.links ?? null);\n const [pkce, setPKCE] = useState<PKCE | undefined>(autoHydratedState?.pkce ?? undefined);\n const [error, setError] = useState<string | null>(null);\n const [log, setLog] = useState<(string | string[])[]>([]);\n const [initiated, setInitiated] = useState(autoHydratedState ? true : false);\n const {\n buildAuthorizeUrl,\n completionStrategy,\n generatePKCE,\n handleResponse,\n redirectUri: defaultRedirectURi,\n domain,\n } = useContext(CriiptoVerifyContext);\n const redirectUri = props.redirectUri || defaultRedirectURi;\n\n const disabled = props.disabled || group.disabled || initiated;\n\n const reset = () => {\n setPKCE(undefined);\n setLinks(null);\n };\n\n const handleLog = (...statements: string[]) => {\n setLog((logs) => logs.concat([statements]));\n };\n\n const handleComplete = useCallback(\n async (completeUrl: string) => {\n const required = { pkce };\n reset();\n\n const result =\n completeUrl.startsWith(`https://${domain}`) || completeUrl.startsWith(`http://${domain}`)\n ? await fetchComplete(completeUrl)\n : {\n location: completeUrl,\n };\n if (result instanceof NotDoneError && strategy.resume === 'Reload') {\n await handleResponse(\n {\n error: 'access_denied',\n },\n {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n },\n );\n return;\n }\n if (result instanceof Error) {\n setError(result.message);\n return;\n }\n const { location } = result;\n if (completionStrategy === 'openidprovider') {\n window.location.href = location;\n return;\n }\n const url = new URL(location);\n const params = searchParamsToPOJO(url.searchParams) as AuthorizeResponse;\n\n await handleResponse(params, {\n pkce: required.pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n });\n },\n [completionStrategy, pkce, domain, strategy],\n );\n\n const refresh = useCallback(async () => {\n handleLog('SEBankID: Refresh authorize url');\n const pkce = await generatePKCE();\n\n buildAuthorizeUrl({\n acrValues: 'urn:grn:authn:se:bankid:same-device',\n // When used on a mobile device, we might have already set appswitch login hints\n loginHint: loginHint?.includes('appswitch:') ? undefined : 'appswitch:browser',\n responseMode: 'json',\n pkce,\n redirectUri,\n prompt: 'login', // Triggering SSO at this point would be a mistake\n })\n .then((url) => {\n return fetch(url).then((response) => response.json() as Promise<Links>);\n })\n .then((links) => {\n setPKCE(pkce || undefined);\n setLinks(links);\n\n const redirect = strategy.redirect ? window.location.href : 'null';\n const newUrl = new URL(\n strategy.linkType === 'universal'\n ? links.launchLinks.universalLink\n : links.launchLinks.customFileHandlerUrl,\n );\n newUrl.searchParams.set('redirect', redirect);\n const newHref = newUrl.href;\n\n handleLog(window.location.href);\n handleLog(newHref);\n setHref(newHref);\n })\n .catch((err) => {\n setInitiated(false);\n });\n }, [buildAuthorizeUrl, redirectUri, strategy]);\n\n // Generate URL on first button render\n useEffect(() => {\n if (initiated) return;\n refresh();\n }, [refresh, initiated]);\n\n // Continously fetch new autostart token if UI is open for a long time\n useEffect(() => {\n if (initiated) return;\n\n const interval = setInterval(() => {\n if (initiated) return;\n refresh();\n }, 25000);\n return () => clearInterval(interval);\n }, [refresh, initiated]);\n\n // Track when the button is clicked to stop refreshing URL\n const handleInitiate = () => {\n group.setDisabled(true);\n handleLog('Initiated');\n setInitiated(true);\n setError(null);\n };\n\n const handleError = async (error: string) => {\n group.setDisabled(false);\n setInitiated(false);\n setError(error);\n\n if (error === 'access_denied' || error === '\"access_denied\"') {\n await handleResponse(\n {\n error: 'access_denied',\n },\n {\n pkce,\n redirectUri,\n source: 'SEBankIDSameDeviceButton',\n },\n );\n }\n };\n\n const element = href ? (\n <a\n className={classNames(props.className, { 'criipto-eid-btn--disabled': disabled })}\n href={href}\n onClick={handleInitiate}\n >\n {initiated ? (\n <div className=\"criipto-eid-logo\">\n <Spinner />\n </div>\n ) : (\n props.logo\n )}\n {props.children}\n </a>\n ) : (\n props.fallback\n );\n\n return (\n <React.Fragment>\n {links ? (\n <React.Fragment>\n {strategy.resume === 'Poll' ? (\n <PollStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n >\n {element}\n </PollStrategy>\n ) : strategy.resume === 'Foreground' ? (\n <ForegroundStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n >\n {element}\n </ForegroundStrategy>\n ) : strategy.resume === 'Reload' ? (\n <ReloadStrategy\n links={links}\n onError={handleError}\n onComplete={handleComplete}\n onInitiate={handleInitiate}\n onLog={handleLog}\n redirectUri={redirectUri!}\n pkce={pkce}\n >\n {element}\n </ReloadStrategy>\n ) : (\n element\n )}\n </React.Fragment>\n ) : (\n element\n )}\n {error && <p>{error}</p>}\n {/* {log && (\n <pre>\n {JSON.stringify(log, null, 2)}\n </pre>\n )} */}\n </React.Fragment>\n );\n}\n","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALAAAABICAYAAABWdn8qAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAsKADAAQAAAABAAAASAAAAACoGQzqAAAJX0lEQVR4Ae2c/XXbuBLF7T37/9NWsEwF0VZguoJoK1ilguhVYG8F9lYguYJ4KyBTQfQqIFOB1UHe7zpEDgUBEs0PiR+Yc25ADAaD4cwNCEpKrq6ChAwMOAPXA459MKF///49ItgYvAczINmBb2B7fX2d0gYJGehHBiDsDCzBGmTglGQYrEHUjzsIUUwqAxBPhI3BA/gKmoh8mF16Unmsc7PhCFEna8yBZDHNHHwo2jZJl+PzlqOF2iBHMhAIfCQ55SEIG9FfgBsQgzYJi7sDydEEEh+kZV8RCLyfj5+94jEuwurFS20Ezi05CwYSH8l6IHApOcWxwBwJ4tLQJS9zFg8kvmQF+r62iAsS0FfJCCzqex5DfBfIAMTQW/8QJCPIQGKLI5M9QkAGvYR9BrGVkz53c4ILx4lShSZJ4IK8CXmYl3IxlMucQAOJi2r9MpSqtRznHf585H1m7I9rhPZPkIM+SUQwSThO9KkkZ4yFwusrXp9kdigY6gWvj5IRVGTHO7X+5I4QFF0k9RV+w8b70SaB2Gvr6KfgqdDrPP0JREX/XE3OQuE4ca5sX3odeHhs9xVPEztGdJEGHBKVbRmfO2zOocpYZC+Wclxjv57aGfivEwXVcSG2bLSzHgg7dW4pd1b/XN2IhZKpkvj6XFm+9DpFgXV8qCJ6kcvBHMTgQCDwXu4K/18xFJGjgwndK3KWCMeJ7vN8mRUg2AK0JvZd4Fg/qZxJT6tjh/2zygTdUmNmLtfmZ5grrjPQVDIc/PRv1gntCDJAYdeginzGaF1CxvWBnEoJE3QckbyARQV7kflRExpKxvzo1HphfGAZoKgq7ClxvcQtXJOq3H4xb1XF1tgwJ5DYJCO0PzIAKfRIryIuApuddG/+qdxirDWdZ2702m01/nrkKPsq9DSNJcNDVPY9xuupfAoRVyxeXtHuqBnEETH1O4vUNixIJWILOifPLZsDUlvjVbsRhuuqxkO1mwqBP3RdIBETiJAJa4mcIuY3x7oxOkPSiGududVe0Up/p+uWJMbnqiVfwc2lMkAR9SJVRQ52LCaJBAdi3wsGIrAtB/40DyOdczPLOKFfNU5r6tHuix3rmPqj34EpbUzBzI537trpBfBgbT5CXoF3BHMLnoqgYtoD22KsSaPz9qKJgz7PHT2BSf78ggUQIR9860PiFCwZF5n/BjnoQpZdOO2DzykQuPPz74lCLtkBMxD77CBxDu4Z146cg7blpm2HffE3agJDGu2AccNky0dTiXCQEI9e8kRo9Q9EREYpEu8OBpspXj+2a+ain7NHTWBSPu8o7XUJpnj0YpdB4gQs7fgKEv9r61voz1rw0TsXYyfwooWMp/iwCfts+y2Il9t6+v+AP4B21i0wEnOxhsSuGHNj1GI7a9FXb1z92ptIugnkrWe/3+wwIOYOkomA2jkj8AQegUtEUmOXc/3E/A3tq+BH419B9Krw/zFKsvlvt/7Idf2p/Z4JWSIizN4Y5Q77d5BObSdSxLXE+e/gC2ttaPcEG5F8vqds3tG/89s2dxM8nCUDkEAvS3VkdZYAPYsQsD47bltePMsNXj3mM/BNzeo8wJ5KJMYuqrmGc1rh78E52EwZdt5m+Tv/bMiQgSayZnLsihx9BBIguQORx+71WzDGPwM9EWZH7O4Y7+KrZNxW+wvpiq3vulGegSnYnMTrHNmG7HCiHUytMC9AsycpPWOjAdlFYAbKsqWTA9lKfHY/Rtv5c7Tn37ESeEXdu3gUt0Mnv5eUof8BQ+4Z1+9BDOqKvuV7V3dymHeBDLADJ6ANSXBy8M0ZOh0NYrABZcnorICI9ypcR0A+MuCTNQNzM8duGdN6p3xg4hR9rBdkSBmgjPrKtolkTI6r3DN2IqxEZP5JXNdcxu9laMnSZevSMS8CmTX/VLeyf9eaQXeBDJyq6InxjPHoLWFjv6xqj61e6Iysqs4zdkwUid/ysheZuaEdSAYMO2q2yy5vsyCgQnM+2tHH4EHjwBmL9KCKtPUi22VKgm87A1T2LTtUmQiZ7Ut9DHQG1VHhHkQuG6Nj3BDQa4tN4vKD7g7Y8hXFwdEEXZV7fDRxhXZAGaC4Gagj9/Zt4iQCNlkWtp362N2BsmheZNuiix06reOTe4f9o8+4pHfGafsacn+s38R9qVmUrWOeHvUzS//J6ou8srm39NKtLN0VH2ulto7+wqEzqt/NRandlq59l6lvIOh7nAHIZD4ZKG1GlS5j+7Y8s14cdr4d9Nm2baNPXLEnNqNO2lin7z7GugNvaiY+rzhvVtFOZv95g22bpnWfQm3G0LmvURKYR/SOzHWy83VekeoL3JwwTU+Mj2J4zD9o/y8VWgylSjoSEOtdxXj1BJgfsd15ztlHpgxzaLQEpoA5pPibslQlRR8qGB8JIi3GjtmY6ZM4PpibHXULiRNQVSI7Gb6JDjvfS9zByxQ+F0C76J6g23jWWxpDxucem7L6p72ZN9Z2lGdgq1h/0t9aukt3Rd6VHQRPjSW6jyAFOXgGt+g3tK/Cte4l/dHz/imbIGPJAFvTDOgbrVMS2ffsm+Cwe8sOvMSv80sO26+rz9zEFxf6zDVnrLop7MD64mBHAW/BqZ1pVrXQEMW2tfvGlUsvnSAiRsawSot9jJ3gk9Q3EPQDz4BIB47txA/lW8T2E/DJyrJd+wzRR8aWa8WQASMZF0sz7mux0bw7cEoWPh9j1F+P8aaO3RPVf935sJl77Dbo9Rb/HuyRlL4tGxTfwA2IgU9yBlKgf23xF3CtnaP/B2yBro3EXCiWJZiBU/KOJ05+ymgs45MjsApXgcRDre8G8n4cavB14p4kgZWokZJ4Uruv6jiJlzjdqC3sVDt0t0CP7DGIdt98DDfylnuY7A5skjSSnVjEvQ0ENlWdWDtwEutJov/3IZ9Y2V5vd7JHiHKxKf5QjxMi7SR3XlO/QOAiEwMkcVqQdyxneMPJ0DbJgI4T4NiXHQxfVDJWXza5xzHNnfxLnKuYEGSGXr8im7vGL6DTEecZPPGkSC+wfm+XDAT2lObCJBZht+Bf8Axpc9ogjgwEAjuSYlRnJnHKul9AGnZZU4HQNs6ASAw+g7Ylw+EjWIBZ40CDg5CBYxmAZPoNbwbqygsT12AFomNrhbGQgU4yIOKBqkQWYRMgwsadBBScXoUzcE0SQMo5Uw3K//eDfjKpF7AtZ9ldTfdhWshAyMAUMvB/9l5bjLOCCUUAAAAASUVORK5CYII=\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALAAAABICAYAAABWdn8qAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAsKADAAQAAAABAAAASAAAAACoGQzqAAADbUlEQVR4Ae2agVHbMBSGSa8DMIJH6Ab1BmWEdgLSCWImgE4AjNAJmhE6gkdgg/R/xXAc957tEMeWrE93hvCkSL8+/XlIdi4uKBCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCJxG4HA4NLrWUupTaAjC9wBEc0q/qb33U2qC0PNKYPf6ihchAQwcolm8olYG3S6uInEBGDjtBdrJxJdpS1xWHQZelv/Q6GZethI9lD731K2p6q8m83viCZm5roM+b4L4+/AYc26VhR83m43NgbJmAlro6C7E/dTz1liVLreMHct9sx/8M7bPl3bqhrsQLzD4vTgBO9BdLa4iQQHsgRNclEDSrUxs2xbKGwIY+A2MRF620vHoaKkU2zrxokMYOM3lbyTryZF2rSxcOfFiQxg4waXXHYdWsn450mwLMfmB1BknmxAGTnep7iTNy8J2oKvTlT2vMgw8L+/RoykLm3m9LGx93HOge0aJgZ85pPozysKVBG9TFT2nLgw8J+0jxxrIwhzoxLMUA0dPpfSfeFSpj/TelM2jLHypQW6nHCjHvkoxcI5r819zl4Wj71Zc6eNXZzu5CYRj4AkgnrsLmdiy8D4Yp+gsjIEDVyQYjrLwF2XhYg90GDhBp3qSlIX3inuPmK35Tia2PXFxhe8Dj1vydlyzs7eyTPtN13uz2t9W1+gqqhRjYGWwJveVtQOdMq093PC+CG+31R7Ups19nsfoZwtxDK0E2nYfxNaRYlnYM7bTdD0hDJznWv4IZNv97iqoW2UYA2e4rMrCe8m2yytF3VbDwJ4F8ohZFn5ypBb1cAMDOw7IIdQd1qJvqxWzF8bAObg11ninqtaprhX76sRXF8LAGS+psrBtIcIDXcZTGy0dA49GlWbDgQNdmqInVIWBJ4S5YFdRFl5Q0jxDY+B5OJ91lO5Ad3PWQRLtHAMnujAfkGUHOu+22ge6yuctGDiftepV2h3ofvY2WmElBl7RosrED5rOfkVTGpwKBh5ElF2DovbCGDg7f/YL7m6rRU/o+t9MLQQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAuMI/AMbHRP0yohB0QAAAABJRU5ErkJggg==\"","import React from 'react';\nimport dkmitid from './logos/dkmitid.png';\nimport dkmitiderhverv from './logos/dkmitiderhverv.png';\nimport ftnmobile from './logos/ftnmobile.png';\nimport itsme from './logos/itsme.png';\nimport nobankid from './logos/nobankid.png';\nimport novipps from './logos/novipps.png';\nimport sebankid from './logos/sebankid.png';\nimport sefrejaid from './logos/sefrejaid.png';\nimport depersonalausweis from './logos/depersonalausweis.png';\nimport ukoneid from './logos/ukoneid.png';\nimport idin from './logos/idin.png';\nimport ftn from './logos/ftn.png';\n\nexport interface AuthMethodButtonLogoProps {\n acrValue: string;\n /**\n * base64 image string, e.x. data:image/png;base64,\n * or a ReactElement\n */\n logo?: React.ReactElement | string;\n}\nexport default function AuthMethodButtonLogo(props: AuthMethodButtonLogoProps) {\n const logo =\n typeof props.logo === 'string' ? (\n <img src={props.logo} alt=\"\" />\n ) : (\n (props.logo ??\n (acrValueToLogo(props.acrValue) ? (\n <img src={acrValueToLogo(props.acrValue)} alt=\"\" />\n ) : (\n <span> </span>\n )))\n );\n\n if (logo) return <div className=\"criipto-eid-logo\">{logo}</div>;\n return null;\n}\n\nfunction acrValueToLogo(value: string) {\n if (value.startsWith('urn:grn:authn:dk:mitid:business')) {\n return dkmitiderhverv;\n }\n if (value.startsWith('urn:grn:authn:dk:mitid')) {\n return dkmitid;\n }\n if (value.startsWith('urn:grn:authn:fi:mobile')) {\n return ftnmobile;\n }\n if (value.startsWith('urn:grn:authn:fi')) {\n return ftn;\n }\n if (value.startsWith('urn:grn:authn:itsme')) {\n return itsme;\n }\n if (value.startsWith('urn:grn:authn:se:bankid')) {\n return sebankid;\n }\n if (value.startsWith('urn:grn:authn:no:bankid')) {\n return nobankid;\n }\n if (value.startsWith('urn:grn:authn:no:vipps')) {\n return novipps;\n }\n if (value.startsWith('urn:grn:authn:se:frejaid')) {\n return sefrejaid;\n }\n if (value.startsWith('urn:grn:authn:uk:oneid')) {\n return ukoneid;\n }\n if (value.startsWith('urn:grn:authn:de:personalausweis')) {\n return depersonalausweis;\n }\n if (value.startsWith('urn:grn:authn:nl:idin')) {\n return idin;\n }\n}\n","import React from 'react';\nimport classNames from 'classnames';\n\ninterface ButtonProps {\n className?: string;\n children: React.ReactNode;\n onClick?: React.MouseEventHandler;\n disabled?: boolean;\n}\nexport function AnchorButton(props: AnchorButtonProps) {\n return (\n <a\n className={classNames(`criipto-verify-button`, props.className)}\n href={props.href}\n aria-disabled={props.disabled}\n onClick={props.onClick}\n >\n {props.children}\n </a>\n );\n}\n\ninterface AnchorButtonProps extends ButtonProps {\n href: string;\n}\nexport function Button(props: ButtonProps) {\n return (\n <button\n className={classNames(`criipto-verify-button`, props.className)}\n type=\"button\"\n disabled={props.disabled}\n onClick={props.onClick}\n >\n {props.children}\n </button>\n );\n}\n","import React, { useContext, useEffect, useState } from 'react';\n\nimport './AuthMethodButton/AuthMethodButton.css';\nimport CriiptoVerifyContext, { type Action } from '../context';\nimport SEBankIDSameDeviceButton from './SEBankIDSameDeviceButton';\nimport { savePKCEState } from '@criipto/auth-js';\nimport AuthMethodButtonLogo, { type AuthMethodButtonLogoProps } from './AuthMethodButton/Logo';\nimport { AnchorButton, Button } from './Button';\nimport { acrValueToTitle, isAmbiguous, isSingle, stringifyAction } from '../utils';\nimport { AuthButtonGroupContext } from './AuthButtonGroup';\nimport { type Language } from '../i18n';\nimport { Spinner } from './Spinner/Spinner';\nimport classNames from 'classnames';\n\nexport type PopupParams = {\n acrValue: string;\n onHide: () => void;\n};\nexport type PopupOption = boolean | ((options: PopupParams) => boolean | React.ReactElement);\n\nexport interface AuthMethodButtonComponentProps {\n acrValue: string;\n href?: string;\n onClick?: React.MouseEventHandler;\n children?: React.ReactNode;\n 'data-testid'?: string;\n className?: string;\n /**\n * base64 image string, e.x. data:image/png;base64,\n * or a ReactElement\n */\n logo?: AuthMethodButtonLogoProps['logo'];\n /**\n * Impacts the button text rendered if no text is provided via props.children\n */\n language?: Language;\n /**\n * Impacts the button text rendered if no text is provided via props.children\n */\n action?: Action;\n disabled?: boolean;\n loading?: boolean;\n}\n\n/**\n * Display only components, does no state management and triggers no login flows on it's own\n */\nexport function AuthMethodButtonComponent(props: AuthMethodButtonComponentProps) {\n const { acrValue, href } = props;\n const group = useContext(AuthButtonGroupContext);\n const standalone = !group.multiple || isSingle(props.acrValue, group.acrValues);\n const language = (props.language ?? 'en') as Language;\n const action = (props.action ?? 'login') as Action;\n\n const disabled = (props.disabled || group.disabled) && !props.loading;\n const className = classNames(`criipto-eid-btn`, acrValueToClassName(acrValue), props.className, {\n 'criipto-eid-btn--disabled': disabled,\n 'criipto-eid-btn--loading': props.loading,\n });\n\n const { title, subtitle } = acrValueToTitle(language, acrValue, {\n disambiguate: isAmbiguous(acrValue, group.acrValues),\n });\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title} \n {standalone ? null : lowercaseFirst(subtitle)}\n </React.Fragment>\n );\n\n const inner = (\n <React.Fragment>\n <AuthMethodButtonLogo acrValue={acrValue} logo={props.loading ? <Spinner /> : props.logo} />\n <span>{contents}</span>\n </React.Fragment>\n );\n\n const commonProps = {\n ...props,\n className,\n disabled,\n };\n const button = href ? (\n <React.Fragment>\n <AnchorButton {...commonProps} href={href}>\n {inner}\n </AnchorButton>\n </React.Fragment>\n ) : (\n <React.Fragment>\n <Button {...commonProps}>{inner}</Button>\n </React.Fragment>\n );\n\n return button;\n}\n\nexport type AuthMethodButtonContainerProps = AuthMethodButtonComponentProps & {\n redirectUri?: string;\n popup?: PopupOption;\n\n /**\n * Will ammend the login_hint parameter with `message:{base64(message)}` which will set a login/aprove message where available (Danish MitID).\n */\n message?: string;\n\n userAgent?: string;\n};\n\nexport function AuthMethodButtonContainer(props: AuthMethodButtonContainerProps) {\n const { acrValue } = props;\n const group = useContext(AuthButtonGroupContext);\n const standalone = !group.multiple || isSingle(props.acrValue, group.acrValues);\n const context = useContext(CriiptoVerifyContext);\n const { initializePAR } = context;\n const language = (props.language ?? context.uiLocales ?? 'en') as Language;\n const action = (props.action ?? context.action ?? 'login') as Action;\n const className = `criipto-eid-btn ${acrValueToClassName(acrValue)}${\n props.className ? ` ${props.className}` : ''\n }`;\n const [backdrop, setBackdrop] = useState<React.ReactElement | null>(null);\n const [loading, setLoading] = useState<boolean>(props.loading ?? false);\n useEffect(() => {\n setLoading(props.loading ?? false);\n }, [props.loading]);\n\n const redirectUri = props.redirectUri || context.redirectUri;\n\n const handleClick: React.MouseEventHandler = (event) => {\n if (props.href) return;\n\n if (context.pkce && 'code_verifier' in context.pkce) {\n // just-in-time saving of PKCE, in case of man-in-the-browser\n savePKCEState(context.store, {\n response_type: 'id_token',\n pkce_code_verifier: context.pkce.code_verifier,\n redirect_uri: redirectUri!,\n });\n }\n\n if (props.popup) {\n let willPopup =\n typeof props.popup === 'function'\n ? props.popup({\n acrValue,\n onHide: () => setBackdrop(null),\n })\n : props.popup === true;\n\n if (willPopup !== false) {\n event.preventDefault();\n\n if (typeof willPopup === 'boolean') {\n context.loginWithPopup({\n acrValues: [acrValue],\n redirectUri: redirectUri,\n backdrop: true,\n });\n } else {\n setBackdrop(willPopup);\n context.loginWithPopup({\n acrValues: [acrValue],\n redirectUri: redirectUri,\n backdrop: false,\n });\n }\n }\n }\n\n if (props.onClick) props.onClick(event);\n\n if (!event.isDefaultPrevented()) {\n setLoading(true);\n group.setDisabled(true);\n initializePAR({\n redirectUri,\n acrValues: acrValue,\n loginHint: '',\n })\n .then((authorizeUrl) => {\n window.location.href = authorizeUrl.toString();\n })\n .catch((error) => {\n setLoading(false);\n group.setDisabled(false);\n context.handleResponse(error);\n });\n }\n };\n\n const { title, subtitle } = acrValueToTitle(language, acrValue, {\n disambiguate: isAmbiguous(acrValue, group.acrValues),\n });\n\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title} \n {standalone ? null : lowercaseFirst(subtitle)}\n </React.Fragment>\n );\n\n const button = (\n <React.Fragment>\n <AuthMethodButtonComponent\n {...props}\n className={className}\n onClick={handleClick}\n loading={loading}\n />\n {backdrop}\n </React.Fragment>\n );\n\n if (!props.href && acrValue === 'urn:grn:authn:se:bankid:same-device') {\n return (\n <SEBankIDSameDeviceButton\n redirectUri={props.redirectUri}\n fallback={button}\n className={className}\n userAgent={props.userAgent}\n logo={<AuthMethodButtonLogo acrValue={acrValue} logo={props.logo} />}\n disabled={props.disabled}\n >\n <span>{contents}</span>\n </SEBankIDSameDeviceButton>\n );\n }\n\n return button;\n}\n\nfunction acrValueToClassName(value: string) {\n value = value.replace('urn:grn:authn:', '');\n const segments = value.split(':');\n const classNames = segments.reduce((memo: string[], segment: string) => {\n if (memo.length) {\n return memo.concat([`${memo[memo.length - 1]}-${segment}`]);\n } else {\n return memo.concat([segment]);\n }\n }, []);\n\n return classNames.map((className) => `criipto-eid-btn--${className}`).join(' ');\n}\n\nfunction lowercaseFirst(input?: string) {\n if (!input) return input;\n return input.substring(0, 1).toLowerCase() + input.substr(1, input.length);\n}\n","import { useContext } from 'react';\nimport CriiptoVerifyContext from '../context';\nimport { getUserAgent } from '../device';\nimport { filterAcrValues } from '../utils';\nimport { type Language } from '../i18n';\nimport { AuthMethodButtonContainer, type AuthMethodButtonContainerProps } from './AuthMethodButton';\n\nimport './AuthMethodSelector/AuthMethodSelector.css';\nimport SEBankIDQrCode from './SEBankIDQRCode';\nimport AuthButtonGroup from './AuthButtonGroup';\n\ninterface AuthMethodSelectorProps {\n acrValues?: string[];\n language?: Language;\n onSelect?: (acrValue: string) => void;\n redirectUri?: string;\n popup?: AuthMethodButtonContainerProps['popup'];\n userAgent?: string;\n}\n\nexport default function AuthMethodSelector(props: AuthMethodSelectorProps) {\n const { action, uiLocales, acrValues: configurationAcrValues } = useContext(CriiptoVerifyContext);\n const language = props.language || (uiLocales as Language) || 'en';\n\n const acrValues = filterAcrValues(props.acrValues ?? configurationAcrValues ?? []);\n const onlySweden =\n !!acrValues.length && acrValues.every((s) => s.startsWith('urn:grn:authn:se:bankid:'));\n\n if (onlySweden) {\n return <Sweden {...props} acrValues={acrValues} />;\n }\n\n return (\n <div className=\"criipto-eid-selector\">\n <AuthButtonGroup>\n {acrValues.map((acrValue) => (\n <AuthMethodButtonContainer\n acrValue={acrValue}\n key={acrValue}\n onClick={props.onSelect ? () => props.onSelect!(acrValue) : undefined}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ))}\n </AuthButtonGroup>\n </div>\n );\n}\n\ntype SwedenProps = Omit<AuthMethodSelectorProps, 'acrValues'> & {\n acrValues: string[];\n};\n\nexport function Sweden(props: SwedenProps) {\n const { acrValues } = props;\n const { action, uiLocales } = useContext(CriiptoVerifyContext);\n const language = props.language || (uiLocales as Language) || 'en';\n const hasQR = acrValues.includes(SEBankIDQrCode.acr_values);\n const filteredAcrValues = acrValues.filter((s) => s !== SEBankIDQrCode.acr_values);\n\n const userAgent = getUserAgent(\n typeof navigator !== 'undefined' ? navigator.userAgent : props.userAgent,\n );\n const mobileOS =\n userAgent?.os.name === 'iOS' ? 'iOS' : userAgent?.os.name === 'Android' ? 'android' : null;\n const showQR = hasQR && !mobileOS;\n\n return (\n <div className=\"criipto-eid-selector\">\n <AuthButtonGroup>\n {filteredAcrValues.map((acrValue) => (\n <AuthMethodButtonContainer\n acrValue={acrValue}\n key={acrValue}\n onClick={props.onSelect ? () => props.onSelect!(acrValue) : undefined}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ))}\n {showQR ? (\n <SEBankIDQrCode\n language={language}\n redirectUri={props.redirectUri}\n fallback={\n <AuthMethodButtonContainer\n acrValue={SEBankIDQrCode.acr_values}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n }\n />\n ) : hasQR && mobileOS ? (\n <AuthMethodButtonContainer\n acrValue={SEBankIDQrCode.acr_values}\n redirectUri={props.redirectUri}\n popup={props.popup}\n language={language}\n action={action}\n userAgent={props.userAgent}\n />\n ) : null}\n </AuthButtonGroup>\n </div>\n );\n}\n","import {\n OAuth2Error,\n savePKCEState,\n UserCancelledError,\n type CriiptoConfiguration,\n} from '@criipto/auth-js';\n\nimport React, {\n useContext,\n useRef,\n useEffect,\n useLayoutEffect,\n useState,\n useCallback,\n} from 'react';\nimport CriiptoVerifyContext from '../context';\n\n// Inlined types less readable (for library developers) but improves intellisense for consumers\nconst QRCode: React.FC<{\n margin?: number;\n className?: string;\n acrValues?: string[];\n children: (props: {\n qrElement: React.ReactElement;\n /**\n * Will be true once the QR code has been scanned\n */\n isAcknowledged: boolean;\n /**\n * Will be true if the user cancels the login on his mobile device\n */\n isCancelled: boolean;\n /**\n * Whether or not QR codes are enabled for this Criipto Applicaiton\n */\n isEnabled: boolean | undefined;\n error: OAuth2Error | Error | null;\n retry: () => void;\n /**\n * A method for triggering a full screen redirect to authentication (useful if user is on mobile device already)\n */\n redirect: () => Promise<void>;\n }) => React.ReactElement;\n}> = (props) => {\n const { children, margin, className } = props;\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n client,\n buildOptions,\n buildAuthorizeUrl,\n handleResponse,\n pkce,\n store,\n acrValues: configurationAcrValues,\n } = useContext(CriiptoVerifyContext);\n const [requestId, setRequestId] = useState(() => Math.random().toString());\n const [isAcknowledged, setAcknowledged] = useState(false);\n const [isCancelled, setCancelled] = useState(false);\n const [error, setError] = useState<OAuth2Error | Error | null>(null);\n const [criiptoConfiguration, setCriiptoConfiguration] = useState<CriiptoConfiguration | null>(\n null,\n );\n const isEnabled = criiptoConfiguration?.client.qr_enabled;\n\n const acrValues = props.acrValues ?? configurationAcrValues ?? [];\n\n useEffect(() => {\n let isSubsribed = true;\n\n client.fetchCriiptoConfiguration().then((c) => {\n if (!isSubsribed) return;\n setCriiptoConfiguration(c);\n });\n\n return () => {\n isSubsribed = false;\n };\n }, [client]);\n\n const redirect = useCallback(async () => {\n if (!criiptoConfiguration) return;\n const intermediaryUrl = (\n criiptoConfiguration.client.qr_intermediary_url ?? criiptoConfiguration.qr_intermediary_url\n )\n .replace('/{id}', '')\n .replace('{id}', '');\n const authorizeUrl = new URL(\n await buildAuthorizeUrl({\n acrValues,\n }),\n );\n const authorizeParams = new URLSearchParams(authorizeUrl.search);\n authorizeParams.set('domain', authorizeUrl.host);\n authorizeUrl.host = new URL(intermediaryUrl).host;\n authorizeUrl.port = new URL(intermediaryUrl).port;\n authorizeUrl.pathname = new URL(intermediaryUrl).pathname + '/authorize';\n authorizeUrl.search = authorizeParams.toString();\n\n if (pkce && 'code_verifier' in pkce) {\n // just-in-time saving of PKCE, in case of man-in-the-browser\n savePKCEState(store, {\n response_type: 'id_token',\n pkce_code_verifier: pkce.code_verifier,\n redirect_uri: authorizeParams.get('redirect_uri')!,\n });\n }\n\n window.location.href = authorizeUrl.toString();\n }, [buildAuthorizeUrl, criiptoConfiguration, acrValues]);\n\n const authorize = useCallback(() => {\n return client.qr.authorize(elementRef.current!, {\n ...buildOptions({ acrValues }),\n margin,\n });\n }, [client, buildOptions, margin, acrValues]);\n\n useLayoutEffect(() => {\n if (!elementRef.current) return;\n if (error) return;\n if (!isEnabled) return;\n\n const promise = authorize();\n\n promise.onAcknowledged = () => {\n setAcknowledged(true);\n };\n\n promise\n .then((response) => {\n if (promise.cancelled) return;\n handleResponse(response, {\n pkce: pkce && 'code_verifier' in pkce ? pkce : undefined,\n source: 'QRCode',\n });\n })\n .catch((err) => {\n if (err instanceof UserCancelledError) {\n setCancelled(true);\n return;\n }\n\n if (promise.cancelled) return;\n\n setError(err);\n handleResponse(err, { source: 'QRCode' });\n });\n\n return () => {\n promise.cancel();\n };\n }, [authorize, pkce, handleResponse, requestId, error, isEnabled]);\n\n const handleRetry = () => {\n setAcknowledged(false);\n setCancelled(false);\n setError(null);\n setRequestId(Math.random().toString());\n };\n\n const qrElement = <div ref={elementRef} className={className} />;\n return children({\n qrElement,\n isAcknowledged,\n isCancelled,\n isEnabled: criiptoConfiguration?.client.qr_enabled,\n error,\n retry: handleRetry,\n redirect,\n });\n};\nexport default QRCode;\n","import { useContext } from 'react';\nimport CriiptoVerifyContext from './context';\n\nexport default function useCriiptoVerify() {\n const {\n result,\n claims,\n loginWithRedirect,\n loginWithPopup,\n acrValues,\n isLoading,\n isInitializing,\n logout,\n checkSession,\n } = useContext(CriiptoVerifyContext);\n\n return {\n result,\n /**\n * The claims of the decoded id_token (if available)\n */\n claims,\n /**\n * Set when the provider failed to fetch configuration (e.g. invalid `domain`/`clientID`,\n * or CORS), or when an authentication attempt failed (e.g. user cancellation, OAuth2 errors\n * from the IdP). Always render this in your UI — failures are otherwise silent.\n *\n * `OAuth2Error` for IdP-returned errors, `Error` for everything else.\n */\n error: result && ('error' in result || result instanceof Error) ? result : null,\n loginWithRedirect,\n loginWithPopup,\n acrValues,\n /**\n * Will be true when performing token exchange after redirect or during an initial SSO check\n */\n isLoading,\n /**\n * Will be true until the first set of useEffect hooks have been called\n */\n isInitializing,\n /**\n * Check if there is an existing SSO session.\n */\n checkSession,\n /**\n * Clear local session store and logout of any existing SSO session\n */\n logout,\n };\n}\n"],"mappings":"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"}
|