@criipto/verify-react 5.0.2 → 6.0.1

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
@@ -1,22 +1,27 @@
1
1
  # @criipto/verify-react
2
2
 
3
- Accept MitID, Swedish BankID, Norwegian BankID and more logins in your React app with `@criipto/verify-react`.
3
+ The Idura Verify React SDK lets you authenticate users with European eID providers [supported by Idura](https://docs.idura.app/verify/e-ids/).
4
4
 
5
- ## App switch support
6
-
7
- `@criipto/verify-react` supports app switching for Swedish BankID and Danish MitID by a best-effort mobile-os detection and setting the relevant Criipto Verify login hints.
5
+ The SDK uses the [PKCE flow](https://docs.idura.app/verify/reference/authorization-flows/pkce/) suitable for public clients.
8
6
 
9
7
  ## Installation
10
8
 
11
- Using [npm](https://npmjs.org/)
12
-
13
9
  ```sh
14
10
  npm install @criipto/verify-react
15
11
  ```
16
12
 
17
- ## Getting Started
13
+ ## Prerequisites
14
+
15
+ You need an Idura application to initialize the SDK. If you haven't already, follow the [dashboard setup guide](https://docs.idura.app/verify/getting-started/dashboard-setup/) to create one.
16
+
17
+ The SDK needs two values from your Idura application:
18
18
 
19
- Setup the Criipto Verify SDK by wrapping your application in `CriiptoVerifyProvider`:
19
+ - your Idura domain
20
+ - your application client ID
21
+
22
+ ## Initialize the SDK
23
+
24
+ Initialize the SDK by wrapping your React app in `CriiptoVerifyProvider`:
20
25
 
21
26
  ```jsx
22
27
  // src/index.js
@@ -28,8 +33,8 @@ import App from './App';
28
33
 
29
34
  ReactDOM.render(
30
35
  <CriiptoVerifyProvider
31
- domain="{YOUR_CRIIPTO_DOMAIN}"
32
- clientID="{YOUR_CRIIPTO_APPLICATION_CLIENT_ID}"
36
+ domain="{YOUR_IDURA_DOMAIN}"
37
+ clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
33
38
  redirectUri={window.location.href}
34
39
  >
35
40
  <App />
@@ -38,15 +43,43 @@ ReactDOM.render(
38
43
  );
39
44
  ```
40
45
 
41
- You can find your domain and application client id on the [Criipto Dashboard](https://dashboard.criipto.com/).
46
+ The `redirectUri` you pass to `CriiptoVerifyProvider` is where Idura returns the user after login, and it must be registered as a redirect URL on your Idura application. The examples use `window.location.href`, but any route (e.g. a dedicated `/callback` path) works too.
42
47
 
43
- Use the `useCriiptoVerify` hook + the `AuthMethodSelector` component in your React app to render a login screen.
48
+ ## Call the `useCriiptoVerify` hook
49
+
50
+ Inside a component wrapped by `CriiptoVerifyProvider`, call `useCriiptoVerify` to read the auth state and start a login.
51
+
52
+ ```jsx
53
+ const {
54
+ result,
55
+ claims,
56
+ error,
57
+ loginWithRedirect,
58
+ loginWithPopup,
59
+ logout,
60
+ isLoading,
61
+ isInitializing,
62
+ } = useCriiptoVerify();
63
+ ```
64
+
65
+ - `result`: the login outcome, `result.id_token` or `result.code` on success and an error otherwise
66
+ - `claims`: the decoded `id_token`
67
+ - `error`: configuration and login errors
68
+ - `loginWithRedirect` / `loginWithPopup`: start a login with redirect or in a popup window
69
+ - `logout`: clear the session store and end the SSO session
70
+ - `isLoading` / `isInitializing`: whether the SDK is still working or starting up
71
+
72
+ ## Render login options
73
+
74
+ The SDK provides an `AuthMethodSelector` component that renders a method selector screen where your users can choose a login method.
75
+
76
+ By default, `AuthMethodSelector` shows one button per eID method enabled for your Idura application (**Applications → your app → eIDs** in the dashboard).
44
77
 
45
78
  ```jsx
46
79
  // src/App.js
47
80
  import React from 'react';
48
81
  import { useCriiptoVerify, AuthMethodSelector } from '@criipto/verify-react';
49
- import '@criipto/verify-react/index.css';
82
+ import '@criipto/verify-react/index.css'; // Import the stylesheet, or the buttons render unstyled.
50
83
 
51
84
  export default function App() {
52
85
  const { result, error } = useCriiptoVerify();
@@ -64,20 +97,87 @@ export default function App() {
64
97
  }
65
98
  ```
66
99
 
67
- Always render the `error` field from `useCriiptoVerify`. It surfaces both **configuration errors** (e.g. invalid `domain` or `clientID`, or CORS) raised when the provider mounts, and **runtime errors** raised during a login attempt (e.g. user cancellation, OAuth2 errors from the IdP). Without rendering `error`, misconfiguration and failed logins will appear silent to the user.
100
+ Always render the `error` field from `useCriiptoVerify`. It surfaces both **configuration errors** (e.g. invalid `domain` or `clientID`, or CORS) raised when the provider mounts, and **runtime errors** raised during a login attempt (e.g. user cancellation, or OAuth2 errors from the [identity provider (IdP)](https://docs.idura.app/verify/reference/glossary/#identity-provider-idp)). Without rendering `error`, misconfiguration and failed logins will appear silent to the user.
101
+
102
+ ### Select eIDs programmatically
103
+
104
+ To control eID methods from your code instead of the dashboard, pass `acrValues` to `AuthMethodSelector`:
105
+
106
+ ```jsx
107
+ <AuthMethodSelector
108
+ acrValues={['urn:grn:authn:dk:mitid:substantial', 'urn:grn:authn:dk:mitid:high']}
109
+ />
110
+ ```
111
+
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
+
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
+
145
+ ## Send the user directly to an eID login screen
146
+
147
+ If you don't need the method selector, use `loginWithRedirect` (or `loginWithPopup`) and pass a single eID method identifier in `acrValues`.
148
+
149
+ ```jsx
150
+ // src/App.js
151
+ import React from 'react';
152
+ import { useCriiptoVerify } from '@criipto/verify-react';
153
+
154
+ export default function App() {
155
+ const { result, loginWithRedirect } = useCriiptoVerify();
156
+
157
+ if (result?.id_token) {
158
+ return <pre>{JSON.stringify(result.id_token, null, 2)}</pre>;
159
+ }
160
+
161
+ return (
162
+ <button onClick={() => loginWithRedirect({ acrValues: 'urn:grn:authn:dk:mitid:substantial' })}>
163
+ Log in with MitID
164
+ </button>
165
+ );
166
+ }
167
+ ```
68
168
 
69
169
  ## CORS
70
170
 
71
- The library makes fetch requests to Criipto for two reasons:
171
+ The SDK makes fetch requests to Idura for two reasons:
72
172
 
73
173
  1. To load application configuration when the provider mounts.
74
174
  2. To push the authorization request (PAR) when a user clicks a login button.
75
175
 
76
- Make sure that the origin your React app runs on is included in the list of callback URLs for your application. Otherwise, both calls will fail with CORS errors.
176
+ Make sure the origin your React app runs on is included in the list of redirect URLs for your Idura application. Otherwise, both calls will fail with CORS errors.
77
177
 
78
178
  ## Sessions
79
179
 
80
- If you want to use `@criipto/verify-react` for session management (rather than one-off authentication) you can configure a `sessionStore`:
180
+ If you want to use the SDK for session management (rather than one-off authentication), you can configure a `sessionStore`:
81
181
 
82
182
  ```jsx
83
183
  // src/index.js
@@ -89,8 +189,8 @@ import App from './App';
89
189
 
90
190
  ReactDOM.render(
91
191
  <CriiptoVerifyProvider
92
- domain="{YOUR_CRIIPTO_DOMAIN}"
93
- clientID="{YOUR_CRIIPTO_APPLICATION_CLIENT_ID}"
192
+ domain="{YOUR_IDURA_DOMAIN}"
193
+ clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
94
194
  redirectUri={window.location.href}
95
195
  sessionStore={window.sessionStorage} // or window.localStorage
96
196
  >
@@ -100,11 +200,11 @@ ReactDOM.render(
100
200
  );
101
201
  ```
102
202
 
103
- When a `sessionStore` is configured the library will store the id_token in your chosen storage (sessionStorage or localStorage) and invalidate the token once it expires.
203
+ When a `sessionStore` is configured, the SDK stores the `id_token` in your chosen storage (`sessionStorage` or `localStorage`) and invalidates it once it expires.
104
204
 
105
- The library will also attempt to retrieve a user token on page load via SSO (if your criipto domain has SSO enabled).
205
+ The SDK will also attempt to retrieve the token on page load via SSO. (This requires SSO enabled on your Idura domain: check **Domains → your domain → SSO** section in the dashboard).
106
206
 
107
- You may wish to increase the "Token lifetime" setting of your Criipto Application.
207
+ For longer sessions, you can increase the **Token lifetime** setting of your Idura application (**Applications → your app → Advanced Options**).
108
208
 
109
209
  ```jsx
110
210
  // src/App.js
@@ -126,7 +226,7 @@ export default function App() {
126
226
  <React.Fragment>
127
227
  {error ? (
128
228
  <p>
129
- An error occured:{' '}
229
+ An error occurred:{' '}
130
230
  {error instanceof OAuth2Error
131
231
  ? `${error.error} (${error.error_description})`
132
232
  : String(error)}
@@ -139,18 +239,34 @@ export default function App() {
139
239
  }
140
240
  ```
141
241
 
142
- ### Logging Out
242
+ ### Logging out
143
243
 
144
- `@criipto/verify-react` offers the logout method you can use to clear session storage and log out of any existing SSO session.
244
+ The `logout` method clears the session store and ends any existing SSO session.
145
245
 
146
246
  ```jsx
147
- const {logout} = useCriiptoVerify();
148
- ...
149
- <button onClick={() => logout({redirectUri: window.location.href})}>
150
- Log Out
151
- </button>
247
+ // src/App.js
248
+ import React from 'react';
249
+ import { useCriiptoVerify, AuthMethodSelector } from '@criipto/verify-react';
250
+ import '@criipto/verify-react/index.css';
251
+
252
+ export default function App() {
253
+ const { claims, logout } = useCriiptoVerify();
254
+
255
+ if (claims) {
256
+ return (
257
+ <React.Fragment>
258
+ <pre>{JSON.stringify(claims, null, 2)}</pre>
259
+ <button onClick={() => logout({ redirectUri: window.location.href })}>Log out</button>
260
+ </React.Fragment>
261
+ );
262
+ }
263
+
264
+ return <AuthMethodSelector />;
265
+ }
152
266
  ```
153
267
 
268
+ `logout` takes an optional `redirectUri` (where to send the user afterwards) and `state` (an opaque string used to mitigate CSRF attacks, see [state](https://docs.idura.app/verify/reference/request-parameters/#state)).
269
+
154
270
  ## useEffect + loginWithRedirect
155
271
 
156
272
  If you are triggering `loginWithRedirect` inside a `useEffect` hook, you need to allow the SDK time to initialize a few values before you redirect the user:
@@ -164,6 +280,10 @@ useEffect(() => {
164
280
  }, [isLoading, isInitializing]);
165
281
  ```
166
282
 
167
- ## Criipto
283
+ ## Idura
284
+
285
+ Learn more about Idura and sign up for a free developer account at [idura.eu](https://idura.eu).
286
+
287
+ ### Why the package is named `@criipto/verify-react`
168
288
 
169
- Learn more about Criipto and sign up for your free developer account at [criipto.com](https://www.criipto.com).
289
+ Idura was previously called Criipto, and most of our SDKs keep the `@criipto` name for backwards compatibility. You can read more about the rebrand in [our blog](https://idura.eu/blog/criipto-is-now-idura).
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
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
7
- type ResultSource = 'QRCode' | 'SEBankIDQrCode' | 'SEBankIDSameDeviceButton' | 'redirect' | 'popup';
7
+ type ResultSource = 'SEBankIDQrCode' | 'SEBankIDSameDeviceButton' | 'redirect' | 'popup';
8
8
  type Result = {
9
9
  id_token: string;
10
10
  state?: string;
@@ -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
  */
@@ -159,34 +200,6 @@ declare function AuthButtonGroup(props: {
159
200
  children: React.ReactNode;
160
201
  }): react_jsx_runtime0.JSX.Element;
161
202
  //#endregion
162
- //#region src/components/QRCode.d.ts
163
- declare const QRCode: React.FC<{
164
- margin?: number;
165
- className?: string;
166
- acrValues?: string[];
167
- children: (props: {
168
- qrElement: React.ReactElement;
169
- /**
170
- * Will be true once the QR code has been scanned
171
- */
172
- isAcknowledged: boolean;
173
- /**
174
- * Will be true if the user cancels the login on his mobile device
175
- */
176
- isCancelled: boolean;
177
- /**
178
- * Whether or not QR codes are enabled for this Criipto Applicaiton
179
- */
180
- isEnabled: boolean | undefined;
181
- error: OAuth2Error$1 | Error | null;
182
- retry: () => void;
183
- /**
184
- * A method for triggering a full screen redirect to authentication (useful if user is on mobile device already)
185
- */
186
- redirect: () => Promise<void>;
187
- }) => React.ReactElement;
188
- }>;
189
- //#endregion
190
203
  //#region src/components/SEBankIDQRCode.d.ts
191
204
  interface Props {
192
205
  redirectUri?: string;
@@ -263,5 +276,5 @@ declare function useCriiptoVerify(): {
263
276
  //#region src/utils.d.ts
264
277
  declare function filterAcrValues(input: string[]): string[];
265
278
  //#endregion
266
- export { type Action, AuthMethodButtonContainer as AuthButton, AuthMethodButtonContainer as AuthMethodButton, AuthMethodButtonComponent as AuthButtonComponent, AuthButtonGroup, AuthMethodSelector, Sweden as AuthMethodSelectorSweden, CriiptoVerifyProvider, type Language, OAuth2Error, QRCode, type Result, SEBankIDQrCode as SEBankIDQRCode, actions, filterAcrValues, useCriiptoVerify };
279
+ 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 };
267
280
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
2
- import CriiptoAuth, { OAuth2Error, OAuth2Error as OAuth2Error$1, UserCancelledError, clearPKCEState, generatePKCE, parseAuthorizeResponseFromLocation, savePKCEState } from "@criipto/auth-js";
1
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
2
+ import CriiptoAuth, { OAuth2Error, OAuth2Error as OAuth2Error$1, clearPKCEState, generatePKCE, parseAuthorizeResponseFromLocation, savePKCEState } from "@criipto/auth-js";
3
3
  import jwtDecode from "jwt-decode";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { UAParser } from "@ua-parser-js/pro-enterprise";
6
- import QRCode$1 from "qrcode";
6
+ import QRCode from "qrcode";
7
7
  import classNames from "classnames";
8
8
  //#region src/context.ts
9
9
  const actions = [
@@ -45,7 +45,7 @@ const CriiptoVerifyContext = createContext({
45
45
  });
46
46
  //#endregion
47
47
  //#region package.json
48
- var version = "5.0.2";
48
+ var version = "6.0.1";
49
49
  //#endregion
50
50
  //#region src/i18n/en.ts
51
51
  const en = {
@@ -464,10 +464,14 @@ const MESSAGE_SUPPORTING_ACR_VALUES = [
464
464
  "urn:grn:authn:se:bankid:same-device",
465
465
  "urn:grn:authn:se:bankid:another-device:qr"
466
466
  ];
467
+ function normalizeAcrValues(acrValues) {
468
+ if (!acrValues) return [];
469
+ return Array.isArray(acrValues) ? acrValues : [acrValues];
470
+ }
467
471
  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:"));
472
+ const { options, action, message, extraLoginHint } = params;
473
+ const acrValues = normalizeAcrValues(options === null || options === void 0 ? void 0 : options.acrValues);
474
+ 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
475
  if (action) {
472
476
  hints = hints.filter((h) => !h.startsWith("action:"));
473
477
  if (acrValues.length === 1) {
@@ -574,6 +578,10 @@ const CriiptoVerifyProvider = (props) => {
574
578
  const action = (_ref = (_props$action = props.action) !== null && _props$action !== void 0 ? _props$action : parseAction(loginHint)) !== null && _ref !== void 0 ? _ref : "login";
575
579
  const message = (_props$message = props.message) !== null && _props$message !== void 0 ? _props$message : parseMessage(loginHint);
576
580
  const sessionStore = props.sessionStore;
581
+ const beforeAuthorizeRef = useRef(props.beforeAuthorize);
582
+ useEffect(() => {
583
+ beforeAuthorizeRef.current = props.beforeAuthorize;
584
+ }, [props.beforeAuthorize]);
577
585
  const refreshPKCE = function() {
578
586
  var _ref2 = _asyncToGenerator(function* () {
579
587
  if (props.pkce) return props.pkce;
@@ -592,8 +600,8 @@ const CriiptoVerifyProvider = (props) => {
592
600
  };
593
601
  }();
594
602
  const buildOptions = useCallback((options) => {
595
- var _props$responseType, _props$state, _props$nonce, _props$prompt, _props$scope, _options$pkce;
596
- return _objectSpread2(_objectSpread2({
603
+ 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;
604
+ const resolved = _objectSpread2(_objectSpread2({
597
605
  redirectUri: defaultRedirectUri(props.redirectUri),
598
606
  responseType: (_props$responseType = props.responseType) !== null && _props$responseType !== void 0 ? _props$responseType : "code",
599
607
  responseMode: props.responseMode
@@ -611,6 +619,25 @@ const CriiptoVerifyProvider = (props) => {
611
619
  }),
612
620
  extraUrlParams: props.criiptoSdk !== void 0 ? { criipto_sdk: props.criiptoSdk } : { criipto_sdk: `@criipto/verify-react@${version}` }
613
621
  });
622
+ const overrides = (_beforeAuthorizeRef$c = beforeAuthorizeRef.current) === null || _beforeAuthorizeRef$c === void 0 ? void 0 : _beforeAuthorizeRef$c.call(beforeAuthorizeRef, {
623
+ acrValues: normalizeAcrValues(resolved.acrValues),
624
+ options: resolved
625
+ });
626
+ if (!overrides) return resolved;
627
+ return _objectSpread2(_objectSpread2({}, resolved), {}, {
628
+ state: (_overrides$state = overrides.state) !== null && _overrides$state !== void 0 ? _overrides$state : resolved.state,
629
+ nonce: (_overrides$nonce = overrides.nonce) !== null && _overrides$nonce !== void 0 ? _overrides$nonce : resolved.nonce,
630
+ prompt: (_overrides$prompt = overrides.prompt) !== null && _overrides$prompt !== void 0 ? _overrides$prompt : resolved.prompt,
631
+ scope: (_overrides$scope = overrides.scope) !== null && _overrides$scope !== void 0 ? _overrides$scope : resolved.scope,
632
+ uiLocales: (_overrides$uiLocales = overrides.uiLocales) !== null && _overrides$uiLocales !== void 0 ? _overrides$uiLocales : resolved.uiLocales,
633
+ loginHint: buildLoginHint(props.loginHint, {
634
+ options,
635
+ action: (_overrides$action = overrides.action) !== null && _overrides$action !== void 0 ? _overrides$action : action,
636
+ message: (_overrides$message = overrides.message) !== null && _overrides$message !== void 0 ? _overrides$message : message,
637
+ extraLoginHint: overrides.loginHint
638
+ }),
639
+ extraUrlParams: _objectSpread2(_objectSpread2({}, resolved.extraUrlParams), overrides.extraUrlParams)
640
+ });
614
641
  }, [
615
642
  pkce,
616
643
  props.state,
@@ -1215,7 +1242,7 @@ function useDraw(qrCode, options) {
1215
1242
  if (!qrCode) return;
1216
1243
  let isSubscribed = true;
1217
1244
  _asyncToGenerator(function* () {
1218
- const qrImage = yield QRCode$1.toDataURL(qrCode, {
1245
+ const qrImage = yield QRCode.toDataURL(qrCode, {
1219
1246
  errorCorrectionLevel: "low",
1220
1247
  scale: 10,
1221
1248
  width,
@@ -1819,113 +1846,6 @@ function Sweden(props) {
1819
1846
  });
1820
1847
  }
1821
1848
  //#endregion
1822
- //#region src/components/QRCode.tsx
1823
- const QRCode = (props) => {
1824
- var _ref, _props$acrValues;
1825
- const { children, margin, className } = props;
1826
- const elementRef = useRef(null);
1827
- const { client, buildOptions, buildAuthorizeUrl, handleResponse, pkce, store, acrValues: configurationAcrValues } = useContext(CriiptoVerifyContext);
1828
- const [requestId, setRequestId] = useState(() => Math.random().toString());
1829
- const [isAcknowledged, setAcknowledged] = useState(false);
1830
- const [isCancelled, setCancelled] = useState(false);
1831
- const [error, setError] = useState(null);
1832
- const [criiptoConfiguration, setCriiptoConfiguration] = useState(null);
1833
- const isEnabled = criiptoConfiguration === null || criiptoConfiguration === void 0 ? void 0 : criiptoConfiguration.client.qr_enabled;
1834
- const acrValues = (_ref = (_props$acrValues = props.acrValues) !== null && _props$acrValues !== void 0 ? _props$acrValues : configurationAcrValues) !== null && _ref !== void 0 ? _ref : [];
1835
- useEffect(() => {
1836
- let isSubsribed = true;
1837
- client.fetchCriiptoConfiguration().then((c) => {
1838
- if (!isSubsribed) return;
1839
- setCriiptoConfiguration(c);
1840
- });
1841
- return () => {
1842
- isSubsribed = false;
1843
- };
1844
- }, [client]);
1845
- const redirect = useCallback(_asyncToGenerator(function* () {
1846
- var _criiptoConfiguration;
1847
- if (!criiptoConfiguration) return;
1848
- const intermediaryUrl = ((_criiptoConfiguration = criiptoConfiguration.client.qr_intermediary_url) !== null && _criiptoConfiguration !== void 0 ? _criiptoConfiguration : criiptoConfiguration.qr_intermediary_url).replace("/{id}", "").replace("{id}", "");
1849
- const authorizeUrl = new URL(yield buildAuthorizeUrl({ acrValues }));
1850
- const authorizeParams = new URLSearchParams(authorizeUrl.search);
1851
- authorizeParams.set("domain", authorizeUrl.host);
1852
- authorizeUrl.host = new URL(intermediaryUrl).host;
1853
- authorizeUrl.port = new URL(intermediaryUrl).port;
1854
- authorizeUrl.pathname = new URL(intermediaryUrl).pathname + "/authorize";
1855
- authorizeUrl.search = authorizeParams.toString();
1856
- if (pkce && "code_verifier" in pkce) savePKCEState(store, {
1857
- response_type: "id_token",
1858
- pkce_code_verifier: pkce.code_verifier,
1859
- redirect_uri: authorizeParams.get("redirect_uri")
1860
- });
1861
- window.location.href = authorizeUrl.toString();
1862
- }), [
1863
- buildAuthorizeUrl,
1864
- criiptoConfiguration,
1865
- acrValues
1866
- ]);
1867
- const authorize = useCallback(() => {
1868
- return client.qr.authorize(elementRef.current, _objectSpread2(_objectSpread2({}, buildOptions({ acrValues })), {}, { margin }));
1869
- }, [
1870
- client,
1871
- buildOptions,
1872
- margin,
1873
- acrValues
1874
- ]);
1875
- useLayoutEffect(() => {
1876
- if (!elementRef.current) return;
1877
- if (error) return;
1878
- if (!isEnabled) return;
1879
- const promise = authorize();
1880
- promise.onAcknowledged = () => {
1881
- setAcknowledged(true);
1882
- };
1883
- promise.then((response) => {
1884
- if (promise.cancelled) return;
1885
- handleResponse(response, {
1886
- pkce: pkce && "code_verifier" in pkce ? pkce : void 0,
1887
- source: "QRCode"
1888
- });
1889
- }).catch((err) => {
1890
- if (err instanceof UserCancelledError) {
1891
- setCancelled(true);
1892
- return;
1893
- }
1894
- if (promise.cancelled) return;
1895
- setError(err);
1896
- handleResponse(err, { source: "QRCode" });
1897
- });
1898
- return () => {
1899
- promise.cancel();
1900
- };
1901
- }, [
1902
- authorize,
1903
- pkce,
1904
- handleResponse,
1905
- requestId,
1906
- error,
1907
- isEnabled
1908
- ]);
1909
- const handleRetry = () => {
1910
- setAcknowledged(false);
1911
- setCancelled(false);
1912
- setError(null);
1913
- setRequestId(Math.random().toString());
1914
- };
1915
- return children({
1916
- qrElement: /* @__PURE__ */ jsx("div", {
1917
- ref: elementRef,
1918
- className
1919
- }),
1920
- isAcknowledged,
1921
- isCancelled,
1922
- isEnabled: criiptoConfiguration === null || criiptoConfiguration === void 0 ? void 0 : criiptoConfiguration.client.qr_enabled,
1923
- error,
1924
- retry: handleRetry,
1925
- redirect
1926
- });
1927
- };
1928
- //#endregion
1929
1849
  //#region src/use-criipto-verify.ts
1930
1850
  function useCriiptoVerify() {
1931
1851
  const { result, claims, loginWithRedirect, loginWithPopup, acrValues, isLoading, isInitializing, logout, checkSession } = useContext(CriiptoVerifyContext);
@@ -1943,6 +1863,6 @@ function useCriiptoVerify() {
1943
1863
  };
1944
1864
  }
1945
1865
  //#endregion
1946
- export { AuthMethodButtonContainer as AuthButton, AuthMethodButtonContainer as AuthMethodButton, AuthMethodButtonComponent as AuthButtonComponent, AuthButtonGroup, AuthMethodSelector, Sweden as AuthMethodSelectorSweden, CriiptoVerifyProvider, OAuth2Error, QRCode, SEBankIDQrCode as SEBankIDQRCode, actions, filterAcrValues, useCriiptoVerify };
1866
+ export { AuthMethodButtonContainer as AuthButton, AuthMethodButtonContainer as AuthMethodButton, AuthMethodButtonComponent as AuthButtonComponent, AuthButtonGroup, AuthMethodSelector, Sweden as AuthMethodSelectorSweden, CriiptoVerifyProvider, OAuth2Error, SEBankIDQrCode as SEBankIDQRCode, actions, filterAcrValues, useCriiptoVerify };
1947
1867
 
1948
1868
  //# sourceMappingURL=index.js.map