@criipto/verify-react 6.0.0 → 6.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/README.md CHANGED
@@ -111,6 +111,37 @@ To control eID methods from your code instead of the dashboard, pass `acrValues`
111
111
 
112
112
  See the [Authorize URL Builder](https://docs.idura.app/verify/guides/authorize-url-builder) or individual eID pages for the full list of supported `acr_values`.
113
113
 
114
+ ### Configure the request per eID
115
+
116
+ `login_hint` and `scope` values are eID specific, so a single provider-level setting rarely fits every button. Pass a `beforeAuthorize` function to `CriiptoVerifyProvider` to adjust the request for the eID the user actually picked:
117
+
118
+ ```jsx
119
+ <CriiptoVerifyProvider
120
+ domain="{YOUR_IDURA_DOMAIN}"
121
+ clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
122
+ beforeAuthorize={({ acrValues }) => {
123
+ if (acrValues[0].startsWith('urn:grn:authn:dk:mitid')) {
124
+ return { scope: 'openid address' };
125
+ }
126
+ if (acrValues[0].startsWith('urn:grn:authn:se:bankid')) {
127
+ return { loginHint: 'stepUp:mrtd' };
128
+ }
129
+ }}
130
+ >
131
+ <App />
132
+ </CriiptoVerifyProvider>
133
+ ```
134
+
135
+ `beforeAuthorize` runs just before every authorize request is built, whichever way the login was started: `AuthMethodSelector`, `AuthMethodButton`, `SEBankIDQRCode`, `loginWithRedirect` or `loginWithPopup`. Return the values you want to change for that one request, or nothing at all to leave it as configured on the provider.
136
+
137
+ - `acrValues` is always an array, and holds a single value for logins started from a button or `AuthMethodSelector`
138
+ - `options` holds the request as the SDK would otherwise send it, in case you want to inspect it
139
+ - you can override `loginHint`, `scope`, `prompt`, `uiLocales`, `state`, `nonce`, `extraUrlParams` and the `action`/`message` shorthands
140
+ - `loginHint` is appended to the hints the SDK already adds, so use `action` and `message` rather than writing `action:`/`message:` hints yourself
141
+ - `acrValues`, `redirectUri` and the PKCE and response parameters are managed by the SDK and cannot be overridden here. Use `redirectUri` on the button or selector to change where a single eID returns the user
142
+
143
+ The hint and scope values differ per eID, see the individual eID pages in the [Idura docs](https://docs.idura.app/verify/e-ids/) for what each one supports.
144
+
114
145
  ## Send the user directly to an eID login screen
115
146
 
116
147
  If you don't need the method selector, use `loginWithRedirect` (or `loginWithPopup`) and pass a single eID method identifier in `acrValues`.
package/dist/index.css CHANGED
@@ -74,6 +74,10 @@
74
74
  background-color: hsl(15.07 100% calc(57.06% + var(--bg-lightness-mod)) / var(--bg-alpha-mod));
75
75
  }
76
76
 
77
+ .criipto-eid-btn.criipto-eid-btn--no-vipps.criipto-eid-btn--market-FI, .criipto-eid-btn.criipto-eid-btn--no-vipps.criipto-eid-btn--market-DK {
78
+ background-color: hsl(229 100% calc(68% + var(--bg-lightness-mod)) / var(--bg-alpha-mod));
79
+ }
80
+
77
81
  .criipto-eid-btn.criipto-eid-btn--itsme {
78
82
  background-color: hsl(9.72 98.18% calc(56.86% + var(--bg-lightness-mod)) / var(--bg-alpha-mod));
79
83
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import * as _criipto_auth_js0 from "@criipto/auth-js";
3
- import CriiptoAuth, { OAuth2Error, OAuth2Error as OAuth2Error$1, PKCEPublicPart, Prompt, ResponseType } from "@criipto/auth-js";
3
+ import CriiptoAuth, { AuthorizeUrlParamsOptional, OAuth2Error, OAuth2Error as OAuth2Error$1, PKCEPublicPart, Prompt, ResponseType } from "@criipto/auth-js";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
6
6
  //#region src/context.d.ts
@@ -26,6 +26,39 @@ type Claims = {
26
26
  exp: number;
27
27
  [key: string]: string | number;
28
28
  };
29
+ interface BeforeAuthorizeParams {
30
+ /**
31
+ * The acr_values of the authorize request that is about to be made, always normalized to an array.
32
+ * For logins started from a button or `AuthMethodSelector` this will hold exactly one value.
33
+ */
34
+ acrValues: string[];
35
+ /**
36
+ * The parameters the SDK is about to use, with `CriiptoVerifyProvider` configuration already applied.
37
+ */
38
+ options: AuthorizeUrlParamsOptional;
39
+ }
40
+ /**
41
+ * Parameters to override for a single authorize request. Any field left out (or set to `undefined`)
42
+ * keeps the value configured on `CriiptoVerifyProvider`.
43
+ */
44
+ interface BeforeAuthorizeOverrides {
45
+ /**
46
+ * Appended to the login_hint of this request, just like a `loginHint` passed directly to
47
+ * `loginWithRedirect`. Use `action` and `message` rather than `action:`/`message:` hints,
48
+ * as those are managed by the SDK.
49
+ */
50
+ loginHint?: string;
51
+ action?: Action;
52
+ message?: string;
53
+ scope?: string;
54
+ prompt?: Prompt;
55
+ uiLocales?: string;
56
+ state?: string;
57
+ nonce?: string;
58
+ extraUrlParams?: {
59
+ [key: string]: string | null;
60
+ };
61
+ }
29
62
  //#endregion
30
63
  //#region src/provider.d.ts
31
64
  interface CriiptoVerifyProviderOptions {
@@ -67,6 +100,14 @@ interface CriiptoVerifyProviderOptions {
67
100
  */
68
101
  response?: 'token' | 'code';
69
102
  completionStrategy?: 'client' | 'openidprovider';
103
+ /**
104
+ * Called just before each authorize request is built, for every login flow
105
+ * (`AuthMethodSelector`, `AuthMethodButton`, `SEBankIDQRCode`, `loginWithRedirect` and `loginWithPopup`).
106
+ * Return the parameters you wish to change for that particular request, for instance a
107
+ * `loginHint` that depends on the acr_value the user picked. Returning nothing leaves the
108
+ * request as configured on the provider.
109
+ */
110
+ beforeAuthorize?: (params: BeforeAuthorizeParams) => BeforeAuthorizeOverrides | void;
70
111
  /**
71
112
  * @deprecated Criipto internal use
72
113
  */
@@ -88,6 +129,7 @@ type Language = 'en' | 'da' | 'sv' | 'nb' | 'fi' | 'de' | 'nl';
88
129
  //#region src/components/AuthMethodButton/Logo.d.ts
89
130
  interface AuthMethodButtonLogoProps {
90
131
  acrValue: string;
132
+ loginHint?: string;
91
133
  /**
92
134
  * base64 image string, e.x. data:image/png;base64,
93
135
  * or a ReactElement
@@ -123,6 +165,7 @@ interface AuthMethodButtonComponentProps {
123
165
  action?: Action;
124
166
  disabled?: boolean;
125
167
  loading?: boolean;
168
+ loginHint?: string;
126
169
  }
127
170
  /**
128
171
  * Display only components, does no state management and triggers no login flows on it's own
@@ -235,5 +278,5 @@ declare function useCriiptoVerify(): {
235
278
  //#region src/utils.d.ts
236
279
  declare function filterAcrValues(input: string[]): string[];
237
280
  //#endregion
238
- export { type Action, AuthMethodButtonContainer as AuthButton, AuthMethodButtonContainer as AuthMethodButton, AuthMethodButtonComponent as AuthButtonComponent, AuthButtonGroup, AuthMethodSelector, Sweden as AuthMethodSelectorSweden, CriiptoVerifyProvider, type Language, OAuth2Error, type Result, SEBankIDQrCode as SEBankIDQRCode, actions, filterAcrValues, useCriiptoVerify };
281
+ export { type Action, AuthMethodButtonContainer as AuthButton, AuthMethodButtonContainer as AuthMethodButton, AuthMethodButtonComponent as AuthButtonComponent, AuthButtonGroup, AuthMethodSelector, Sweden as AuthMethodSelectorSweden, type BeforeAuthorizeOverrides, type BeforeAuthorizeParams, CriiptoVerifyProvider, type Language, OAuth2Error, type Result, SEBankIDQrCode as SEBankIDQRCode, actions, filterAcrValues, useCriiptoVerify };
239
282
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ const CriiptoVerifyContext = createContext({
45
45
  });
46
46
  //#endregion
47
47
  //#region package.json
48
- var version = "6.0.0";
48
+ var version = "6.0.2";
49
49
  //#endregion
50
50
  //#region src/i18n/en.ts
51
51
  const en = {
@@ -251,7 +251,7 @@ function acrValueToProviderPrefix(value) {
251
251
  else if (value.startsWith("itsme")) return "itsme";
252
252
  else return value.split(":").slice(0, 2).join(":");
253
253
  }
254
- function acrValueToTitle(language, value, { disambiguate }) {
254
+ function acrValueToTitle(language, value, { disambiguate, loginHint }) {
255
255
  const i18n = getI18n(language);
256
256
  value = value.replace("urn:grn:authn:", "");
257
257
  const provider = acrValueToProviderPrefix(value);
@@ -286,7 +286,11 @@ function acrValueToTitle(language, value, { disambiguate }) {
286
286
  subtitle
287
287
  };
288
288
  }
289
- if (provider === "no:vipps") return { title: autoTitleCase(value).replace("NO ", "") };
289
+ if (provider === "no:vipps") {
290
+ const marketHint = loginHint === null || loginHint === void 0 ? void 0 : loginHint.split(" ").find((s) => s.startsWith("market:"));
291
+ if (marketHint === "market:DK" || marketHint === "market:FI") return { title: "MobilePay" };
292
+ return { title: autoTitleCase(value).replace("NO ", "") };
293
+ }
290
294
  if (provider === "se:frejaid") return { title: "FrejaID" };
291
295
  if (provider === "uk:oneid") return { title: "OneID" };
292
296
  if (provider === "de:personalausweis") return { title: "Personalausweis" };
@@ -464,10 +468,14 @@ const MESSAGE_SUPPORTING_ACR_VALUES = [
464
468
  "urn:grn:authn:se:bankid:same-device",
465
469
  "urn:grn:authn:se:bankid:another-device:qr"
466
470
  ];
471
+ function normalizeAcrValues(acrValues) {
472
+ if (!acrValues) return [];
473
+ return Array.isArray(acrValues) ? acrValues : [acrValues];
474
+ }
467
475
  function buildLoginHint(loginHint, params) {
468
- const { options, action, message } = params;
469
- const acrValues = (options === null || options === void 0 ? void 0 : options.acrValues) ? Array.isArray(options === null || options === void 0 ? void 0 : options.acrValues) ? options === null || options === void 0 ? void 0 : options.acrValues : [options === null || options === void 0 ? void 0 : options.acrValues] : [];
470
- let hints = (loginHint ? loginHint.split(" ") : []).concat((options === null || options === void 0 ? void 0 : options.loginHint) ? options === null || options === void 0 ? void 0 : options.loginHint.split(" ") : []).filter((hint) => !hint.startsWith("message:") && !hint.startsWith("action:"));
476
+ const { options, action, message, extraLoginHint } = params;
477
+ const acrValues = normalizeAcrValues(options === null || options === void 0 ? void 0 : options.acrValues);
478
+ let hints = (loginHint ? loginHint.split(" ") : []).concat((options === null || options === void 0 ? void 0 : options.loginHint) ? options === null || options === void 0 ? void 0 : options.loginHint.split(" ") : []).concat(extraLoginHint ? extraLoginHint.split(" ") : []).filter((hint) => !hint.startsWith("message:") && !hint.startsWith("action:"));
471
479
  if (action) {
472
480
  hints = hints.filter((h) => !h.startsWith("action:"));
473
481
  if (acrValues.length === 1) {
@@ -574,6 +582,10 @@ const CriiptoVerifyProvider = (props) => {
574
582
  const action = (_ref = (_props$action = props.action) !== null && _props$action !== void 0 ? _props$action : parseAction(loginHint)) !== null && _ref !== void 0 ? _ref : "login";
575
583
  const message = (_props$message = props.message) !== null && _props$message !== void 0 ? _props$message : parseMessage(loginHint);
576
584
  const sessionStore = props.sessionStore;
585
+ const beforeAuthorizeRef = useRef(props.beforeAuthorize);
586
+ useEffect(() => {
587
+ beforeAuthorizeRef.current = props.beforeAuthorize;
588
+ }, [props.beforeAuthorize]);
577
589
  const refreshPKCE = function() {
578
590
  var _ref2 = _asyncToGenerator(function* () {
579
591
  if (props.pkce) return props.pkce;
@@ -592,8 +604,8 @@ const CriiptoVerifyProvider = (props) => {
592
604
  };
593
605
  }();
594
606
  const buildOptions = useCallback((options) => {
595
- var _props$responseType, _props$state, _props$nonce, _props$prompt, _props$scope, _options$pkce;
596
- return _objectSpread2(_objectSpread2({
607
+ var _props$responseType, _props$state, _props$nonce, _props$prompt, _props$scope, _options$pkce, _beforeAuthorizeRef$c, _overrides$state, _overrides$nonce, _overrides$prompt, _overrides$scope, _overrides$uiLocales, _overrides$action, _overrides$message;
608
+ const resolved = _objectSpread2(_objectSpread2({
597
609
  redirectUri: defaultRedirectUri(props.redirectUri),
598
610
  responseType: (_props$responseType = props.responseType) !== null && _props$responseType !== void 0 ? _props$responseType : "code",
599
611
  responseMode: props.responseMode
@@ -611,6 +623,25 @@ const CriiptoVerifyProvider = (props) => {
611
623
  }),
612
624
  extraUrlParams: props.criiptoSdk !== void 0 ? { criipto_sdk: props.criiptoSdk } : { criipto_sdk: `@criipto/verify-react@${version}` }
613
625
  });
626
+ const overrides = (_beforeAuthorizeRef$c = beforeAuthorizeRef.current) === null || _beforeAuthorizeRef$c === void 0 ? void 0 : _beforeAuthorizeRef$c.call(beforeAuthorizeRef, {
627
+ acrValues: normalizeAcrValues(resolved.acrValues),
628
+ options: resolved
629
+ });
630
+ if (!overrides) return resolved;
631
+ return _objectSpread2(_objectSpread2({}, resolved), {}, {
632
+ state: (_overrides$state = overrides.state) !== null && _overrides$state !== void 0 ? _overrides$state : resolved.state,
633
+ nonce: (_overrides$nonce = overrides.nonce) !== null && _overrides$nonce !== void 0 ? _overrides$nonce : resolved.nonce,
634
+ prompt: (_overrides$prompt = overrides.prompt) !== null && _overrides$prompt !== void 0 ? _overrides$prompt : resolved.prompt,
635
+ scope: (_overrides$scope = overrides.scope) !== null && _overrides$scope !== void 0 ? _overrides$scope : resolved.scope,
636
+ uiLocales: (_overrides$uiLocales = overrides.uiLocales) !== null && _overrides$uiLocales !== void 0 ? _overrides$uiLocales : resolved.uiLocales,
637
+ loginHint: buildLoginHint(props.loginHint, {
638
+ options,
639
+ action: (_overrides$action = overrides.action) !== null && _overrides$action !== void 0 ? _overrides$action : action,
640
+ message: (_overrides$message = overrides.message) !== null && _overrides$message !== void 0 ? _overrides$message : message,
641
+ extraLoginHint: overrides.loginHint
642
+ }),
643
+ extraUrlParams: _objectSpread2(_objectSpread2({}, resolved.extraUrlParams), overrides.extraUrlParams)
644
+ });
614
645
  }, [
615
646
  pkce,
616
647
  props.state,
@@ -1553,6 +1584,9 @@ var nobankid_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALAAAABICA
1553
1584
  //#region src/components/AuthMethodButton/logos/novipps.png
1554
1585
  var novipps_default = "data:image/png;base64,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";
1555
1586
  //#endregion
1587
+ //#region src/components/AuthMethodButton/logos/mobilepay.png
1588
+ var mobilepay_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFgAAAAkCAYAAAANdf2OAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAOdEVYdFNvZnR3YXJlAEZpZ21hnrGWYwAAAlhJREFUeAHtmu1R20AQhteZ/I86iDoIHVgdQAdxB04HIRXgVGBSQaACQQWmA7kDoIJll3uNj0PfYjg0t8/Mju37+OFXe7u3dyL6xDBzIbYVK8V+kjEdETITW0NU5d77/ouMccBbLyAoQ1QVOkP/Fn0ZGf0Rwc4Cb1WRlzXjCoz5TUY7CAPnnrdWKlyXd+JB7MhoRgTKIeghDCwHzF1hXkFGPQgBSk4Dgec/hxH8zhGn/+Oh+SsizVh9SFY0Epl7EuwymkgzVssfPx2zzGvidhcVpQpEKgeML/gYt4dQUGS+Uhw2YuqN2WKxeGgbyK64uPCadPyV2J3YrdeeBWO+iT1SimC5d8ZJhISXJc8u9vqJrStc7NjF/IJSg12SaqzM2CUzn6V6M/ePwSEVp7Sz4GNldtoypgwELnka3+mD+UKRkNh7Ix97sbYDnCuaOdEEBpdi6slFQ/8/cglrtsQW+C85AWvDBHYYG5oxUQWGgJdiq5YEdE0zJrYHKyqgilt7YyEPQfe7NzRToguMZKd21jLsD82UWJVciO4WNprsIPgrtE36fgTNGl507B7f915fLnbifaYNH48hy45xWr013Xic181nV/mtUGh8+D7408DuRoN5ZLXlFS4FGW+Bpymjz3F54CldcqAUnnIYf1gFORlvmbrMuecpXdJMXeaYvyWjHm+ZD9pesTve3GKuvWbVhLdl67XMEVZKCNt7XtLw8bai6TA+vAC95x4vrhjAS3brmvaDtzIPfHHF8IB4FUTVO7idees7gqRVBd66NmHfGXZ3cXZgYxhReAKtoA9h3jxwjgAAAABJRU5ErkJggg==";
1589
+ //#endregion
1556
1590
  //#region src/components/AuthMethodButton/logos/sebankid.png
1557
1591
  var sebankid_default = "data:image/png;base64,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";
1558
1592
  //#endregion
@@ -1577,8 +1611,8 @@ function AuthMethodButtonLogo(props) {
1577
1611
  const logo = typeof props.logo === "string" ? /* @__PURE__ */ jsx("img", {
1578
1612
  src: props.logo,
1579
1613
  alt: ""
1580
- }) : (_props$logo = props.logo) !== null && _props$logo !== void 0 ? _props$logo : acrValueToLogo(props.acrValue) ? /* @__PURE__ */ jsx("img", {
1581
- src: acrValueToLogo(props.acrValue),
1614
+ }) : (_props$logo = props.logo) !== null && _props$logo !== void 0 ? _props$logo : acrValueToLogo(props.acrValue, props.loginHint) ? /* @__PURE__ */ jsx("img", {
1615
+ src: acrValueToLogo(props.acrValue, props.loginHint),
1582
1616
  alt: ""
1583
1617
  }) : /* @__PURE__ */ jsx("span", { children: "\xA0" });
1584
1618
  if (logo) return /* @__PURE__ */ jsx("div", {
@@ -1587,7 +1621,7 @@ function AuthMethodButtonLogo(props) {
1587
1621
  });
1588
1622
  return null;
1589
1623
  }
1590
- function acrValueToLogo(value) {
1624
+ function acrValueToLogo(value, loginHint) {
1591
1625
  if (value.startsWith("urn:grn:authn:dk:mitid:business")) return dkmitiderhverv_default;
1592
1626
  if (value.startsWith("urn:grn:authn:dk:mitid")) return dkmitid_default;
1593
1627
  if (value.startsWith("urn:grn:authn:fi:mobile")) return ftnmobile_default;
@@ -1595,7 +1629,11 @@ function acrValueToLogo(value) {
1595
1629
  if (value.startsWith("urn:grn:authn:itsme")) return itsme_default;
1596
1630
  if (value.startsWith("urn:grn:authn:se:bankid")) return sebankid_default;
1597
1631
  if (value.startsWith("urn:grn:authn:no:bankid")) return nobankid_default;
1598
- if (value.startsWith("urn:grn:authn:no:vipps")) return novipps_default;
1632
+ if (value.startsWith("urn:grn:authn:no:vipps")) {
1633
+ const marketHint = loginHint === null || loginHint === void 0 ? void 0 : loginHint.split(" ").find((s) => s.startsWith("market:"));
1634
+ if (marketHint === "market:DK" || marketHint === "market:FI") return mobilepay_default;
1635
+ return novipps_default;
1636
+ }
1599
1637
  if (value.startsWith("urn:grn:authn:se:frejaid")) return sefrejaid_default;
1600
1638
  if (value.startsWith("urn:grn:authn:uk:oneid")) return ukoneid_default;
1601
1639
  if (value.startsWith("urn:grn:authn:de:personalausweis")) return depersonalausweis_default;
@@ -1638,7 +1676,10 @@ function AuthMethodButtonComponent(props) {
1638
1676
  "criipto-eid-btn--disabled": disabled,
1639
1677
  "criipto-eid-btn--loading": props.loading
1640
1678
  });
1641
- const { title, subtitle } = acrValueToTitle(language, acrValue, { disambiguate: isAmbiguous(acrValue, group.acrValues) });
1679
+ const { title, subtitle } = acrValueToTitle(language, acrValue, {
1680
+ disambiguate: isAmbiguous(acrValue, group.acrValues),
1681
+ loginHint: props.loginHint
1682
+ });
1642
1683
  const contents = (_props$children = props.children) !== null && _props$children !== void 0 ? _props$children : /* @__PURE__ */ jsxs(React.Fragment, { children: [
1643
1684
  stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : "",
1644
1685
  title,
@@ -1647,6 +1688,7 @@ function AuthMethodButtonComponent(props) {
1647
1688
  ] });
1648
1689
  const inner = /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsx(AuthMethodButtonLogo, {
1649
1690
  acrValue,
1691
+ loginHint: props.loginHint,
1650
1692
  logo: props.loading ? /* @__PURE__ */ jsx(Spinner, {}) : props.logo
1651
1693
  }), /* @__PURE__ */ jsx("span", { children: contents })] });
1652
1694
  const commonProps = _objectSpread2(_objectSpread2({}, props), {}, {
@@ -1659,7 +1701,7 @@ function AuthMethodButtonComponent(props) {
1659
1701
  })) }) : /* @__PURE__ */ jsx(React.Fragment, { children: /* @__PURE__ */ jsx(Button, _objectSpread2(_objectSpread2({}, commonProps), {}, { children: inner })) });
1660
1702
  }
1661
1703
  function AuthMethodButtonContainer(props) {
1662
- var _ref, _props$language2, _ref2, _props$action2, _props$loading, _props$children2;
1704
+ var _ref, _props$language2, _ref2, _props$action2, _context$loginHint, _props$loading, _props$children2;
1663
1705
  const { acrValue } = props;
1664
1706
  const group = useContext(AuthButtonGroupContext);
1665
1707
  const standalone = !group.multiple || isSingle(props.acrValue, group.acrValues);
@@ -1667,7 +1709,7 @@ function AuthMethodButtonContainer(props) {
1667
1709
  const { initializePAR } = context;
1668
1710
  const language = (_ref = (_props$language2 = props.language) !== null && _props$language2 !== void 0 ? _props$language2 : context.uiLocales) !== null && _ref !== void 0 ? _ref : "en";
1669
1711
  const action = (_ref2 = (_props$action2 = props.action) !== null && _props$action2 !== void 0 ? _props$action2 : context.action) !== null && _ref2 !== void 0 ? _ref2 : "login";
1670
- const className = `criipto-eid-btn ${acrValueToClassName(acrValue)}${props.className ? ` ${props.className}` : ""}`;
1712
+ const className = `criipto-eid-btn ${acrValueToClassName(acrValue)} ${loginHintToClassName((_context$loginHint = context.loginHint) !== null && _context$loginHint !== void 0 ? _context$loginHint : "")} ${props.className ? ` ${props.className}` : ""}`;
1671
1713
  const [backdrop, setBackdrop] = useState(null);
1672
1714
  const [loading, setLoading] = useState((_props$loading = props.loading) !== null && _props$loading !== void 0 ? _props$loading : false);
1673
1715
  useEffect(() => {
@@ -1721,7 +1763,10 @@ function AuthMethodButtonContainer(props) {
1721
1763
  });
1722
1764
  }
1723
1765
  };
1724
- const { title, subtitle } = acrValueToTitle(language, acrValue, { disambiguate: isAmbiguous(acrValue, group.acrValues) });
1766
+ const { title, subtitle } = acrValueToTitle(language, acrValue, {
1767
+ disambiguate: isAmbiguous(acrValue, group.acrValues),
1768
+ loginHint: context.loginHint
1769
+ });
1725
1770
  const contents = (_props$children2 = props.children) !== null && _props$children2 !== void 0 ? _props$children2 : /* @__PURE__ */ jsxs(React.Fragment, { children: [
1726
1771
  stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : "",
1727
1772
  title,
@@ -1731,7 +1776,8 @@ function AuthMethodButtonContainer(props) {
1731
1776
  const button = /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsx(AuthMethodButtonComponent, _objectSpread2(_objectSpread2({}, props), {}, {
1732
1777
  className,
1733
1778
  onClick: handleClick,
1734
- loading
1779
+ loading,
1780
+ loginHint: context.loginHint
1735
1781
  })), backdrop] });
1736
1782
  if (!props.href && acrValue === "urn:grn:authn:se:bankid:same-device") return /* @__PURE__ */ jsx(SEBankIDSameDeviceButton, {
1737
1783
  redirectUri: props.redirectUri,
@@ -1740,6 +1786,7 @@ function AuthMethodButtonContainer(props) {
1740
1786
  userAgent: props.userAgent,
1741
1787
  logo: /* @__PURE__ */ jsx(AuthMethodButtonLogo, {
1742
1788
  acrValue,
1789
+ loginHint: props.loginHint,
1743
1790
  logo: props.logo
1744
1791
  }),
1745
1792
  disabled: props.disabled,
@@ -1754,6 +1801,10 @@ function acrValueToClassName(value) {
1754
1801
  else return memo.concat([segment]);
1755
1802
  }, []).map((className) => `criipto-eid-btn--${className}`).join(" ");
1756
1803
  }
1804
+ function loginHintToClassName(value) {
1805
+ const marketHint = value.split(" ").find((s) => s.startsWith("market:"));
1806
+ return [marketHint ? `criipto-eid-btn--${marketHint === null || marketHint === void 0 ? void 0 : marketHint.replace(":", "-")}` : void 0].filter((id) => id !== void 0);
1807
+ }
1757
1808
  function lowercaseFirst(input) {
1758
1809
  if (!input) return input;
1759
1810
  return input.substring(0, 1).toLowerCase() + input.substr(1, input.length);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["OAuth2Error","usePoll","searchParamsToPOJO","logo","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/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 = 'SEBankIDQrCode' | 'SEBankIDSameDeviceButton' | 'redirect' | '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,iVBORw0KGgoAAAANSUhEUgAAALAAAABICAYAAABWdn8qAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAsKADAAQAAAABAAAASAAAAACoGQzqAAAG20lEQVR4Ae1bi3HbOBC1b64AlQBXcLoKTFdgdxCmAisVmKogTgVSKohTgekKrKtA7CDuIPdehpiBGIIk+EXktzM7ABb7w8MKBCX74kIkBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBITAO0Lg8h2t9WSpP3/+XEFwD96A2c/B28vLS7bREPJMkMwt+A5swKRDycy3oCCUSr9Jg12BOfIbYjBelDR5AZeFsq5b/ZjFgjiMsaqJc0Cct6oc+q+Q1eV1M2Ze1bhdxyVuD9DftNg8It9PLTq/TcN/BiH9d6UDFHPw9xjw6Zr0YD0AlYB91LY5neLDeeoLAHlSddKi/1zVn3uM/FbgV3BX4ocxiOA46+q8Ru8I2T3YBAX9E5WxyKYC/jEUBNqDj2AfJVXcoPjoU6a8qj/3GCnsmEcgfQ7JE76HFLBN7YhOGhJ3bN2/xnYY6G8F/V2gTVWdj0FTFQ4Yv/lssVksfG5alUc7teF7jfipL4cG+Qa2ScP8FFMGTneI+w3MvZydli5gLpgn9F2flcMuhR05lJ4aDJrmuEnGww0ug6bug7RPlXvheOqi14hxeeUxvawHGMVQwEz/c+gnuNTn6RtM5UvItsawgKxOXqM6mSgZ4Pl2gO1QUwMHs5/EsRQwFx9ajIOuDijiDDGvwF/AezDf5P+FvEC7JJkBwfmEWJLWCB66j0vm2x4bJ2XTSxymTyhp93hxAQtzYtU86OSzY9y9J9Sxi30XHY//zuIuMagDh1lnp+GKSdc8hurFcgLbdeyAVZdT5NkanGFbDFjTYYDtmKazncJ/j5n1CL4MfGzAGbiWUOAEx9ROBgjhZ+dR/1rekXlK8cPkfj117bHh97ZVf/wFK/gHBvh/ARtPnDZxLAWcAA8TwXWsDa/2eSyEiwmldZ1nODGhjqCfeHz5XKVWv2c86/do/YS0zNc66NGarrHgO+vhP8Qk65rLEL3YrhB2Le6pZ2Vsq6ecO3cW/fL0/9pjMV8iO/F8T6seS/ObLF3AT57UeApt3DmMU4wTV+b0c6d/Dl2u/RCwEP69xwleAbZTqa6ncuz6XbqA+RVW7ibk9B9QtIbjsn1w5tzuHoM+J5brI6o+ivENCd10XBcxpG5sxPcCM3VSMbzEfcQiX8GrymI55pWBm8PiNeAqFRBswQl4CmIh0b8l/lCwtgOnpR4LySXKelNZxCmKIIMT8j9gG7tA/zv4CXo52ljJILFiyuQWL2BsQIFNYpHU3Xt5lXjGXOIBYVvae6aHieGbRZhZL+WJYovIitnyG4fMFYzV5/rgKx3L37n5WfoK8QtPbNIjOrkH3MQj38Nu75mT+J0gEEUBl1h/RMsTrwsVUHIf7V1spHOGCCx+hbCY8lHZcJWwarbdUt8OzrEFFiusKwFfgw3Yvbrwg04+gF/AOfDgODYqpk4omgLmQrEJ/HtbviglHHvorK8O5T37HmtPwSsPBlacoLPhAHZ7NFF9sOc4ZGK6QnAfSE1XiQLzZ3t1QBGycF/BLMq24oXKCaUYHeGD39jEQPkcSURXwOWn1lekS58wxRSbgqKzf0vxCP+hhVtNKYO/XVW4wPi/OWJGV8BcNIqYG5mz79A5Xx1YcKmz1qHdNIIi5h5OTlEWcLlq9ypRQOY7lScHacoA5SP/boIYLOLNBH67uMznuP8ykWgLuHKVWPrq0LZpb20KdfMoMAN5Vjc3koz/qmVG8hXiZrbDJqpvIaoI8SqBDeCvXPvqXGTjVc985njh4vXkpmd+fcx41cv7GPaxifYEtov5A4qXqZrq4xpjvph5CxtzBnYpeGpKmvIYOXgBf59G9tnoLvoCbsx+/smiISQf18/gHZhfhf0Arxv07xrmxp7ajO2wxl8B2Q0OnLeauclEUV8hJlt1f8d5i2nSMu9O37qDifvXE/vP4f8jireYOM5v7nUC/waJX1BuUO7XCJpJgrSHKU91jeBpuwUuNyU2w7LsYa0CDgfN/Xov3BoWuGIkvQyHGZlh5ifWvwoXkisUbnYyM/NAV4hAwHnSoAD5Vv8NbALNrfrKdmZs14h1GBCPRfsEfmELHDhenOYo4AKr3HpWyrkxiBsTGsOnT1+NhM2jzhUKOUX7AWxKRvPrr8QKtC9gtnXEzffFr9MfQ1ZdV97BaQEd5nrgBxetSAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASGwJAL/A+Yt1oQ//F+YAAAAAElFTkSuQmCC\"","\"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,iVBORw0KGgoAAAANSUhEUgAAALAAAABICAYAAABWdn8qAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAsKADAAQAAAABAAAASAAAAACoGQzqAAAIFklEQVR4Ae2djXXaSBSF7T1bAB3spIIlFUSuYJ0KrFQQUgG4AjsVQCqIU4HkCkIqQK7AdJD9LplxZDGAiAFrRvPOuZ6f9zR6P5fxCPDx2VmSlIGUgZSBlIGUgZSBlIGUgZSBfmXgPMZwf/78OSCujyAHBnRJKuuM2iVQ+wDm6p+fn2ucpGUGoiMw5DXEXgC1IoiI0SUxODOw8PnlfP6GsoTQXfPf53OaO1QGIPACSG6BiNJZwT8DMnAJ5G8BHkFdFgymwHQ2kOTYYTJAkUUGyfQwK77OKvg/BCNQgLoUDPLX8Srd9egZoLgTW+3s6Dc70Q2IR7t0DhbAyYJOfiIX0m1OlQGKOrMVNqe65ynvQ2wZKGyMaqYgyljb5vXvtobJ7uzsEGR5ybsMXFtShxI/ctoxUCtSX6Ob0U8ScgYo5AxIzKHi0FqgAMeQBYsW4CuYAD3MtfbdXkOzEhE6ScgZoIzHIPDiFz9O+vM7d7sBw131kA1YAEnQD6+7Yo1eTwEPSmDWy8WKVxaROd9WPPQGLICkVyT+a1tikq4Tn+JpF55CzAXIfTWx5+q36PShh150Nz67GOcSgcOpqsHVKeQU1H8mkHjJxAWogN5DHtFGL4nA4ZU4x+ViB4lF5jE2w/DC28/jROD98tUVa4MjOhuvEdQeJ96jH4DojxKJwFQ5UBFBiw0kLtF9Bhn6EW20kggcdmlF4q+Q1HjCmDC3BGP0sotSEoHDL6shhLW3zuxDnXZhkXcEopRE4DjKuumocEt4S6Av90cpicDxlHXtqFDfhTlGZPGE+juSRODfuQi9t+mocGcDuwo9QJ//icC+rIQ797H5wMYuPCecEuiLQiJ5VJIIHFU5Vw9suSeke+ZE3qFHF/RUInDQ5fM6/59ntrRzlx5d0FOJwEGXz+u8vl7ZPCrMreW/3isCnkwEDrh4G1wXeYd1nX03QiR+Nl+3CbWf/qSoXeWWmN15TA1zIsWgoSsZV0Dzl0AyW/38Za9r6nLHYAkyYMBLRfcsG4v8YKzd2UDoqqFLwy5kgOLMgMT4/GF+AEZgCgpwA7y2uh7dBEgWvvXcHHpntzLmRy4drXETNVvNPbp52xprP2vM/+lQL4hnwkITu9jwmSLwQW+OEBTPUKvv4AbkIAMjsEA3pm0l2GoXyywGuogdbULzSf1dYne/6112L9T7zrqVXTMR+IXJPfnlkM1w0wKo9Yl2J5G5jegFoLWEBddd6SKIeUtTqr9L9rHdtdYG/eqF1dAt7dina5iGM+zLDpxRErOjLGPIuG9xZX9bW/e+1vd2uUdmFcfchX1xLO19fTqvryFM9oXAq11yR0FU2MsdNj61ztXGKiqfQWNu9WkZu3DJvL4tdhSp+eTWdwR24yjavhDYHLla+6yvF8rU+jOhrWz/2I0j8D/HvtEp1+8LgauWSXVFbmn+ZObWFznbyKWOEuzCul+rh782i/bRpi8E/taiuBU2ZQu7pskdRKzs5Lumcst4CokHXFu/fov5i1XGrvDw4pU6tEAvCAxJbsn5fEfeP9sdcYfZ2Q8MSgs9iH0AZ/bMeal+SzHYjVra7m1We1HtfW1IF/Tpk7j3FEZnz6xRoCXja0vyhmp9iN0a6Sx5i3XrnTNjrp2diGwD643ijUZ6Q2BLkgsIk1E9QQWtgAi0s6j2OsyfidbQhwYjoL4TY+2Nm6hdX7eTeorOvaV2qAesubtvrXX3rWpzqdulDECEGZCYQ/jFOvqAI0RZ+21AEC6W7BC56coavTgDN5NNMevv3TbVMYx1Tm+K+3jZtzs3bYMZ94rAEFe/2rU7PYIFfWEcTLXaO1p6TA1zyzbHJc+1nZ3qDYEhqgoo8mbAiaGjX60jNxFJW9bjID6df4cgqt1XMfaGwMSaAQN8MrZF9ulCmys9u6zIK/EdLX5pAv3ZJwJfbamR26G2mASj+uLx1MV+59EFPdUnAgddqD2cLz22GXM6//p0HvNwphKBw6lVG0/XPhThaJRxoQH3IDpJBI6rpNeecNzxYebRBT+VCBx8CZ8CuOaIUD2N6LD7GpocVOiiO/8SV6/ehVC8sYoIOvEEN7Zzvp3ZYx7eVNqBw6tZ0+MlExfNyfrui65s6mMZ94nAKnSM8ql5dLBBPu2+G/RR5KJPBH6IomLPg/gAOWfPp1Zn34/M5UBHixlttNKbr1NSwXlEVdRvk/eQs2zGZI8OEzu/drRo2oc+7tMOfEexYjhGlMTxdgt5C/QDsOlogSoe6Q2BKbjIG/LTuPwXKS9A1aSg3XlFXgOusblt2sQ47g2BVTxb1C+BFdK98N5sImWDvF+wmwQW4x+726cz8CpJFDen4BUD95T+x8k74oXy7xvQXyyXtBuFWDKUU2CAyJvT9kZ6R2BVliLrO8AzuhPwHxiA15CKm2qHVfsA5qDEP423Cv7LZ70IR9bwWnHZfm+a85gitaS8IqY3FLNqGxvXGWzX/lrBkkREOZjs49emm+JXhs7tukv6H1j3bpN9mg8kAyIwkJhAXN7LTeLKQAGcfKVz0BfYXg4l48NmgGLqaCDJDrvy661GLPoD1BEogJOCTjQxvl52O3ZnFdVWWL9egxViMKBJWoVWgCzYwJLjuzNgi0zT/b82xkcRdQhyoH93oCPBI6jLgsEEpKOCp/xRPcQpPgptaAqgVg84c9AVEQkdEc0Gp+RzCe6B3karaJNsyEB0BFaclsQjuu/AUHMdksr6IqKq/2Bb9eeJsGQhScpAykDKQMpAykDKQMpAykDKQMrAxgz8DwJAaLFs+kDBAAAAAElFTkSuQmCC\"","\"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>&nbsp;</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}&nbsp;\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}&nbsp;\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 { 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","PollStrategy","ForegroundStrategy","ReloadStrategy","dkmitiderhverv","dkmitid","ftnmobile","ftn","itsme","sebankid","nobankid","mobilepay","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/mobilepay.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/use-criipto-verify.ts"],"sourcesContent":["import CriiptoAuth, {\n OpenIDConfiguration,\n type AuthorizeUrlParamsOptional,\n type PKCE,\n type AuthorizeResponse,\n OAuth2Error,\n type PKCEPublicPart,\n type Prompt,\n} from '@criipto/auth-js';\nimport type { PopupAuthorizeParams, RedirectAuthorizeParams } from '@criipto/auth-js';\nimport { createContext } from 'react';\n\nexport type ResultSource = 'SEBankIDQrCode' | 'SEBankIDSameDeviceButton' | 'redirect' | '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 BeforeAuthorizeParams {\n /**\n * The acr_values of the authorize request that is about to be made, always normalized to an array.\n * For logins started from a button or `AuthMethodSelector` this will hold exactly one value.\n */\n acrValues: string[];\n /**\n * The parameters the SDK is about to use, with `CriiptoVerifyProvider` configuration already applied.\n */\n options: AuthorizeUrlParamsOptional;\n}\n\n/**\n * Parameters to override for a single authorize request. Any field left out (or set to `undefined`)\n * keeps the value configured on `CriiptoVerifyProvider`.\n */\nexport interface BeforeAuthorizeOverrides {\n /**\n * Appended to the login_hint of this request, just like a `loginHint` passed directly to\n * `loginWithRedirect`. Use `action` and `message` rather than `action:`/`message:` hints,\n * as those are managed by the SDK.\n */\n loginHint?: string;\n action?: Action;\n message?: string;\n scope?: string;\n prompt?: Prompt;\n uiLocales?: string;\n state?: string;\n nonce?: string;\n extraUrlParams?: {\n [key: string]: string | null;\n };\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, loginHint }: { disambiguate: boolean; loginHint?: string },\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 const marketHint = loginHint?.split(' ').find((s) => s.startsWith('market:'));\n if (marketHint === 'market:DK' || marketHint === 'market:FI') {\n return { title: 'MobilePay' };\n }\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, useRef } 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 BeforeAuthorizeOverrides,\n type BeforeAuthorizeParams,\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 * Called just before each authorize request is built, for every login flow\n * (`AuthMethodSelector`, `AuthMethodButton`, `SEBankIDQRCode`, `loginWithRedirect` and `loginWithPopup`).\n * Return the parameters you wish to change for that particular request, for instance a\n * `loginHint` that depends on the acr_value the user picked. Returning nothing leaves the\n * request as configured on the provider.\n */\n beforeAuthorize?: (params: BeforeAuthorizeParams) => BeforeAuthorizeOverrides | void;\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 normalizeAcrValues(acrValues?: string | string[]): string[] {\n if (!acrValues) return [];\n return Array.isArray(acrValues) ? acrValues : [acrValues];\n}\n\nexport function buildLoginHint(\n loginHint: string | undefined | null,\n params: {\n options?: AuthorizeUrlParamsOptional;\n action?: Action;\n message?: string;\n /**\n * Additional hints, e.x. contributed by `beforeAuthorize`\n */\n extraLoginHint?: string;\n },\n) {\n const { options, action, message, extraLoginHint } = params;\n const acrValues = normalizeAcrValues(options?.acrValues);\n let hints = (loginHint ? loginHint.split(' ') : [])\n .concat(options?.loginHint ? options?.loginHint.split(' ') : [])\n .concat(extraLoginHint ? extraLoginHint.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 /*\n * `beforeAuthorize` is only ever called imperatively, when a login is started.\n * Keeping it in a ref (rather than in the `buildOptions` dependencies) means an inline\n * function does not invalidate `buildAuthorizeUrl`, which components like `SEBankIDQRCode`\n * memoize on and would otherwise restart their flow on every provider render.\n */\n const beforeAuthorizeRef = useRef(props.beforeAuthorize);\n useEffect(() => {\n beforeAuthorizeRef.current = props.beforeAuthorize;\n }, [props.beforeAuthorize]);\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 const resolved: AuthorizeUrlParamsOptional = {\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 const overrides = beforeAuthorizeRef.current?.({\n acrValues: normalizeAcrValues(resolved.acrValues),\n options: resolved,\n });\n if (!overrides) return resolved;\n\n return {\n ...resolved,\n state: overrides.state ?? resolved.state,\n nonce: overrides.nonce ?? resolved.nonce,\n prompt: overrides.prompt ?? resolved.prompt,\n scope: overrides.scope ?? resolved.scope,\n uiLocales: overrides.uiLocales ?? resolved.uiLocales,\n loginHint: buildLoginHint(props.loginHint, {\n options,\n action: overrides.action ?? action,\n message: overrides.message ?? message,\n extraLoginHint: overrides.loginHint,\n }),\n extraUrlParams: {\n ...resolved.extraUrlParams,\n ...overrides.extraUrlParams,\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,iVBORw0KGgoAAAANSUhEUgAAAFgAAAAkCAYAAAANdf2OAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAOdEVYdFNvZnR3YXJlAEZpZ21hnrGWYwAAAlhJREFUeAHtmu1R20AQhteZ/I86iDoIHVgdQAdxB04HIRXgVGBSQaACQQWmA7kDoIJll3uNj0PfYjg0t8/Mju37+OFXe7u3dyL6xDBzIbYVK8V+kjEdETITW0NU5d77/ouMccBbLyAoQ1QVOkP/Fn0ZGf0Rwc4Cb1WRlzXjCoz5TUY7CAPnnrdWKlyXd+JB7MhoRgTKIeghDCwHzF1hXkFGPQgBSk4Dgec/hxH8zhGn/+Oh+SsizVh9SFY0Epl7EuwymkgzVssfPx2zzGvidhcVpQpEKgeML/gYt4dQUGS+Uhw2YuqN2WKxeGgbyK64uPCadPyV2J3YrdeeBWO+iT1SimC5d8ZJhISXJc8u9vqJrStc7NjF/IJSg12SaqzM2CUzn6V6M/ePwSEVp7Sz4GNldtoypgwELnka3+mD+UKRkNh7Ix97sbYDnCuaOdEEBpdi6slFQ/8/cglrtsQW+C85AWvDBHYYG5oxUQWGgJdiq5YEdE0zJrYHKyqgilt7YyEPQfe7NzRToguMZKd21jLsD82UWJVciO4WNprsIPgrtE36fgTNGl507B7f915fLnbifaYNH48hy45xWr013Xic181nV/mtUGh8+D7408DuRoN5ZLXlFS4FGW+Bpymjz3F54CldcqAUnnIYf1gFORlvmbrMuecpXdJMXeaYvyWjHm+ZD9pesTve3GKuvWbVhLdl67XMEVZKCNt7XtLw8bai6TA+vAC95x4vrhjAS3brmvaDtzIPfHHF8IB4FUTVO7idees7gqRVBd66NmHfGXZ3cXZgYxhReAKtoA9h3jxwjgAAAABJRU5ErkJggg==\"","\"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 mobilepay from './logos/mobilepay.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 loginHint?: 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, props.loginHint) ? (\n <img src={acrValueToLogo(props.acrValue, props.loginHint)} alt=\"\" />\n ) : (\n <span>&nbsp;</span>\n )))\n );\n\n if (logo) return <div className=\"criipto-eid-logo\">{logo}</div>;\n return null;\n}\n\nfunction acrValueToLogo(value: string, loginHint: string | undefined) {\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 const marketHint = loginHint?.split(' ').find((s) => s.startsWith('market:'));\n if (marketHint === 'market:DK' || marketHint === 'market:FI') {\n return mobilepay;\n }\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 loginHint?: string;\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 loginHint: props.loginHint,\n });\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title}&nbsp;\n {standalone ? null : lowercaseFirst(subtitle)}\n </React.Fragment>\n );\n\n const inner = (\n <React.Fragment>\n <AuthMethodButtonLogo\n acrValue={acrValue}\n loginHint={props.loginHint}\n logo={props.loading ? <Spinner /> : props.logo}\n />\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)} ${loginHintToClassName(context.loginHint ?? '')} ${\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 loginHint: context.loginHint,\n });\n\n const contents = props.children ?? (\n <React.Fragment>\n {stringifyAction(language, action) ? `${stringifyAction(language, action)} ` : ''}\n {title}&nbsp;\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 loginHint={context.loginHint}\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={\n <AuthMethodButtonLogo acrValue={acrValue} loginHint={props.loginHint} logo={props.logo} />\n }\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 loginHintToClassName(value: string) {\n const hints = value.split(' ');\n const marketHint = hints.find((s) => s.startsWith('market:'));\n\n return [marketHint ? `criipto-eid-btn--${marketHint?.replace(':', '-')}` : undefined].filter(\n (id) => id !== undefined,\n );\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 { 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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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@criipto/verify-react",
3
3
  "private": false,
4
- "version": "6.0.0",
4
+ "version": "6.0.2",
5
5
  "type": "module",
6
6
  "description": "Verify SDK for React Single Page Applications",
7
7
  "exports": {