@thunderid/react 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ThunderIDReactClient.d.ts +5 -0
- package/dist/ThunderIDReactClient.d.ts.map +1 -1
- package/dist/ThunderIDReactClient.js +11 -1
- package/dist/ThunderIDReactClient.js.map +1 -1
- package/dist/cjs/ThunderIDReactClient.cjs +11 -1
- package/dist/cjs/ThunderIDReactClient.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs +1 -0
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs +2 -3
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs +1 -0
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs.map +1 -1
- package/dist/cjs/components/primitives/AffixedField/AffixedField.cjs +11 -1
- package/dist/cjs/components/primitives/AffixedField/AffixedField.cjs.map +1 -1
- package/dist/cjs/components/primitives/Checkbox/Checkbox.cjs +11 -1
- package/dist/cjs/components/primitives/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/primitives/DatePicker/DatePicker.cjs +11 -1
- package/dist/cjs/components/primitives/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/cjs/components/primitives/FormControl/FormControl.cjs +2 -1
- package/dist/cjs/components/primitives/FormControl/FormControl.cjs.map +1 -1
- package/dist/cjs/components/primitives/MultiInput/MultiInput.cjs +11 -2
- package/dist/cjs/components/primitives/MultiInput/MultiInput.cjs.map +1 -1
- package/dist/cjs/components/primitives/OtpField/OtpField.cjs +9 -0
- package/dist/cjs/components/primitives/OtpField/OtpField.cjs.map +1 -1
- package/dist/cjs/components/primitives/Select/Select.cjs +8 -0
- package/dist/cjs/components/primitives/Select/Select.cjs.map +1 -1
- package/dist/cjs/components/primitives/TextField/TextField.cjs +11 -1
- package/dist/cjs/components/primitives/TextField/TextField.cjs.map +1 -1
- package/dist/cjs/components/primitives/Toggle/Toggle.cjs +10 -1
- package/dist/cjs/components/primitives/Toggle/Toggle.cjs.map +1 -1
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs +1 -1
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +6 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts +4 -0
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js +1 -0
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.js +2 -3
- package/dist/components/presentation/auth/SignIn/SignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts +4 -0
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js +1 -0
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js.map +1 -1
- package/dist/components/primitives/AffixedField/AffixedField.d.ts.map +1 -1
- package/dist/components/primitives/AffixedField/AffixedField.js +11 -1
- package/dist/components/primitives/AffixedField/AffixedField.js.map +1 -1
- package/dist/components/primitives/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/primitives/Checkbox/Checkbox.js +10 -1
- package/dist/components/primitives/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/primitives/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/primitives/DatePicker/DatePicker.js +10 -1
- package/dist/components/primitives/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/primitives/FormControl/FormControl.d.ts +4 -0
- package/dist/components/primitives/FormControl/FormControl.d.ts.map +1 -1
- package/dist/components/primitives/FormControl/FormControl.js +2 -1
- package/dist/components/primitives/FormControl/FormControl.js.map +1 -1
- package/dist/components/primitives/MultiInput/MultiInput.d.ts.map +1 -1
- package/dist/components/primitives/MultiInput/MultiInput.js +12 -3
- package/dist/components/primitives/MultiInput/MultiInput.js.map +1 -1
- package/dist/components/primitives/OtpField/OtpField.d.ts.map +1 -1
- package/dist/components/primitives/OtpField/OtpField.js +10 -1
- package/dist/components/primitives/OtpField/OtpField.js.map +1 -1
- package/dist/components/primitives/Select/Select.d.ts.map +1 -1
- package/dist/components/primitives/Select/Select.js +9 -1
- package/dist/components/primitives/Select/Select.js.map +1 -1
- package/dist/components/primitives/TextField/TextField.d.ts.map +1 -1
- package/dist/components/primitives/TextField/TextField.js +10 -1
- package/dist/components/primitives/TextField/TextField.js.map +1 -1
- package/dist/components/primitives/Toggle/Toggle.d.ts.map +1 -1
- package/dist/components/primitives/Toggle/Toggle.js +9 -1
- package/dist/components/primitives/Toggle/Toggle.js.map +1 -1
- package/dist/contexts/Theme/ThemeProvider.d.ts.map +1 -1
- package/dist/contexts/Theme/ThemeProvider.js +1 -1
- package/dist/contexts/Theme/ThemeProvider.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts +4 -3
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.js +6 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
- package/package.json +4 -4
|
@@ -6,6 +6,8 @@ const require_FormControl = require('../FormControl/FormControl.cjs');
|
|
|
6
6
|
const require_InputLabel = require('../InputLabel/InputLabel.cjs');
|
|
7
7
|
let __thunderid_browser = require("@thunderid/browser");
|
|
8
8
|
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
9
|
+
let react = require("react");
|
|
10
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
9
11
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
12
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
11
13
|
|
|
@@ -23,10 +25,15 @@ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
|
23
25
|
const Toggle = ({ label, error, className, required, helperText, style = {},...rest }) => {
|
|
24
26
|
const { theme, colorScheme } = require_useTheme.default();
|
|
25
27
|
const hasError = !!error;
|
|
28
|
+
const generatedId = (0, react.useId)();
|
|
29
|
+
const inputId = rest.id ?? generatedId;
|
|
30
|
+
const helperTextId = error || helperText ? `${inputId}-helper-text` : void 0;
|
|
31
|
+
const describedBy = [rest["aria-describedby"], helperTextId].filter(Boolean).join(" ") || void 0;
|
|
26
32
|
const styles = require_Toggle_styles.default(theme, colorScheme, hasError, !!required);
|
|
27
33
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FormControl.default, {
|
|
28
34
|
error,
|
|
29
35
|
helperText,
|
|
36
|
+
helperTextId,
|
|
30
37
|
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("toggle")), className),
|
|
31
38
|
helperTextMarginLeft: `calc(${theme.vars.spacing.unit} * 5.5)`,
|
|
32
39
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
@@ -39,7 +46,9 @@ const Toggle = ({ label, error, className, required, helperText, style = {},...r
|
|
|
39
46
|
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("toggle", "input")), styles["input"]),
|
|
40
47
|
"aria-invalid": hasError,
|
|
41
48
|
"aria-required": required,
|
|
42
|
-
...rest
|
|
49
|
+
...rest,
|
|
50
|
+
id: inputId,
|
|
51
|
+
"aria-describedby": describedBy
|
|
43
52
|
}),
|
|
44
53
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
45
54
|
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("toggle", "track")), styles["track"]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toggle.cjs","names":["Toggle: FC<ToggleProps>","useTheme","styles: Record<string, string>","useStyles","FormControl","cx","InputLabel"],"sources":["../../../../../src/components/primitives/Toggle/Toggle.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {FC, InputHTMLAttributes} from 'react';\nimport useStyles from './Toggle.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\n/**\n * Props for the Toggle component.\n */\nexport interface ToggleProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'type'> {\n className?: string;\n error?: string;\n helperText?: string;\n label?: string;\n required?: boolean;\n}\n\n/**\n * A Toggle component that represents a boolean input. It is built on top of a hidden checkbox input\n * and styled to look like a switch.\n *\n * The component is wrapped in a FormControl to display error messages and helper text.\n * The label is associated with the input for accessibility.\n *\n * @param props - Props for the Toggle component\n * @returns A JSX element representing the Toggle\n */\nconst Toggle: FC<ToggleProps> = ({label, error, className, required, helperText, style = {}, ...rest}: ToggleProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const hasError = !!error;\n const styles: Record<string, string> = useStyles(theme, colorScheme, hasError, !!required);\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n className={cx(withVendorCSSClassPrefix(bem('toggle')), className)}\n helperTextMarginLeft={`calc(${theme.vars.spacing.unit} * 5.5)`}\n >\n <label style={style} className={cx(withVendorCSSClassPrefix(bem('toggle', 'container')), styles['container'])}>\n <input\n type=\"checkbox\"\n role=\"switch\"\n className={cx(withVendorCSSClassPrefix(bem('toggle', 'input')), styles['input'])}\n aria-invalid={hasError}\n aria-required={required}\n {...rest}\n />\n <div className={cx(withVendorCSSClassPrefix(bem('toggle', 'track')), styles['track'])}>\n <span className={cx(withVendorCSSClassPrefix(bem('toggle', 'thumb')), styles['thumb'])} />\n </div>\n {label && (\n <InputLabel\n required={required}\n error={hasError}\n variant=\"inline\"\n className={cx(withVendorCSSClassPrefix(bem('toggle', 'label')), styles['label'], styles['errorLabel'], {\n [withVendorCSSClassPrefix(bem('toggle', 'label', 'error'))]: hasError,\n })}\n >\n {label}\n </InputLabel>\n )}\n </label>\n </FormControl>\n );\n};\n\nexport default Toggle;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toggle.cjs","names":["Toggle: FC<ToggleProps>","useTheme","generatedId: string","inputId: string","helperTextId: string | undefined","describedBy: string | undefined","styles: Record<string, string>","useStyles","FormControl","cx","InputLabel"],"sources":["../../../../../src/components/primitives/Toggle/Toggle.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {FC, InputHTMLAttributes, useId} from 'react';\nimport useStyles from './Toggle.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\n/**\n * Props for the Toggle component.\n */\nexport interface ToggleProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'type'> {\n className?: string;\n error?: string;\n helperText?: string;\n label?: string;\n required?: boolean;\n}\n\n/**\n * A Toggle component that represents a boolean input. It is built on top of a hidden checkbox input\n * and styled to look like a switch.\n *\n * The component is wrapped in a FormControl to display error messages and helper text.\n * The label is associated with the input for accessibility.\n *\n * @param props - Props for the Toggle component\n * @returns A JSX element representing the Toggle\n */\nconst Toggle: FC<ToggleProps> = ({label, error, className, required, helperText, style = {}, ...rest}: ToggleProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const hasError = !!error;\n const generatedId: string = useId();\n const inputId: string = rest.id ?? generatedId;\n const helperTextId: string | undefined = error || helperText ? `${inputId}-helper-text` : undefined;\n const describedBy: string | undefined =\n [rest['aria-describedby'], helperTextId].filter(Boolean).join(' ') || undefined;\n const styles: Record<string, string> = useStyles(theme, colorScheme, hasError, !!required);\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n helperTextId={helperTextId}\n className={cx(withVendorCSSClassPrefix(bem('toggle')), className)}\n helperTextMarginLeft={`calc(${theme.vars.spacing.unit} * 5.5)`}\n >\n <label style={style} className={cx(withVendorCSSClassPrefix(bem('toggle', 'container')), styles['container'])}>\n <input\n type=\"checkbox\"\n role=\"switch\"\n className={cx(withVendorCSSClassPrefix(bem('toggle', 'input')), styles['input'])}\n aria-invalid={hasError}\n aria-required={required}\n {...rest}\n id={inputId}\n aria-describedby={describedBy}\n />\n <div className={cx(withVendorCSSClassPrefix(bem('toggle', 'track')), styles['track'])}>\n <span className={cx(withVendorCSSClassPrefix(bem('toggle', 'thumb')), styles['thumb'])} />\n </div>\n {label && (\n <InputLabel\n required={required}\n error={hasError}\n variant=\"inline\"\n className={cx(withVendorCSSClassPrefix(bem('toggle', 'label')), styles['label'], styles['errorLabel'], {\n [withVendorCSSClassPrefix(bem('toggle', 'label', 'error'))]: hasError,\n })}\n >\n {label}\n </InputLabel>\n )}\n </label>\n </FormControl>\n );\n};\n\nexport default Toggle;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAMA,UAA2B,EAAC,OAAO,OAAO,WAAW,UAAU,YAAY,QAAQ,EAAE,CAAE,GAAG,WAAuB;CACrH,MAAM,EAAC,OAAO,gBAA4CC,0BAAU;CACpE,MAAM,WAAW,CAAC,CAAC;CACnB,MAAMC,gCAA6B;CACnC,MAAMC,UAAkB,KAAK,MAAM;CACnC,MAAMC,eAAmC,SAAS,aAAa,GAAG,QAAQ,gBAAgB;CAC1F,MAAMC,cACJ,CAAC,KAAK,qBAAqB,aAAa,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;CACxE,MAAMC,SAAiCC,8BAAU,OAAO,aAAa,UAAU,CAAC,CAAC,SAAS;AAE1F,QACE,2CAACC;EACQ;EACK;EACE;EACd,WAAWC,kGAAgC,SAAS,CAAC,EAAE,UAAU;EACjE,sBAAsB,QAAQ,MAAM,KAAK,QAAQ,KAAK;YAEtD,4CAAC;GAAa;GAAO,WAAWA,kGAAgC,UAAU,YAAY,CAAC,EAAE,OAAO,aAAa;;IAC3G,2CAAC;KACC,MAAK;KACL,MAAK;KACL,WAAWA,kGAAgC,UAAU,QAAQ,CAAC,EAAE,OAAO,SAAS;KAChF,gBAAc;KACd,iBAAe;KACf,GAAI;KACJ,IAAI;KACJ,oBAAkB;MAClB;IACF,2CAAC;KAAI,WAAWA,kGAAgC,UAAU,QAAQ,CAAC,EAAE,OAAO,SAAS;eACnF,2CAAC,UAAK,WAAWA,kGAAgC,UAAU,QAAQ,CAAC,EAAE,OAAO,SAAS,GAAI;MACtF;IACL,SACC,2CAACC;KACW;KACV,OAAO;KACP,SAAQ;KACR,WAAWD,kGAAgC,UAAU,QAAQ,CAAC,EAAE,OAAO,UAAU,OAAO,eAAe,kFACvE,UAAU,SAAS,QAAQ,CAAC,GAAG,UAC9D,CAAC;eAED;MACU;;IAET;GACI;;AAIlB,qBAAe"}
|
|
@@ -70,7 +70,7 @@ const ThemeProvider = ({ children, mode, theme: themeOverrideProp }) => {
|
|
|
70
70
|
}
|
|
71
71
|
const mediaQuery = (0, __thunderid_browser.createMediaQueryListener)(handleThemeChange);
|
|
72
72
|
return () => {
|
|
73
|
-
|
|
73
|
+
mediaQuery?.disconnect();
|
|
74
74
|
};
|
|
75
75
|
}, [mode]);
|
|
76
76
|
const toggleTheme = (0, react.useCallback)(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeProvider.cjs","names":["ThemeProvider: FC<PropsWithChildren<ThemeProviderProps>>","themeOverride: RecursivePartial<ThemeConfig> | undefined","normalizeThemeConfig","flowMetaContext: FlowMetaContextValue | null","FlowMetaContext","flowMetaTheme: FlowMetaTheme | null","toggleTheme: () => void","finalThemeConfig: RecursivePartial<ThemeConfig> | undefined","metaConfig: RecursivePartial<ThemeConfig>","buildThemeConfigFromFlowMeta","theme: Theme","direction: 'ltr' | 'rtl'","value: any","ThemeContext"],"sources":["../../../../src/contexts/Theme/ThemeProvider.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n createClassObserver,\n createMediaQueryListener,\n createTheme,\n detectThemeMode,\n FlowMetaTheme,\n RecursivePartial,\n Theme,\n ThemeConfig,\n ThemeMode,\n} from '@thunderid/browser';\nimport {FC, PropsWithChildren, ReactElement, useCallback, useContext, useEffect, useMemo, useState} from 'react';\nimport ThemeContext from './ThemeContext';\nimport applyThemeToDOM from '../../utils/applyThemeToDOM';\nimport buildThemeConfigFromFlowMeta from '../../utils/buildThemeConfigFromFlowMeta';\nimport normalizeThemeConfig from '../../utils/normalizeThemeConfig';\nimport FlowMetaContext, {FlowMetaContextValue} from '../FlowMeta/FlowMetaContext';\n\nexport interface ThemeProviderProps {\n /**\n * Initial color scheme override. Overrides the server default when provided.\n */\n mode?: ThemeMode;\n\n /**\n * Optional theme overrides merged on top of the server-side flow meta theme.\n * User-supplied values take highest precedence.\n */\n theme?: RecursivePartial<ThemeConfig>;\n}\n\n/**\n * ThemeProvider is the v2 drop-in replacement for `ThemeProvider`.\n *\n * It reads the design theme from the nearest `FlowMetaContext` (provided by\n * `FlowMetaProvider`) and publishes a resolved `Theme` object through the\n * **same** `ThemeContext` that `useTheme` consumes. This means all existing\n * components that call `useTheme` continue to work without any changes.\n *\n * The `defaultColorScheme` field returned by the server is used to seed the\n * active color scheme; the user can still toggle it locally via the\n * `toggleTheme` value exposed in the context.\n *\n * @example\n * ```tsx\n * <FlowMetaProvider config={{ baseUrl, type: FlowMetaType.App, id: appId }}>\n * <ThemeProvider>\n * <App /> {/* useTheme() works here as usual *\\/}\n * </ThemeProvider>\n * </FlowMetaProvider>\n * ```\n *\n * @example\n * With user theme overrides (user values win over server values):\n * ```tsx\n * <ThemeProvider theme={{ colors: { primary: { main: '#ff0000' } } }}>\n * <App />\n * </ThemeProvider>\n * ```\n */\nconst ThemeProvider: FC<PropsWithChildren<ThemeProviderProps>> = ({\n children,\n mode,\n theme: themeOverrideProp,\n}: PropsWithChildren<ThemeProviderProps>): ReactElement => {\n const themeOverride: RecursivePartial<ThemeConfig> | undefined = normalizeThemeConfig(themeOverrideProp);\n const flowMetaContext: FlowMetaContextValue | null = useContext(FlowMetaContext);\n\n const flowMetaTheme: FlowMetaTheme | null = flowMetaContext?.meta?.design?.theme ?? null;\n const isLoading: boolean = flowMetaContext?.isLoading ?? false;\n const error: Error | null = flowMetaContext?.error ?? null;\n\n // Seed the color scheme: a fixed mode wins outright, 'system'/'class' detect it from the\n // environment via the same shared utilities Vue's ThemeProvider uses, and no mode falls back\n // to the server's default (unchanged pre-`mode` behavior).\n const getInitialColorScheme = (): 'light' | 'dark' => {\n if (mode === 'light' || mode === 'dark') return mode;\n if (mode === 'system' || mode === 'class') return detectThemeMode(mode);\n return flowMetaTheme?.defaultColorScheme ?? 'light';\n };\n\n const [colorScheme, setColorScheme] = useState<'light' | 'dark'>(getInitialColorScheme);\n\n // When mode is unset, sync the color scheme with the server default once flow meta loads.\n useEffect(() => {\n if (mode === undefined && flowMetaTheme?.defaultColorScheme) {\n setColorScheme(flowMetaTheme.defaultColorScheme);\n }\n }, [mode, flowMetaTheme?.defaultColorScheme]);\n\n // Set up automatic detection listeners for 'system'/'class' modes.\n useEffect(() => {\n if (mode !== 'system' && mode !== 'class') return undefined;\n\n const handleThemeChange = (isDark: boolean): void => {\n setColorScheme(isDark ? 'dark' : 'light');\n };\n\n if (mode === 'class') {\n if (typeof document === 'undefined') return undefined;\n const observer = createClassObserver(document.documentElement, handleThemeChange);\n return () => {\n observer.disconnect();\n };\n }\n\n const mediaQuery = createMediaQueryListener(handleThemeChange);\n return () => {\n
|
|
1
|
+
{"version":3,"file":"ThemeProvider.cjs","names":["ThemeProvider: FC<PropsWithChildren<ThemeProviderProps>>","themeOverride: RecursivePartial<ThemeConfig> | undefined","normalizeThemeConfig","flowMetaContext: FlowMetaContextValue | null","FlowMetaContext","flowMetaTheme: FlowMetaTheme | null","toggleTheme: () => void","finalThemeConfig: RecursivePartial<ThemeConfig> | undefined","metaConfig: RecursivePartial<ThemeConfig>","buildThemeConfigFromFlowMeta","theme: Theme","direction: 'ltr' | 'rtl'","value: any","ThemeContext"],"sources":["../../../../src/contexts/Theme/ThemeProvider.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n createClassObserver,\n createMediaQueryListener,\n createTheme,\n detectThemeMode,\n FlowMetaTheme,\n RecursivePartial,\n Theme,\n ThemeConfig,\n ThemeMode,\n} from '@thunderid/browser';\nimport {FC, PropsWithChildren, ReactElement, useCallback, useContext, useEffect, useMemo, useState} from 'react';\nimport ThemeContext from './ThemeContext';\nimport applyThemeToDOM from '../../utils/applyThemeToDOM';\nimport buildThemeConfigFromFlowMeta from '../../utils/buildThemeConfigFromFlowMeta';\nimport normalizeThemeConfig from '../../utils/normalizeThemeConfig';\nimport FlowMetaContext, {FlowMetaContextValue} from '../FlowMeta/FlowMetaContext';\n\nexport interface ThemeProviderProps {\n /**\n * Initial color scheme override. Overrides the server default when provided.\n */\n mode?: ThemeMode;\n\n /**\n * Optional theme overrides merged on top of the server-side flow meta theme.\n * User-supplied values take highest precedence.\n */\n theme?: RecursivePartial<ThemeConfig>;\n}\n\n/**\n * ThemeProvider is the v2 drop-in replacement for `ThemeProvider`.\n *\n * It reads the design theme from the nearest `FlowMetaContext` (provided by\n * `FlowMetaProvider`) and publishes a resolved `Theme` object through the\n * **same** `ThemeContext` that `useTheme` consumes. This means all existing\n * components that call `useTheme` continue to work without any changes.\n *\n * The `defaultColorScheme` field returned by the server is used to seed the\n * active color scheme; the user can still toggle it locally via the\n * `toggleTheme` value exposed in the context.\n *\n * @example\n * ```tsx\n * <FlowMetaProvider config={{ baseUrl, type: FlowMetaType.App, id: appId }}>\n * <ThemeProvider>\n * <App /> {/* useTheme() works here as usual *\\/}\n * </ThemeProvider>\n * </FlowMetaProvider>\n * ```\n *\n * @example\n * With user theme overrides (user values win over server values):\n * ```tsx\n * <ThemeProvider theme={{ colors: { primary: { main: '#ff0000' } } }}>\n * <App />\n * </ThemeProvider>\n * ```\n */\nconst ThemeProvider: FC<PropsWithChildren<ThemeProviderProps>> = ({\n children,\n mode,\n theme: themeOverrideProp,\n}: PropsWithChildren<ThemeProviderProps>): ReactElement => {\n const themeOverride: RecursivePartial<ThemeConfig> | undefined = normalizeThemeConfig(themeOverrideProp);\n const flowMetaContext: FlowMetaContextValue | null = useContext(FlowMetaContext);\n\n const flowMetaTheme: FlowMetaTheme | null = flowMetaContext?.meta?.design?.theme ?? null;\n const isLoading: boolean = flowMetaContext?.isLoading ?? false;\n const error: Error | null = flowMetaContext?.error ?? null;\n\n // Seed the color scheme: a fixed mode wins outright, 'system'/'class' detect it from the\n // environment via the same shared utilities Vue's ThemeProvider uses, and no mode falls back\n // to the server's default (unchanged pre-`mode` behavior).\n const getInitialColorScheme = (): 'light' | 'dark' => {\n if (mode === 'light' || mode === 'dark') return mode;\n if (mode === 'system' || mode === 'class') return detectThemeMode(mode);\n return flowMetaTheme?.defaultColorScheme ?? 'light';\n };\n\n const [colorScheme, setColorScheme] = useState<'light' | 'dark'>(getInitialColorScheme);\n\n // When mode is unset, sync the color scheme with the server default once flow meta loads.\n useEffect(() => {\n if (mode === undefined && flowMetaTheme?.defaultColorScheme) {\n setColorScheme(flowMetaTheme.defaultColorScheme);\n }\n }, [mode, flowMetaTheme?.defaultColorScheme]);\n\n // Set up automatic detection listeners for 'system'/'class' modes.\n useEffect(() => {\n if (mode !== 'system' && mode !== 'class') return undefined;\n\n const handleThemeChange = (isDark: boolean): void => {\n setColorScheme(isDark ? 'dark' : 'light');\n };\n\n if (mode === 'class') {\n if (typeof document === 'undefined') return undefined;\n const observer = createClassObserver(document.documentElement, handleThemeChange);\n return () => {\n observer.disconnect();\n };\n }\n\n const mediaQuery = createMediaQueryListener(handleThemeChange);\n return () => {\n mediaQuery?.disconnect();\n };\n }, [mode]);\n\n const toggleTheme: () => void = useCallback(() => {\n setColorScheme((prev: 'light' | 'dark') => (prev === 'light' ? 'dark' : 'light'));\n }, []);\n\n // Build the resolved ThemeConfig: flow meta base → user overrides on top.\n const finalThemeConfig: RecursivePartial<ThemeConfig> | undefined = useMemo(() => {\n if (!flowMetaTheme) {\n return themeOverride;\n }\n\n const metaConfig: RecursivePartial<ThemeConfig> = buildThemeConfigFromFlowMeta(flowMetaTheme, colorScheme);\n\n if (!themeOverride) {\n return metaConfig;\n }\n\n return {\n ...metaConfig,\n ...themeOverride,\n borderRadius: {\n ...metaConfig.borderRadius,\n ...themeOverride.borderRadius,\n },\n colors: {\n ...metaConfig.colors,\n ...themeOverride.colors,\n },\n ...(metaConfig.typography || themeOverride.typography\n ? {\n typography: {\n ...(metaConfig as any).typography,\n ...themeOverride.typography,\n },\n }\n : {}),\n };\n }, [flowMetaTheme, colorScheme, themeOverride]);\n\n const theme: Theme = useMemo(\n () => createTheme(finalThemeConfig, colorScheme === 'dark'),\n [finalThemeConfig, colorScheme],\n );\n\n const direction: 'ltr' | 'rtl' = flowMetaTheme?.direction ?? 'ltr';\n\n // Apply CSS variables to the document root.\n useEffect(() => {\n applyThemeToDOM(theme);\n }, [theme]);\n\n // Apply text direction to the document root.\n useEffect(() => {\n if (typeof document !== 'undefined') {\n document.documentElement.dir = direction;\n }\n }, [direction]);\n\n const value: any = {\n colorScheme,\n direction,\n theme,\n toggleTheme,\n };\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n};\n\nexport default ThemeProvider;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,MAAMA,iBAA4D,EAChE,UACA,MACA,OAAO,wBACkD;CACzD,MAAMC,gBAA2DC,qCAAqB,kBAAkB;CACxG,MAAMC,wCAA0DC,gCAAgB;CAEhF,MAAMC,gBAAsC,iBAAiB,MAAM,QAAQ,SAAS;AACzD,kBAAiB;AAChB,kBAAiB;CAK7C,MAAM,8BAAgD;AACpD,MAAI,SAAS,WAAW,SAAS,OAAQ,QAAO;AAChD,MAAI,SAAS,YAAY,SAAS,QAAS,iDAAuB,KAAK;AACvE,SAAO,eAAe,sBAAsB;;CAG9C,MAAM,CAAC,aAAa,sCAA6C,sBAAsB;AAGvF,4BAAgB;AACd,MAAI,SAAS,UAAa,eAAe,mBACvC,gBAAe,cAAc,mBAAmB;IAEjD,CAAC,MAAM,eAAe,mBAAmB,CAAC;AAG7C,4BAAgB;AACd,MAAI,SAAS,YAAY,SAAS,QAAS,QAAO;EAElD,MAAM,qBAAqB,WAA0B;AACnD,kBAAe,SAAS,SAAS,QAAQ;;AAG3C,MAAI,SAAS,SAAS;AACpB,OAAI,OAAO,aAAa,YAAa,QAAO;GAC5C,MAAM,wDAA+B,SAAS,iBAAiB,kBAAkB;AACjF,gBAAa;AACX,aAAS,YAAY;;;EAIzB,MAAM,+DAAsC,kBAAkB;AAC9D,eAAa;AACX,eAAY,YAAY;;IAEzB,CAAC,KAAK,CAAC;CAEV,MAAMC,2CAA4C;AAChD,kBAAgB,SAA4B,SAAS,UAAU,SAAS,QAAS;IAChF,EAAE,CAAC;CAGN,MAAMC,4CAA4E;AAChF,MAAI,CAAC,cACH,QAAO;EAGT,MAAMC,aAA4CC,6CAA6B,eAAe,YAAY;AAE1G,MAAI,CAAC,cACH,QAAO;AAGT,SAAO;GACL,GAAG;GACH,GAAG;GACH,cAAc;IACZ,GAAG,WAAW;IACd,GAAG,cAAc;IAClB;GACD,QAAQ;IACN,GAAG,WAAW;IACd,GAAG,cAAc;IAClB;GACD,GAAI,WAAW,cAAc,cAAc,aACvC,EACE,YAAY;IACV,GAAI,WAAmB;IACvB,GAAG,cAAc;IAClB,EACF,GACD,EAAE;GACP;IACA;EAAC;EAAe;EAAa;EAAc,CAAC;CAE/C,MAAMC,sEACc,kBAAkB,gBAAgB,OAAO,EAC3D,CAAC,kBAAkB,YAAY,CAChC;CAED,MAAMC,YAA2B,eAAe,aAAa;AAG7D,4BAAgB;AACd,kCAAgB,MAAM;IACrB,CAAC,MAAM,CAAC;AAGX,4BAAgB;AACd,MAAI,OAAO,aAAa,YACtB,UAAS,gBAAgB,MAAM;IAEhC,CAAC,UAAU,CAAC;CAEf,MAAMC,QAAa;EACjB;EACA;EACA;EACA;EACD;AAED,QAAO,2CAACC,6BAAa;EAAgB;EAAQ;GAAiC;;AAGhF,4BAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDContext.cjs","names":["ThunderIDContext: Context<ThunderIDContextProps | null>","fallbackResourceInvalidator","VendorConstants"],"sources":["../../../../src/contexts/ThunderID/ThunderIDContext.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ApiFetcher,\n FlowMetadataResponse,\n HttpRequestConfig,\n HttpResponse,\n IdToken,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n TokenExchangeRequestConfig,\n TokenResponse,\n VendorConstants,\n AttributeSchema,\n} from '@thunderid/browser';\nimport {Context, createContext} from 'react';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport {ResourceInvalidator, fallbackResourceInvalidator} from '../../utils/createResourceInvalidator';\n\n/**\n * Props interface of {@link ThunderIDContext}\n */\nexport type ThunderIDContextProps = {\n afterSignInUrl: string | undefined;\n applicationId: string | undefined;\n baseUrl: string | undefined;\n clientId: string | undefined;\n /**\n * Optional endpoint URL overrides from the client config. Used to resolve resource-server\n * endpoints (e.g. flow/user-management) independently of `baseUrl` — see `resolveResourceEndpoint`.\n */\n endpoints?: ThunderIDReactConfig['endpoints'];\n preferences?: ThunderIDReactConfig['preferences'];\n scopes: string | string[] | undefined;\n /**\n * OIDC discovery data.\n */\n discovery: {\n /**\n * The response from the `.well-known/openid-configuration` endpoint.\n * Contains server capabilities, supported endpoints, and metadata.\n * `null` while loading or when discovery has not been fetched.\n */\n wellKnown: OIDCDiscoveryApiResponse | null;\n };\n /**\n * Swaps the current access token with a new one based on the provided configuration (with a grant type).\n * @param config - Configuration for the token exchange request.\n * @returns A promise that resolves to the token response or the raw response.\n */\n exchangeToken: (config: TokenExchangeRequestConfig) => Promise<TokenResponse | Response>;\n /**\n * Retrieves the access token stored in the storage.\n * This function retrieves the access token and returns it.\n * @remarks This does not work in the `webWorker` or any other worker environment.\n * @returns A promise that resolves to the access token.\n */\n getAccessToken: () => Promise<string>;\n /**\n * Function to retrieve the decoded ID token.\n * This function decodes the ID token and returns its payload.\n * It can be used to access user claims and other information contained in the ID token.\n *\n * @returns A promise that resolves to the decoded ID token payload.\n */\n getDecodedIdToken: () => Promise<IdToken>;\n /**\n * Function to retrieve the ID token.\n * This function retrieves the ID token and returns it.\n *\n * @returns A promise that resolves to the ID token.\n */\n getIdToken: () => Promise<string>;\n /**\n * Returns the underlying StorageManager instance for reading and writing SDK-managed storage.\n */\n getStorageManager: () => Promise<any>;\n /**\n * HTTP request function to make API calls.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n http: {\n /**\n * Transport supplied through `ThunderIDProvider`'s `http.fetcher` prop, used by the management\n * hooks. `undefined` means the hooks fall back to the SDK's authenticated HTTP client.\n */\n fetcher?: ApiFetcher;\n /**\n * Makes an HTTP request using the provided configuration.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n request: (requestConfig?: HttpRequestConfig) => Promise<HttpResponse<any>>;\n /**\n * Makes multiple HTTP requests based on the provided configuration.\n * @param requestConfigs - Set of configurations for the HTTP requests.\n * @returns A promise that resolves to an array of HTTP responses.\n */\n requestAll: (requestConfigs?: HttpRequestConfig[]) => Promise<HttpResponse<any>[]>;\n };\n /**\n * Coordinates refetching between the management hooks: a successful mutation invalidates the\n * queries whose data it changed.\n */\n invalidator?: ResourceInvalidator;\n /**\n * Instance ID for multi-instance support.\n */\n instanceId: number;\n isInitialized: boolean;\n /**\n * Flag indicating whether the SDK is working in the background.\n */\n isLoading: boolean;\n /**\n * Flag indicating whether flow metadata is currently being fetched.\n */\n isMetaLoading: boolean;\n /**\n * Flag indicating whether the user is signed in or not.\n */\n isSignedIn: boolean;\n\n /**\n * Flow metadata returned by `GET /flow/meta` (v2 platform only).\n * `null` while loading or when `resolveFromMeta` is disabled.\n */\n meta: FlowMetadataResponse | null;\n\n organizationHandle: string | undefined;\n\n /**\n * Re-initializes the client with a new configuration.\n *\n * @remarks\n * This can be partial configuration to update only specific fields.\n *\n * @param config - New configuration to re-initialize the client with.\n * @returns Promise resolving to boolean indicating success.\n */\n reInitialize: (config: Partial<ThunderIDReactConfig>) => Promise<boolean>;\n\n /**\n * Recovery function to initiate the account/password recovery flow.\n */\n recover: (...args: any[]) => Promise<any>;\n\n /**\n * Resolves `{{ t(key) }}` and `{{ meta(path) }}` template expressions in a string,\n * using the current i18n translation function and flow metadata from context.\n *\n * Useful in render-props patterns where consumers need to expand template strings\n * that come from the server (e.g. component labels, placeholders, headings).\n *\n * @example\n * const {resolveFlowTemplateLiterals} = useThunderID();\n * resolveFlowTemplateLiterals('{{ t(signin.heading.label) }}') // → 'Sign In'\n * resolveFlowTemplateLiterals('Login to {{ meta(application.name) }}') // → 'Login to My App'\n */\n resolveFlowTemplateLiterals: (text: string | undefined) => string;\n\n /**\n * Sign-in function to initiate the authentication process.\n * @remark This is the programmatic version of the `SignInButton` component.\n * TODO: Fix the types.\n */\n signIn: (...args: any) => Promise<any>;\n\n /**\n * Optional additional parameters to be sent in the sign-in request.\n * This can include custom parameters that your authorization server supports.\n * These parameters will be included in the authorization request sent to the server.\n * If not provided, no additional parameters will be sent.\n *\n * @example\n * signInOptions: { prompt: \"login\", fidp: \"OrganizationSSO\" }\n */\n signInOptions?: SignInOptions;\n\n /**\n * Optional token request configuration. params are appended to the token endpoint POST body.\n *\n * @example\n * tokenRequest: { params: { resource: \"https://api.example.com\" } }\n */\n tokenRequest?: {\n params?: Record<string, unknown>;\n };\n\n /**\n * Silent sign-in function to re-authenticate the user without user interaction.\n * @remark This is the programmatic version of the `SilentSignIn` component.\n */\n signInSilently: ThunderIDReactClient['signInSilently'];\n\n signInUrl: string | undefined;\n /**\n * Sign-out function to terminate the authentication session.\n * @remark This is the programmatic version of the `SignOutButton` component.\n * FIXME: Fix the types.\n */\n signOut: any;\n\n /**\n * Sign-up function to initiate the registration process.\n * @remark This is the programmatic version of the `SignUpButton` component.\n */\n signUp: (...args: any[]) => Promise<any>;\n\n signUpUrl: string | undefined;\n\n user: any;\n\n /**\n * Schema metadata for the user type returned by GET /users/me/meta.\n */\n userSchema: Record<string, AttributeSchema> | null;\n\n /**\n * Vendor/brand namespace used to prefix storage keys, cookie names, and CSS class names.\n * Resolved from the `vendor` config option, defaulting to `'thunderid'`.\n */\n vendor: string;\n} & Pick<ThunderIDReactClient, 'clearSession'>;\n\n/**\n * Context object for managing the Authentication flow builder core context.\n */\nconst ThunderIDContext: Context<ThunderIDContextProps | null> = createContext<null | ThunderIDContextProps>({\n afterSignInUrl: undefined,\n applicationId: undefined,\n baseUrl: undefined,\n clearSession: () => {},\n clientId: undefined,\n preferences: undefined,\n scopes: undefined,\n discovery: {\n wellKnown: null,\n },\n exchangeToken: null as unknown as ThunderIDContextProps['exchangeToken'],\n getAccessToken: null as unknown as ThunderIDContextProps['getAccessToken'],\n getDecodedIdToken: null as unknown as ThunderIDContextProps['getDecodedIdToken'],\n getIdToken: null as unknown as ThunderIDContextProps['getIdToken'],\n getStorageManager: () => Promise.resolve(null),\n http: {\n request: () => null as unknown as Promise<HttpResponse<any>>,\n requestAll: () => null as unknown as Promise<HttpResponse<any>[]>,\n },\n instanceId: 0,\n invalidator: fallbackResourceInvalidator,\n isInitialized: false,\n isLoading: true,\n isMetaLoading: false,\n isSignedIn: false,\n meta: null,\n organizationHandle: undefined,\n reInitialize: null as unknown as ThunderIDContextProps['reInitialize'],\n recover: () => Promise.resolve({} as any),\n resolveFlowTemplateLiterals: (text: string | undefined) => text ?? '',\n signIn: () => Promise.resolve({} as any),\n signInSilently: () => Promise.resolve({} as any),\n signInUrl: undefined,\n signOut: () => Promise.resolve({} as any),\n signUp: () => Promise.resolve({} as any),\n signUpUrl: undefined,\n user: null,\n userSchema: null,\n vendor: VendorConstants.VENDOR_PREFIX,\n});\n\nThunderIDContext.displayName = 'ThunderIDContext';\n\nexport default ThunderIDContext;\n"],"mappings":";;;;;;;;;;;AAuOA,MAAMA,4CAAsG;CAC1G,gBAAgB;CAChB,eAAe;CACf,SAAS;CACT,oBAAoB;CACpB,UAAU;CACV,aAAa;CACb,QAAQ;CACR,WAAW,EACT,WAAW,MACZ;CACD,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,YAAY;CACZ,yBAAyB,QAAQ,QAAQ,KAAK;CAC9C,MAAM;EACJ,eAAe;EACf,kBAAkB;EACnB;CACD,YAAY;CACZ,aAAaC;CACb,eAAe;CACf,WAAW;CACX,eAAe;CACf,YAAY;CACZ,MAAM;CACN,oBAAoB;CACpB,cAAc;CACd,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,8BAA8B,SAA6B,QAAQ;CACnE,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,sBAAsB,QAAQ,QAAQ,EAAE,CAAQ;CAChD,WAAW;CACX,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,WAAW;CACX,MAAM;CACN,YAAY;CACZ,QAAQC,oCAAgB;CACzB,CAAC;AAEF,iBAAiB,cAAc;AAE/B,+BAAe"}
|
|
1
|
+
{"version":3,"file":"ThunderIDContext.cjs","names":["ThunderIDContext: Context<ThunderIDContextProps | null>","fallbackResourceInvalidator","VendorConstants"],"sources":["../../../../src/contexts/ThunderID/ThunderIDContext.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ApiFetcher,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n FlowMetadataResponse,\n HttpRequestConfig,\n HttpResponse,\n IdToken,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n StorageManager,\n TokenExchangeRequestConfig,\n TokenResponse,\n VendorConstants,\n AttributeSchema,\n} from '@thunderid/browser';\nimport {Context, createContext} from 'react';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport {ResourceInvalidator, fallbackResourceInvalidator} from '../../utils/createResourceInvalidator';\n\n/**\n * Props interface of {@link ThunderIDContext}\n */\nexport type ThunderIDContextProps = {\n afterSignInUrl: string | undefined;\n applicationId: string | undefined;\n baseUrl: string | undefined;\n clientId: string | undefined;\n /**\n * Optional endpoint URL overrides from the client config. Used to resolve resource-server\n * endpoints (e.g. flow/user-management) independently of `baseUrl` — see `resolveResourceEndpoint`.\n */\n endpoints?: ThunderIDReactConfig['endpoints'];\n preferences?: ThunderIDReactConfig['preferences'];\n scopes: string | string[] | undefined;\n /**\n * OIDC discovery data.\n */\n discovery: {\n /**\n * The response from the `.well-known/openid-configuration` endpoint.\n * Contains server capabilities, supported endpoints, and metadata.\n * `null` while loading or when discovery has not been fetched.\n */\n wellKnown: OIDCDiscoveryApiResponse | null;\n };\n /**\n * Swaps the current access token with a new one based on the provided configuration (with a grant type).\n * @param config - Configuration for the token exchange request.\n * @returns A promise that resolves to the token response or the raw response.\n */\n exchangeToken: (config: TokenExchangeRequestConfig) => Promise<TokenResponse | Response>;\n /**\n * Retrieves the access token stored in the storage.\n * This function retrieves the access token and returns it.\n * @remarks This does not work in the `webWorker` or any other worker environment.\n * @returns A promise that resolves to the access token.\n */\n getAccessToken: () => Promise<string>;\n /**\n * Function to retrieve the decoded ID token.\n * This function decodes the ID token and returns its payload.\n * It can be used to access user claims and other information contained in the ID token.\n *\n * @returns A promise that resolves to the decoded ID token payload.\n */\n getDecodedIdToken: () => Promise<IdToken>;\n /**\n * Function to retrieve the ID token.\n * This function retrieves the ID token and returns it.\n *\n * @returns A promise that resolves to the ID token.\n */\n getIdToken: () => Promise<string>;\n /**\n * Returns the underlying StorageManager instance for reading and writing SDK-managed storage.\n * Resolves to `null` where the SDK has no browser storage (the context default, and `@thunderid/nextjs`).\n */\n getStorageManager: () => Promise<StorageManager<ThunderIDReactConfig> | null>;\n /**\n * HTTP request function to make API calls.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n http: {\n /**\n * Transport supplied through `ThunderIDProvider`'s `http.fetcher` prop, used by the management\n * hooks. `undefined` means the hooks fall back to the SDK's authenticated HTTP client.\n */\n fetcher?: ApiFetcher;\n /**\n * Makes an HTTP request using the provided configuration.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n request: (requestConfig?: HttpRequestConfig) => Promise<HttpResponse<any>>;\n /**\n * Makes multiple HTTP requests based on the provided configuration.\n * @param requestConfigs - Set of configurations for the HTTP requests.\n * @returns A promise that resolves to an array of HTTP responses.\n */\n requestAll: (requestConfigs?: HttpRequestConfig[]) => Promise<HttpResponse<any>[]>;\n };\n /**\n * Coordinates refetching between the management hooks: a successful mutation invalidates the\n * queries whose data it changed.\n */\n invalidator?: ResourceInvalidator;\n /**\n * Instance ID for multi-instance support.\n */\n instanceId: number;\n isInitialized: boolean;\n /**\n * Flag indicating whether the SDK is working in the background.\n */\n isLoading: boolean;\n /**\n * Flag indicating whether flow metadata is currently being fetched.\n */\n isMetaLoading: boolean;\n /**\n * Flag indicating whether the user is signed in or not.\n */\n isSignedIn: boolean;\n\n /**\n * Flow metadata returned by `GET /flow/meta` (v2 platform only).\n * `null` while loading or when `resolveFromMeta` is disabled.\n */\n meta: FlowMetadataResponse | null;\n\n organizationHandle: string | undefined;\n\n /**\n * Re-initializes the client with a new configuration.\n *\n * @remarks\n * This can be partial configuration to update only specific fields.\n *\n * @param config - New configuration to re-initialize the client with.\n * @returns Promise resolving to boolean indicating success.\n */\n reInitialize: (config: Partial<ThunderIDReactConfig>) => Promise<boolean>;\n\n /**\n * Recovery function to initiate the account/password recovery flow.\n */\n recover: (payload?: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n\n /**\n * Resolves `{{ t(key) }}` and `{{ meta(path) }}` template expressions in a string,\n * using the current i18n translation function and flow metadata from context.\n *\n * Useful in render-props patterns where consumers need to expand template strings\n * that come from the server (e.g. component labels, placeholders, headings).\n *\n * @example\n * const {resolveFlowTemplateLiterals} = useThunderID();\n * resolveFlowTemplateLiterals('{{ t(signin.heading.label) }}') // → 'Sign In'\n * resolveFlowTemplateLiterals('Login to {{ meta(application.name) }}') // → 'Login to My App'\n */\n resolveFlowTemplateLiterals: (text: string | undefined) => string;\n\n /**\n * Sign-in function to initiate the authentication process.\n * @remark This is the programmatic version of the `SignInButton` component.\n * TODO: Fix the types.\n */\n signIn: (...args: any) => Promise<any>;\n\n /**\n * Optional additional parameters to be sent in the sign-in request.\n * This can include custom parameters that your authorization server supports.\n * These parameters will be included in the authorization request sent to the server.\n * If not provided, no additional parameters will be sent.\n *\n * @example\n * signInOptions: { prompt: \"login\", fidp: \"OrganizationSSO\" }\n */\n signInOptions?: SignInOptions;\n\n /**\n * Optional token request configuration. params are appended to the token endpoint POST body.\n *\n * @example\n * tokenRequest: { params: { resource: \"https://api.example.com\" } }\n */\n tokenRequest?: {\n params?: Record<string, unknown>;\n };\n\n /**\n * Silent sign-in function to re-authenticate the user without user interaction.\n * @remark This is the programmatic version of the `SilentSignIn` component.\n */\n signInSilently: ThunderIDReactClient['signInSilently'];\n\n signInUrl: string | undefined;\n /**\n * Sign-out function to terminate the authentication session.\n * @remark This is the programmatic version of the `SignOutButton` component.\n * FIXME: Fix the types.\n */\n signOut: any;\n\n /**\n * Sign-up function to initiate the registration process.\n * @remark This is the programmatic version of the `SignUpButton` component.\n */\n signUp: (...args: any[]) => Promise<any>;\n\n signUpUrl: string | undefined;\n\n user: any;\n\n /**\n * Schema metadata for the user type returned by GET /users/me/meta.\n */\n userSchema: Record<string, AttributeSchema> | null;\n\n /**\n * Vendor/brand namespace used to prefix storage keys, cookie names, and CSS class names.\n * Resolved from the `vendor` config option, defaulting to `'thunderid'`.\n */\n vendor: string;\n} & Pick<ThunderIDReactClient, 'clearSession'>;\n\n/**\n * Context object for managing the Authentication flow builder core context.\n */\nconst ThunderIDContext: Context<ThunderIDContextProps | null> = createContext<null | ThunderIDContextProps>({\n afterSignInUrl: undefined,\n applicationId: undefined,\n baseUrl: undefined,\n clearSession: () => {},\n clientId: undefined,\n preferences: undefined,\n scopes: undefined,\n discovery: {\n wellKnown: null,\n },\n exchangeToken: null as unknown as ThunderIDContextProps['exchangeToken'],\n getAccessToken: null as unknown as ThunderIDContextProps['getAccessToken'],\n getDecodedIdToken: null as unknown as ThunderIDContextProps['getDecodedIdToken'],\n getIdToken: null as unknown as ThunderIDContextProps['getIdToken'],\n getStorageManager: () => Promise.resolve(null),\n http: {\n request: () => null as unknown as Promise<HttpResponse<any>>,\n requestAll: () => null as unknown as Promise<HttpResponse<any>[]>,\n },\n instanceId: 0,\n invalidator: fallbackResourceInvalidator,\n isInitialized: false,\n isLoading: true,\n isMetaLoading: false,\n isSignedIn: false,\n meta: null,\n organizationHandle: undefined,\n reInitialize: null as unknown as ThunderIDContextProps['reInitialize'],\n recover: () => Promise.resolve({} as any),\n resolveFlowTemplateLiterals: (text: string | undefined) => text ?? '',\n signIn: () => Promise.resolve({} as any),\n signInSilently: () => Promise.resolve({} as any),\n signInUrl: undefined,\n signOut: () => Promise.resolve({} as any),\n signUp: () => Promise.resolve({} as any),\n signUpUrl: undefined,\n user: null,\n userSchema: null,\n vendor: VendorConstants.VENDOR_PREFIX,\n});\n\nThunderIDContext.displayName = 'ThunderIDContext';\n\nexport default ThunderIDContext;\n"],"mappings":";;;;;;;;;;;AA2OA,MAAMA,4CAAsG;CAC1G,gBAAgB;CAChB,eAAe;CACf,SAAS;CACT,oBAAoB;CACpB,UAAU;CACV,aAAa;CACb,QAAQ;CACR,WAAW,EACT,WAAW,MACZ;CACD,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,YAAY;CACZ,yBAAyB,QAAQ,QAAQ,KAAK;CAC9C,MAAM;EACJ,eAAe;EACf,kBAAkB;EACnB;CACD,YAAY;CACZ,aAAaC;CACb,eAAe;CACf,WAAW;CACX,eAAe;CACf,YAAY;CACZ,MAAM;CACN,oBAAoB;CACpB,cAAc;CACd,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,8BAA8B,SAA6B,QAAQ;CACnE,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,sBAAsB,QAAQ,QAAQ,EAAE,CAAQ;CAChD,WAAW;CACX,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,WAAW;CACX,MAAM;CACN,YAAY;CACZ,QAAQC,oCAAgB;CACzB,CAAC;AAEF,iBAAiB,cAAc;AAE/B,+BAAe"}
|
|
@@ -158,6 +158,11 @@ const ThunderIDProvider = ({ afterSignInUrl, afterSignOutUrl, baseUrl: initialBa
|
|
|
158
158
|
await client.on("sign-in", async () => {
|
|
159
159
|
await updateSession();
|
|
160
160
|
});
|
|
161
|
+
await client.on("sign-out", () => {
|
|
162
|
+
setUser(null);
|
|
163
|
+
setUserProfile(null);
|
|
164
|
+
setIsSignedInSync(false);
|
|
165
|
+
});
|
|
161
166
|
try {
|
|
162
167
|
await client.startAutoRefreshToken();
|
|
163
168
|
} catch (error) {
|
|
@@ -265,7 +270,7 @@ const ThunderIDProvider = ({ afterSignInUrl, afterSignOutUrl, baseUrl: initialBa
|
|
|
265
270
|
const requestAll = (0, react.useCallback)(async (...args) => client.requestAll(...args), [client]);
|
|
266
271
|
const exchangeToken = (0, react.useCallback)(async (exchangeConfig) => client.exchangeToken(exchangeConfig), [client]);
|
|
267
272
|
const signOut = (0, react.useCallback)(async (...args) => client.signOut(...args), [client]);
|
|
268
|
-
const recover = (0, react.useCallback)(async (payload) => client.recover(payload), [client]);
|
|
273
|
+
const recover = (0, react.useCallback)(async (payload) => await client.recover(payload), [client]);
|
|
269
274
|
const signUp = (0, react.useCallback)(async (...args) => client.signUp(...args), [client]);
|
|
270
275
|
const clearSession = (0, react.useCallback)(async (...args) => client.clearSession(...args), [client]);
|
|
271
276
|
const reInitialize = (0, react.useCallback)(async (reInitConfig) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDProvider.cjs","names":["logger: ReturnType<typeof createPackageComponentLogger>","ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>>","reRenderCheckRef: RefObject<boolean>","client: ThunderIDReactClient","ThunderIDReactClient","invalidator: ResourceInvalidator","createResourceInvalidator","storageManagerRef: any","useBrowserUrl","pendingSessionUpdateRef: RefObject<Promise<void> | null>","resolvedBaseUrl: string","decodedToken: IdToken","shouldFetchProfile: boolean","claims: User","currentSignInStatus: boolean","getUsersMe","getUsersMeMeta","arg1: any","isV2FlowRequest: boolean","ThunderIDRuntimeError","currentUrl: URL","urlParams: URLSearchParams","code: string | null","executionIdFromUrl: string | null","storedExecutionId: string | null","SPAUtils","interval: NodeJS.Timeout","status: boolean","getDecodedIdToken: () => Promise<IdToken>","getIdToken: () => Promise<string>","getAccessToken: () => Promise<string>","getStorageManager: () => Promise<any>","storageManager: any","request: (...args: any[]) => Promise<any>","requestAll: (...args: any[]) => Promise<any>","exchangeToken: (exchangeConfig: any) => Promise<any>","signOut: (...args: any[]) => Promise<any>","recover: (payload: any) => Promise<any>","signUp: (...args: any[]) => Promise<any>","clearSession: (...args: any[]) => Promise<any>","reInitialize: (reInitConfig: any) => Promise<any>","result: any","reinitializedConfig: ThunderIDReactConfig","value: any","ThunderIDContext","I18nProvider","FlowMetaProvider","ThemeProvider","FlowProvider","UserProvider","ComponentRendererProvider"],"sources":["../../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ThunderIDRuntimeError,\n generateFlattenedUserProfile,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n User,\n UserProfile,\n IdToken,\n extractUserClaimsFromIdToken,\n EmbeddedSignInFlowResponse,\n createPackageComponentLogger,\n getVendorPrefix,\n resolveResourceEndpoint,\n AttributeSchema,\n SPAUtils,\n} from '@thunderid/browser';\nimport {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, useCallback} from 'react';\nimport ThunderIDContext from './ThunderIDContext';\nimport useBrowserUrl from '../../hooks/useBrowserUrl';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport {configureEmotionNonce} from '../../styles/emotion';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport createResourceInvalidator, {ResourceInvalidator} from '../../utils/createResourceInvalidator';\nimport ComponentRendererProvider from '../ComponentRenderer/ComponentRendererProvider';\nimport FlowProvider from '../Flow/FlowProvider';\nimport FlowMetaProvider from '../FlowMeta/FlowMetaProvider';\nimport I18nProvider from '../I18n/I18nProvider';\nimport ThemeProvider from '../Theme/ThemeProvider';\nimport UserProvider from '../User/UserProvider';\nimport getUsersMe from '../../api/getUsersMe';\nimport getUsersMeMeta from '../../api/getUsersMeMeta';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'ThunderIDProvider',\n);\n\n/**\n * Props interface of {@link ThunderIDProvider}\n */\nexport type ThunderIDProviderProps = ThunderIDReactConfig;\n\nconst ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>> = ({\n afterSignInUrl,\n afterSignOutUrl,\n baseUrl: initialBaseUrl,\n clientId,\n children,\n extensions,\n scopes,\n preferences,\n signInUrl,\n signUpUrl,\n organizationHandle,\n applicationId,\n signInOptions,\n tokenRequest,\n instanceId = 0,\n organizationChain,\n cspNonce,\n vendor,\n namespace,\n http: httpOptions,\n ...rest\n}: PropsWithChildren<ThunderIDProviderProps>): ReactElement => {\n // Must run synchronously here, in the render body, before any descendant's css()/cx()/\n // keyframes() calls execute during this same render pass - see the doc comment on\n // `configureEmotionNonce` for why a `useEffect` would be too late.\n configureEmotionNonce(cspNonce, vendor);\n\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const client: ThunderIDReactClient = useMemo(() => new ThunderIDReactClient(instanceId), [instanceId]);\n const invalidator: ResourceInvalidator = useMemo(() => createResourceInvalidator(), []);\n const storageManagerRef: any = useRef<any>(null);\n const {hasAuthParams, hasCalledForThisInstance} = useBrowserUrl();\n const [user, setUser] = useState<any | null>(null);\n const [isSignedInSync, setIsSignedInSync] = useState<boolean>(false);\n const [isInitializedSync, setIsInitializedSync] = useState<boolean>(false);\n const [isLoadingSync, setIsLoadingSync] = useState<boolean>(true);\n\n const [userProfile, setUserProfile] = useState<UserProfile | null>(null);\n const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(null);\n const [baseUrl, setBaseUrl] = useState<string>(initialBaseUrl ?? '');\n const [config, setConfig] = useState<ThunderIDReactConfig>({\n afterSignInUrl: afterSignInUrl ?? window.location.origin,\n afterSignOutUrl: afterSignOutUrl ?? window.location.origin,\n applicationId,\n baseUrl,\n clientId,\n organizationChain,\n organizationHandle,\n scopes,\n signInOptions,\n tokenRequest,\n signInUrl,\n signUpUrl,\n vendor,\n ...rest,\n });\n\n const [isUpdatingSession, setIsUpdatingSession] = useState<boolean>(false);\n const [wellKnown, setWellKnown] = useState<OIDCDiscoveryApiResponse | null>(null);\n\n // Holds the in-flight `updateSession()` promise so concurrent callers coalesce onto a single\n // `/users/me` request instead of issuing one each.\n const pendingSessionUpdateRef: RefObject<Promise<void> | null> = useRef<Promise<void> | null>(null);\n\n useEffect(() => {\n setBaseUrl(initialBaseUrl ?? '');\n }, [initialBaseUrl]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n await client.initialize(config);\n const initializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(initializedConfig);\n setWellKnown(await client.getDiscoveryResponse());\n })();\n }, []);\n\n async function performSessionUpdate(): Promise<void> {\n try {\n // Set flag to prevent loading state tracking from interfering\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n let resolvedBaseUrl: string = baseUrl;\n\n const decodedToken: IdToken = await client.getDecodedIdToken();\n\n // If there's a `user_org` claim in the ID token,\n // Treat this login as a organization login.\n if (decodedToken?.['user_org']) {\n resolvedBaseUrl = `${(await client.getConfiguration()).baseUrl}/o`;\n setBaseUrl(resolvedBaseUrl);\n }\n\n const shouldFetchProfile: boolean = preferences?.user?.fetchUserProfile !== false;\n const claims: User = extractUserClaimsFromIdToken(decodedToken) as User;\n let profileData = claims;\n const currentSignInStatus: boolean = await client.isSignedIn();\n\n if (currentSignInStatus && shouldFetchProfile) {\n try {\n const fetchedProfile = await getUsersMe({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMe', config),\n instanceId,\n });\n profileData = {...claims, ...fetchedProfile};\n } catch (err) {\n logger.warn('Failed to fetch user profile from /users/me:', err);\n }\n\n try {\n const metaRes = await getUsersMeMeta({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMeMeta', config),\n instanceId,\n });\n if (metaRes?.schema) {\n setUserSchema(metaRes.schema);\n } else {\n setUserSchema(null);\n }\n } catch (err) {\n setUserSchema(null);\n logger.warn('Failed to fetch user schema metadata from /users/me/meta:', err);\n }\n } else {\n setUserSchema(null);\n }\n\n setUser(profileData);\n setUserProfile({\n flattenedProfile: generateFlattenedUserProfile(profileData, []),\n profile: profileData,\n });\n\n // CRITICAL: Update sign-in status BEFORE setting loading to false\n // This prevents the race condition where ProtectedRoute sees isLoading=false but isSignedIn=false\n setIsSignedInSync(currentSignInStatus);\n } catch (error) {\n // TODO: Add an error log.\n } finally {\n // Clear the flag and set final loading state\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n\n /**\n * Single-flight wrapper around {@link performSessionUpdate}.\n *\n * Concurrent callers share the in-flight request instead of each issuing their own `/users/me`.\n * This is not a cache: once the request settles the ref is cleared, so a later caller (e.g.\n * revalidation after a profile update) fetches again.\n */\n async function updateSession(): Promise<void> {\n if (pendingSessionUpdateRef.current) {\n return pendingSessionUpdateRef.current;\n }\n\n pendingSessionUpdateRef.current = performSessionUpdate().finally(() => {\n pendingSessionUpdateRef.current = null;\n });\n\n return pendingSessionUpdateRef.current;\n }\n\n async function signIn(...args: any): Promise<User | EmbeddedSignInFlowResponse> {\n // Check if this is a V2 embedded flow request BEFORE calling signIn\n // This allows us to skip session checks entirely for V2 flows\n const arg1: any = args[0];\n const isV2FlowRequest: boolean =\n typeof arg1 === 'object' && arg1 !== null && ('executionId' in arg1 || 'applicationId' in arg1);\n\n try {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n }\n\n return await client.signIn(...args);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n } finally {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n }\n\n /**\n * Try signing in when the component is mounted.\n */\n useEffect(() => {\n // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature.\n // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state\n // This will remount all the useEffects to ensure that there are no unexpected side effects.\n // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to\n // prevent the re-render of this hook as suggested in the following discussion.\n // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623\n if (reRenderCheckRef.current) {\n return;\n }\n\n reRenderCheckRef.current = true;\n\n (async (): Promise<void> => {\n // Sync session state whenever sign-in completes (both redirect and embedded V2 flows).\n // Pass the user returned by the SDK's sign-in flow so users/me result is not discarded.\n await client.on('sign-in', async () => {\n await updateSession();\n });\n\n // Start auto-refresh with a soft failure. This also covers the case where the access token\n // expired while the refresh token is still valid — startAutoRefreshToken() calls\n // refreshAccessToken() immediately when timeUntilRefresh <= 0 — so the sign-in check below\n // sees the refreshed state.\n try {\n await client.startAutoRefreshToken();\n } catch (error) {\n logger.warn('Failed to schedule automatic token refresh.', error);\n }\n\n // User is already authenticated. Restore the session and skip the sign-in path.\n if (await client.isSignedIn()) {\n await updateSession();\n\n return;\n }\n\n const currentUrl: URL = new URL(window.location.href);\n const hasAuthParamsResult: boolean =\n hasAuthParams(currentUrl, config.afterSignInUrl!) && hasCalledForThisInstance(currentUrl, instanceId ?? 0);\n\n if (hasAuthParamsResult) {\n try {\n const urlParams: URLSearchParams = currentUrl.searchParams;\n const code: string | null = urlParams.get('code');\n const executionIdFromUrl: string | null = urlParams.get('executionId');\n const storedExecutionId: string | null = sessionStorage.getItem(\n `${getVendorPrefix(config.vendor)}_execution_id`,\n );\n\n // A silent sign-in response is handled even without a code: an error such as\n // login_required must still be relayed from the iframe to the waiting parent.\n if ((code || SPAUtils.isSilentStatePresentInURL()) && !executionIdFromUrl && !storedExecutionId) {\n await signIn();\n }\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n }\n }\n })();\n }, []);\n\n /**\n * Check if the user is signed in and update the state accordingly.\n * This will also set an interval to check for the sign-in status every second\n * until the user is signed in.\n */\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isSignedIn();\n\n setIsSignedInSync(status);\n\n if (!status) {\n interval = setInterval(async () => {\n const newStatus: boolean = await client.isSignedIn();\n\n if (newStatus) {\n setIsSignedInSync(true);\n clearInterval(interval);\n }\n }, 1000);\n } else {\n // TODO: Add a debug log to indicate that the user is already signed in.\n }\n } catch (error) {\n setIsSignedInSync(false);\n }\n })();\n\n return (): void => {\n if (interval) {\n clearInterval(interval);\n }\n };\n }, [client]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isInitialized();\n\n setIsInitializedSync(status);\n } catch (error) {\n setIsInitializedSync(false);\n }\n })();\n }, [client]);\n\n /**\n * Track loading state changes from the ThunderID client\n */\n useEffect(() => {\n const checkLoadingState = (): void => {\n // Don't override loading state during critical session updates\n if (isUpdatingSession) {\n return;\n }\n\n // Don't set loading=false while auth params are in the URL and user isn't signed in yet.\n // This prevents ProtectedRoute from redirecting before the sign-in effect processes the auth code.\n const currentUrl: URL = new URL(window.location.href);\n if (!isSignedInSync && hasAuthParams(currentUrl, config.afterSignInUrl!)) {\n return;\n }\n\n setIsLoadingSync(client.isLoading());\n };\n\n // Initial check\n checkLoadingState();\n\n // Set up an interval to check for loading state changes\n const interval: NodeJS.Timeout = setInterval(checkLoadingState, 100);\n\n return (): void => {\n clearInterval(interval);\n };\n }, [client, isLoadingSync, isSignedInSync, isUpdatingSession]);\n\n const signInSilently = async (options?: SignInOptions): Promise<User | boolean> => {\n try {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n return await client.signInSilently(options);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Error while signing in silently: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signInSilently-Error',\n 'react',\n 'An error occurred while trying to sign in silently.',\n );\n } finally {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n };\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile | null) => ({\n flattenedProfile: generateFlattenedUserProfile(payload),\n profile: payload,\n }));\n };\n\n const getDecodedIdToken: () => Promise<IdToken> = useCallback(\n async (): Promise<IdToken> => client.getDecodedIdToken(),\n [client],\n );\n\n const getIdToken: () => Promise<string> = useCallback(async (): Promise<string> => client.getIdToken(), [client]);\n\n const getAccessToken: () => Promise<string> = useCallback(\n async (): Promise<string> => client.getAccessToken(),\n [client],\n );\n\n const getStorageManager: () => Promise<any> = useCallback(async (): Promise<any> => {\n const storageManager: any = storageManagerRef.current ?? (await client.getStorageManager());\n if (storageManager) {\n storageManagerRef.current = storageManager;\n }\n return storageManager;\n }, [client]);\n\n const request: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.request(...args),\n [client],\n );\n\n const requestAll: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.requestAll(...args),\n [client],\n );\n\n const exchangeToken: (exchangeConfig: any) => Promise<any> = useCallback(\n async (exchangeConfig: any): Promise<any> => client.exchangeToken(exchangeConfig),\n [client],\n );\n\n const signOut: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signOut(...args),\n [client],\n );\n\n const recover: (payload: any) => Promise<any> = useCallback(\n async (payload: any): Promise<any> => client.recover(payload),\n [client],\n );\n\n const signUp: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signUp(...args),\n [client],\n );\n\n const clearSession: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.clearSession(...args),\n [client],\n );\n\n const reInitialize: (reInitConfig: any) => Promise<any> = useCallback(\n async (reInitConfig: any): Promise<any> => {\n const result: any = await client.reInitialize(reInitConfig);\n\n // Refresh React state from the reinitialized client so the context (config.endpoints,\n // baseUrl, discovery) reflects the new configuration instead of the pre-reinitialization state.\n const reinitializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(reinitializedConfig);\n setBaseUrl(reinitializedConfig.baseUrl ?? '');\n setWellKnown(await client.getDiscoveryResponse());\n\n return result;\n },\n [client],\n );\n\n const value: any = useMemo(\n () => ({\n afterSignInUrl: config.afterSignInUrl,\n applicationId: config.applicationId,\n baseUrl,\n endpoints: config.endpoints,\n scopes: config.scopes,\n clearSession,\n clientId,\n discovery: {\n wellKnown,\n },\n exchangeToken,\n getAccessToken,\n getDecodedIdToken,\n getIdToken,\n getStorageManager,\n http: {\n fetcher: httpOptions?.fetcher,\n request,\n requestAll,\n },\n instanceId,\n invalidator,\n isInitialized: isInitializedSync,\n isLoading: isLoadingSync,\n isSignedIn: isSignedInSync,\n organizationChain,\n organizationHandle: config?.organizationHandle,\n preferences,\n reInitialize,\n recover,\n signIn,\n signInOptions,\n tokenRequest,\n signInSilently,\n signInUrl,\n signOut,\n signUp,\n signUpUrl,\n user,\n userSchema,\n vendor: getVendorPrefix(config.vendor),\n }),\n [\n applicationId,\n config?.organizationHandle,\n config.vendor,\n config.afterSignInUrl,\n config.endpoints,\n config.scopes,\n signInUrl,\n signUpUrl,\n baseUrl,\n clientId,\n wellKnown,\n isInitializedSync,\n isLoadingSync,\n isSignedInSync,\n signIn,\n signInSilently,\n user,\n userSchema,\n client,\n signInOptions,\n tokenRequest,\n getDecodedIdToken,\n clearSession,\n exchangeToken,\n httpOptions?.fetcher,\n getAccessToken,\n getStorageManager,\n instanceId,\n invalidator,\n organizationChain,\n preferences,\n recover,\n reInitialize,\n request,\n requestAll,\n signOut,\n signUp,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={value}>\n <I18nProvider preferences={preferences?.i18n} vendor={getVendorPrefix(config.vendor)}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false} namespace={namespace}>\n <ThemeProvider\n theme={{\n ...preferences?.theme?.overrides,\n direction: preferences?.theme?.direction,\n }}\n >\n <FlowProvider>\n <UserProvider\n profile={userProfile as UserProfile}\n userSchema={userSchema}\n onUpdateProfile={handleProfileUpdate}\n >\n <ComponentRendererProvider renderers={(extensions?.components?.renderers ?? {}) as any}>\n {children}\n </ComponentRendererProvider>\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDProvider;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ThunderIDProvider.cjs","names":["logger: ReturnType<typeof createPackageComponentLogger>","ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>>","reRenderCheckRef: RefObject<boolean>","client: ThunderIDReactClient","ThunderIDReactClient","invalidator: ResourceInvalidator","createResourceInvalidator","storageManagerRef: any","useBrowserUrl","pendingSessionUpdateRef: RefObject<Promise<void> | null>","resolvedBaseUrl: string","decodedToken: IdToken","shouldFetchProfile: boolean","claims: User","currentSignInStatus: boolean","getUsersMe","getUsersMeMeta","arg1: any","isV2FlowRequest: boolean","ThunderIDRuntimeError","currentUrl: URL","urlParams: URLSearchParams","code: string | null","executionIdFromUrl: string | null","storedExecutionId: string | null","SPAUtils","interval: NodeJS.Timeout","status: boolean","getDecodedIdToken: () => Promise<IdToken>","getIdToken: () => Promise<string>","getAccessToken: () => Promise<string>","getStorageManager: ThunderIDContextProps['getStorageManager']","storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>>","request: (...args: any[]) => Promise<any>","requestAll: (...args: any[]) => Promise<any>","exchangeToken: (exchangeConfig: any) => Promise<any>","signOut: (...args: any[]) => Promise<any>","recover: ThunderIDContextProps['recover']","signUp: (...args: any[]) => Promise<any>","clearSession: (...args: any[]) => Promise<any>","reInitialize: (reInitConfig: any) => Promise<any>","result: any","reinitializedConfig: ThunderIDReactConfig","value: any","ThunderIDContext","I18nProvider","FlowMetaProvider","ThemeProvider","FlowProvider","UserProvider","ComponentRendererProvider"],"sources":["../../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ThunderIDRuntimeError,\n generateFlattenedUserProfile,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n User,\n UserProfile,\n IdToken,\n extractUserClaimsFromIdToken,\n EmbeddedSignInFlowResponse,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n createPackageComponentLogger,\n getVendorPrefix,\n resolveResourceEndpoint,\n AttributeSchema,\n SPAUtils,\n} from '@thunderid/browser';\nimport {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, useCallback} from 'react';\nimport ThunderIDContext, {ThunderIDContextProps} from './ThunderIDContext';\nimport useBrowserUrl from '../../hooks/useBrowserUrl';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport {configureEmotionNonce} from '../../styles/emotion';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport createResourceInvalidator, {ResourceInvalidator} from '../../utils/createResourceInvalidator';\nimport ComponentRendererProvider from '../ComponentRenderer/ComponentRendererProvider';\nimport FlowProvider from '../Flow/FlowProvider';\nimport FlowMetaProvider from '../FlowMeta/FlowMetaProvider';\nimport I18nProvider from '../I18n/I18nProvider';\nimport ThemeProvider from '../Theme/ThemeProvider';\nimport UserProvider from '../User/UserProvider';\nimport getUsersMe from '../../api/getUsersMe';\nimport getUsersMeMeta from '../../api/getUsersMeMeta';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'ThunderIDProvider',\n);\n\n/**\n * Props interface of {@link ThunderIDProvider}\n */\nexport type ThunderIDProviderProps = ThunderIDReactConfig;\n\nconst ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>> = ({\n afterSignInUrl,\n afterSignOutUrl,\n baseUrl: initialBaseUrl,\n clientId,\n children,\n extensions,\n scopes,\n preferences,\n signInUrl,\n signUpUrl,\n organizationHandle,\n applicationId,\n signInOptions,\n tokenRequest,\n instanceId = 0,\n organizationChain,\n cspNonce,\n vendor,\n namespace,\n http: httpOptions,\n ...rest\n}: PropsWithChildren<ThunderIDProviderProps>): ReactElement => {\n // Must run synchronously here, in the render body, before any descendant's css()/cx()/\n // keyframes() calls execute during this same render pass - see the doc comment on\n // `configureEmotionNonce` for why a `useEffect` would be too late.\n configureEmotionNonce(cspNonce, vendor);\n\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const client: ThunderIDReactClient = useMemo(() => new ThunderIDReactClient(instanceId), [instanceId]);\n const invalidator: ResourceInvalidator = useMemo(() => createResourceInvalidator(), []);\n const storageManagerRef: any = useRef<any>(null);\n const {hasAuthParams, hasCalledForThisInstance} = useBrowserUrl();\n const [user, setUser] = useState<User | null>(null);\n const [isSignedInSync, setIsSignedInSync] = useState<boolean>(false);\n const [isInitializedSync, setIsInitializedSync] = useState<boolean>(false);\n const [isLoadingSync, setIsLoadingSync] = useState<boolean>(true);\n\n const [userProfile, setUserProfile] = useState<UserProfile | null>(null);\n const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(null);\n const [baseUrl, setBaseUrl] = useState<string>(initialBaseUrl ?? '');\n const [config, setConfig] = useState<ThunderIDReactConfig>({\n afterSignInUrl: afterSignInUrl ?? window.location.origin,\n afterSignOutUrl: afterSignOutUrl ?? window.location.origin,\n applicationId,\n baseUrl,\n clientId,\n organizationChain,\n organizationHandle,\n scopes,\n signInOptions,\n tokenRequest,\n signInUrl,\n signUpUrl,\n vendor,\n ...rest,\n });\n\n const [isUpdatingSession, setIsUpdatingSession] = useState<boolean>(false);\n const [wellKnown, setWellKnown] = useState<OIDCDiscoveryApiResponse | null>(null);\n\n // Holds the in-flight `updateSession()` promise so concurrent callers coalesce onto a single\n // `/users/me` request instead of issuing one each.\n const pendingSessionUpdateRef: RefObject<Promise<void> | null> = useRef<Promise<void> | null>(null);\n\n useEffect(() => {\n setBaseUrl(initialBaseUrl ?? '');\n }, [initialBaseUrl]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n await client.initialize(config);\n const initializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(initializedConfig);\n setWellKnown(await client.getDiscoveryResponse());\n })();\n }, []);\n\n async function performSessionUpdate(): Promise<void> {\n try {\n // Set flag to prevent loading state tracking from interfering\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n let resolvedBaseUrl: string = baseUrl;\n\n const decodedToken: IdToken = await client.getDecodedIdToken();\n\n // If there's a `user_org` claim in the ID token,\n // Treat this login as a organization login.\n if (decodedToken?.['user_org']) {\n resolvedBaseUrl = `${(await client.getConfiguration()).baseUrl}/o`;\n setBaseUrl(resolvedBaseUrl);\n }\n\n const shouldFetchProfile: boolean = preferences?.user?.fetchUserProfile !== false;\n const claims: User = extractUserClaimsFromIdToken(decodedToken) as User;\n let profileData = claims;\n const currentSignInStatus: boolean = await client.isSignedIn();\n\n if (currentSignInStatus && shouldFetchProfile) {\n try {\n const fetchedProfile = await getUsersMe({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMe', config),\n instanceId,\n });\n profileData = {...claims, ...fetchedProfile};\n } catch (err) {\n logger.warn('Failed to fetch user profile from /users/me:', err);\n }\n\n try {\n const metaRes = await getUsersMeMeta({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMeMeta', config),\n instanceId,\n });\n if (metaRes?.schema) {\n setUserSchema(metaRes.schema);\n } else {\n setUserSchema(null);\n }\n } catch (err) {\n setUserSchema(null);\n logger.warn('Failed to fetch user schema metadata from /users/me/meta:', err);\n }\n } else {\n setUserSchema(null);\n }\n\n setUser(profileData);\n setUserProfile({\n flattenedProfile: generateFlattenedUserProfile(profileData, []),\n profile: profileData,\n });\n\n // CRITICAL: Update sign-in status BEFORE setting loading to false\n // This prevents the race condition where ProtectedRoute sees isLoading=false but isSignedIn=false\n setIsSignedInSync(currentSignInStatus);\n } catch (error) {\n // TODO: Add an error log.\n } finally {\n // Clear the flag and set final loading state\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n\n /**\n * Single-flight wrapper around {@link performSessionUpdate}.\n *\n * Concurrent callers share the in-flight request instead of each issuing their own `/users/me`.\n * This is not a cache: once the request settles the ref is cleared, so a later caller (e.g.\n * revalidation after a profile update) fetches again.\n */\n async function updateSession(): Promise<void> {\n if (pendingSessionUpdateRef.current) {\n return pendingSessionUpdateRef.current;\n }\n\n pendingSessionUpdateRef.current = performSessionUpdate().finally(() => {\n pendingSessionUpdateRef.current = null;\n });\n\n return pendingSessionUpdateRef.current;\n }\n\n async function signIn(...args: any): Promise<User | EmbeddedSignInFlowResponse> {\n // Check if this is a V2 embedded flow request BEFORE calling signIn\n // This allows us to skip session checks entirely for V2 flows\n const arg1: any = args[0];\n const isV2FlowRequest: boolean =\n typeof arg1 === 'object' && arg1 !== null && ('executionId' in arg1 || 'applicationId' in arg1);\n\n try {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n }\n\n return await client.signIn(...args);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n } finally {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n }\n\n /**\n * Try signing in when the component is mounted.\n */\n useEffect(() => {\n // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature.\n // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state\n // This will remount all the useEffects to ensure that there are no unexpected side effects.\n // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to\n // prevent the re-render of this hook as suggested in the following discussion.\n // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623\n if (reRenderCheckRef.current) {\n return;\n }\n\n reRenderCheckRef.current = true;\n\n (async (): Promise<void> => {\n // Sync session state whenever sign-in completes (both redirect and embedded V2 flows).\n // Pass the user returned by the SDK's sign-in flow so users/me result is not discarded.\n await client.on('sign-in', async () => {\n await updateSession();\n });\n\n // A session that ends elsewhere, such as a sign-out in another app, signs this app out too.\n await client.on('sign-out', () => {\n setUser(null);\n setUserProfile(null);\n setIsSignedInSync(false);\n });\n\n // Start auto-refresh with a soft failure. This also covers the case where the access token\n // expired while the refresh token is still valid — startAutoRefreshToken() calls\n // refreshAccessToken() immediately when timeUntilRefresh <= 0 — so the sign-in check below\n // sees the refreshed state.\n try {\n await client.startAutoRefreshToken();\n } catch (error) {\n logger.warn('Failed to schedule automatic token refresh.', error);\n }\n\n // User is already authenticated. Restore the session and skip the sign-in path.\n if (await client.isSignedIn()) {\n await updateSession();\n\n return;\n }\n\n const currentUrl: URL = new URL(window.location.href);\n const hasAuthParamsResult: boolean =\n hasAuthParams(currentUrl, config.afterSignInUrl!) && hasCalledForThisInstance(currentUrl, instanceId ?? 0);\n\n if (hasAuthParamsResult) {\n try {\n const urlParams: URLSearchParams = currentUrl.searchParams;\n const code: string | null = urlParams.get('code');\n const executionIdFromUrl: string | null = urlParams.get('executionId');\n const storedExecutionId: string | null = sessionStorage.getItem(\n `${getVendorPrefix(config.vendor)}_execution_id`,\n );\n\n // A silent sign-in response is handled even without a code: an error such as\n // login_required must still be relayed from the iframe to the waiting parent.\n if ((code || SPAUtils.isSilentStatePresentInURL()) && !executionIdFromUrl && !storedExecutionId) {\n await signIn();\n }\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n }\n }\n })();\n }, []);\n\n /**\n * Check if the user is signed in and update the state accordingly.\n * This will also set an interval to check for the sign-in status every second\n * until the user is signed in.\n */\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isSignedIn();\n\n setIsSignedInSync(status);\n\n if (!status) {\n interval = setInterval(async () => {\n const newStatus: boolean = await client.isSignedIn();\n\n if (newStatus) {\n setIsSignedInSync(true);\n clearInterval(interval);\n }\n }, 1000);\n } else {\n // TODO: Add a debug log to indicate that the user is already signed in.\n }\n } catch (error) {\n setIsSignedInSync(false);\n }\n })();\n\n return (): void => {\n if (interval) {\n clearInterval(interval);\n }\n };\n }, [client]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isInitialized();\n\n setIsInitializedSync(status);\n } catch (error) {\n setIsInitializedSync(false);\n }\n })();\n }, [client]);\n\n /**\n * Track loading state changes from the ThunderID client\n */\n useEffect(() => {\n const checkLoadingState = (): void => {\n // Don't override loading state during critical session updates\n if (isUpdatingSession) {\n return;\n }\n\n // Don't set loading=false while auth params are in the URL and user isn't signed in yet.\n // This prevents ProtectedRoute from redirecting before the sign-in effect processes the auth code.\n const currentUrl: URL = new URL(window.location.href);\n if (!isSignedInSync && hasAuthParams(currentUrl, config.afterSignInUrl!)) {\n return;\n }\n\n setIsLoadingSync(client.isLoading());\n };\n\n // Initial check\n checkLoadingState();\n\n // Set up an interval to check for loading state changes\n const interval: NodeJS.Timeout = setInterval(checkLoadingState, 100);\n\n return (): void => {\n clearInterval(interval);\n };\n }, [client, isLoadingSync, isSignedInSync, isUpdatingSession]);\n\n const signInSilently = async (options?: SignInOptions): Promise<User | boolean> => {\n try {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n return await client.signInSilently(options);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Error while signing in silently: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signInSilently-Error',\n 'react',\n 'An error occurred while trying to sign in silently.',\n );\n } finally {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n };\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile | null) => ({\n flattenedProfile: generateFlattenedUserProfile(payload),\n profile: payload,\n }));\n };\n\n const getDecodedIdToken: () => Promise<IdToken> = useCallback(\n async (): Promise<IdToken> => client.getDecodedIdToken(),\n [client],\n );\n\n const getIdToken: () => Promise<string> = useCallback(async (): Promise<string> => client.getIdToken(), [client]);\n\n const getAccessToken: () => Promise<string> = useCallback(\n async (): Promise<string> => client.getAccessToken(),\n [client],\n );\n\n const getStorageManager: ThunderIDContextProps['getStorageManager'] = useCallback(async () => {\n const storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>> =\n storageManagerRef.current ?? (await client.getStorageManager());\n if (storageManager) {\n storageManagerRef.current = storageManager;\n }\n return storageManager;\n }, [client]);\n\n const request: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.request(...args),\n [client],\n );\n\n const requestAll: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.requestAll(...args),\n [client],\n );\n\n const exchangeToken: (exchangeConfig: any) => Promise<any> = useCallback(\n async (exchangeConfig: any): Promise<any> => client.exchangeToken(exchangeConfig),\n [client],\n );\n\n const signOut: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signOut(...args),\n [client],\n );\n\n const recover: ThunderIDContextProps['recover'] = useCallback(\n async (payload?: EmbeddedRecoveryFlowRequest): Promise<EmbeddedRecoveryFlowResponse> =>\n (await client.recover(payload)) as EmbeddedRecoveryFlowResponse,\n [client],\n );\n\n const signUp: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signUp(...args),\n [client],\n );\n\n const clearSession: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.clearSession(...args),\n [client],\n );\n\n const reInitialize: (reInitConfig: any) => Promise<any> = useCallback(\n async (reInitConfig: any): Promise<any> => {\n const result: any = await client.reInitialize(reInitConfig);\n\n // Refresh React state from the reinitialized client so the context (config.endpoints,\n // baseUrl, discovery) reflects the new configuration instead of the pre-reinitialization state.\n const reinitializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(reinitializedConfig);\n setBaseUrl(reinitializedConfig.baseUrl ?? '');\n setWellKnown(await client.getDiscoveryResponse());\n\n return result;\n },\n [client],\n );\n\n const value: any = useMemo(\n () => ({\n afterSignInUrl: config.afterSignInUrl,\n applicationId: config.applicationId,\n baseUrl,\n endpoints: config.endpoints,\n scopes: config.scopes,\n clearSession,\n clientId,\n discovery: {\n wellKnown,\n },\n exchangeToken,\n getAccessToken,\n getDecodedIdToken,\n getIdToken,\n getStorageManager,\n http: {\n fetcher: httpOptions?.fetcher,\n request,\n requestAll,\n },\n instanceId,\n invalidator,\n isInitialized: isInitializedSync,\n isLoading: isLoadingSync,\n isSignedIn: isSignedInSync,\n organizationChain,\n organizationHandle: config?.organizationHandle,\n preferences,\n reInitialize,\n recover,\n signIn,\n signInOptions,\n tokenRequest,\n signInSilently,\n signInUrl,\n signOut,\n signUp,\n signUpUrl,\n user,\n userSchema,\n vendor: getVendorPrefix(config.vendor),\n }),\n [\n applicationId,\n config?.organizationHandle,\n config.vendor,\n config.afterSignInUrl,\n config.endpoints,\n config.scopes,\n signInUrl,\n signUpUrl,\n baseUrl,\n clientId,\n wellKnown,\n isInitializedSync,\n isLoadingSync,\n isSignedInSync,\n signIn,\n signInSilently,\n user,\n userSchema,\n client,\n signInOptions,\n tokenRequest,\n getDecodedIdToken,\n clearSession,\n exchangeToken,\n httpOptions?.fetcher,\n getAccessToken,\n getStorageManager,\n instanceId,\n invalidator,\n organizationChain,\n preferences,\n recover,\n reInitialize,\n request,\n requestAll,\n signOut,\n signUp,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={value}>\n <I18nProvider preferences={preferences?.i18n} vendor={getVendorPrefix(config.vendor)}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false} namespace={namespace}>\n <ThemeProvider\n theme={{\n ...preferences?.theme?.overrides,\n direction: preferences?.theme?.direction,\n }}\n >\n <FlowProvider>\n <UserProvider\n profile={userProfile as UserProfile}\n userSchema={userSchema}\n onUpdateProfile={handleProfileUpdate}\n >\n <ComponentRendererProvider renderers={(extensions?.components?.renderers ?? {}) as any}>\n {children}\n </ComponentRendererProvider>\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDProvider;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAMA,+DACJ,oBACA,oBACD;AAOD,MAAMC,qBAAoE,EACxE,gBACA,iBACA,SAAS,gBACT,UACA,UACA,YACA,QACA,aACA,WACA,WACA,oBACA,eACA,eACA,cACA,aAAa,GACb,mBACA,UACA,QACA,WACA,MAAM,YACN,GAAG,WAC0D;AAI7D,uCAAsB,UAAU,OAAO;CAEvC,MAAMC,qCAA8C,MAAM;CAC1D,MAAMC,kCAA6C,IAAIC,qCAAqB,WAAW,EAAE,CAAC,WAAW,CAAC;CACtG,MAAMC,uCAAiDC,2CAA2B,EAAE,EAAE,CAAC;CACvF,MAAMC,sCAAqC,KAAK;CAChD,MAAM,EAAC,eAAe,6BAA4BC,+BAAe;CACjE,MAAM,CAAC,MAAM,+BAAiC,KAAK;CACnD,MAAM,CAAC,gBAAgB,yCAAuC,MAAM;CACpE,MAAM,CAAC,mBAAmB,4CAA0C,MAAM;CAC1E,MAAM,CAAC,eAAe,wCAAsC,KAAK;CAEjE,MAAM,CAAC,aAAa,sCAA+C,KAAK;CACxE,MAAM,CAAC,YAAY,qCAAkE,KAAK;CAC1F,MAAM,CAAC,SAAS,kCAA+B,kBAAkB,GAAG;CACpE,MAAM,CAAC,QAAQ,iCAA4C;EACzD,gBAAgB,kBAAkB,OAAO,SAAS;EAClD,iBAAiB,mBAAmB,OAAO,SAAS;EACpD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;EACJ,CAAC;CAEF,MAAM,CAAC,mBAAmB,4CAA0C,MAAM;CAC1E,MAAM,CAAC,WAAW,oCAA0D,KAAK;CAIjF,MAAMC,4CAAwF,KAAK;AAEnG,4BAAgB;AACd,aAAW,kBAAkB,GAAG;IAC/B,CAAC,eAAe,CAAC;AAEpB,4BAAgB;AACd,GAAC,YAA2B;AAC1B,SAAM,OAAO,WAAW,OAAO;AAE/B,aADgD,MAAM,OAAO,kBAAkB,CACnD;AAC5B,gBAAa,MAAM,OAAO,sBAAsB,CAAC;MAC/C;IACH,EAAE,CAAC;CAEN,eAAe,uBAAsC;AACnD,MAAI;AAEF,wBAAqB,KAAK;AAC1B,oBAAiB,KAAK;GACtB,IAAIC,kBAA0B;GAE9B,MAAMC,eAAwB,MAAM,OAAO,mBAAmB;AAI9D,OAAI,eAAe,aAAa;AAC9B,sBAAkB,IAAI,MAAM,OAAO,kBAAkB,EAAE,QAAQ;AAC/D,eAAW,gBAAgB;;GAG7B,MAAMC,qBAA8B,aAAa,MAAM,qBAAqB;GAC5E,MAAMC,+DAA4C,aAAa;GAC/D,IAAI,cAAc;GAClB,MAAMC,sBAA+B,MAAM,OAAO,YAAY;AAE9D,OAAI,uBAAuB,oBAAoB;AAC7C,QAAI;KACF,MAAM,iBAAiB,MAAMC,2BAAW;MACtC,SAAS;MACT,sDAA6B,WAAW,OAAO;MAC/C;MACD,CAAC;AACF,mBAAc;MAAC,GAAG;MAAQ,GAAG;MAAe;aACrC,KAAK;AACZ,YAAO,KAAK,gDAAgD,IAAI;;AAGlE,QAAI;KACF,MAAM,UAAU,MAAMC,+BAAe;MACnC,SAAS;MACT,sDAA6B,eAAe,OAAO;MACnD;MACD,CAAC;AACF,SAAI,SAAS,OACX,eAAc,QAAQ,OAAO;SAE7B,eAAc,KAAK;aAEd,KAAK;AACZ,mBAAc,KAAK;AACnB,YAAO,KAAK,6DAA6D,IAAI;;SAG/E,eAAc,KAAK;AAGrB,WAAQ,YAAY;AACpB,kBAAe;IACb,wEAA+C,aAAa,EAAE,CAAC;IAC/D,SAAS;IACV,CAAC;AAIF,qBAAkB,oBAAoB;WAC/B,OAAO,WAEN;AAER,wBAAqB,MAAM;AAC3B,oBAAiB,OAAO,WAAW,CAAC;;;;;;;;;;CAWxC,eAAe,gBAA+B;AAC5C,MAAI,wBAAwB,QAC1B,QAAO,wBAAwB;AAGjC,0BAAwB,UAAU,sBAAsB,CAAC,cAAc;AACrE,2BAAwB,UAAU;IAClC;AAEF,SAAO,wBAAwB;;CAGjC,eAAe,OAAO,GAAG,MAAuD;EAG9E,MAAMC,OAAY,KAAK;EACvB,MAAMC,kBACJ,OAAO,SAAS,YAAY,SAAS,SAAS,iBAAiB,QAAQ,mBAAmB;AAE5F,MAAI;AACF,OAAI,CAAC,iBAAiB;AACpB,yBAAqB,KAAK;AAC1B,qBAAiB,KAAK;;AAGxB,UAAO,MAAM,OAAO,OAAO,GAAG,KAAK;WAC5B,OAAO;AACd,SAAM,IAAIC,0CACR,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,UAAU,MAAM,CAAC,IACzF,0BACA,SACA,6CACD;YACO;AACR,OAAI,CAAC,iBAAiB;AACpB,yBAAqB,MAAM;AAC3B,qBAAiB,OAAO,WAAW,CAAC;;;;;;;AAQ1C,4BAAgB;AAOd,MAAI,iBAAiB,QACnB;AAGF,mBAAiB,UAAU;AAE3B,GAAC,YAA2B;AAG1B,SAAM,OAAO,GAAG,WAAW,YAAY;AACrC,UAAM,eAAe;KACrB;AAGF,SAAM,OAAO,GAAG,kBAAkB;AAChC,YAAQ,KAAK;AACb,mBAAe,KAAK;AACpB,sBAAkB,MAAM;KACxB;AAMF,OAAI;AACF,UAAM,OAAO,uBAAuB;YAC7B,OAAO;AACd,WAAO,KAAK,+CAA+C,MAAM;;AAInE,OAAI,MAAM,OAAO,YAAY,EAAE;AAC7B,UAAM,eAAe;AAErB;;GAGF,MAAMC,aAAkB,IAAI,IAAI,OAAO,SAAS,KAAK;AAIrD,OAFE,cAAc,YAAY,OAAO,eAAgB,IAAI,yBAAyB,YAAY,cAAc,EAAE,CAG1G,KAAI;IACF,MAAMC,YAA6B,WAAW;IAC9C,MAAMC,OAAsB,UAAU,IAAI,OAAO;IACjD,MAAMC,qBAAoC,UAAU,IAAI,cAAc;IACtE,MAAMC,oBAAmC,eAAe,QACtD,4CAAmB,OAAO,OAAO,CAAC,eACnC;AAID,SAAK,QAAQC,6BAAS,2BAA2B,KAAK,CAAC,sBAAsB,CAAC,kBAC5E,OAAM,QAAQ;YAET,OAAO;AACd,UAAM,IAAIN,0CACR,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,UAAU,MAAM,CAAC,IACzF,0BACA,SACA,6CACD;;MAGH;IACH,EAAE,CAAC;;;;;;AAON,4BAAgB;EACd,IAAIO;AAEJ,GAAC,YAA2B;AAC1B,OAAI;IACF,MAAMC,SAAkB,MAAM,OAAO,YAAY;AAEjD,sBAAkB,OAAO;AAEzB,QAAI,CAAC,OACH,YAAW,YAAY,YAAY;AAGjC,SAF2B,MAAM,OAAO,YAAY,EAErC;AACb,wBAAkB,KAAK;AACvB,oBAAc,SAAS;;OAExB,IAAK;YAIH,OAAO;AACd,sBAAkB,MAAM;;MAExB;AAEJ,eAAmB;AACjB,OAAI,SACF,eAAc,SAAS;;IAG1B,CAAC,OAAO,CAAC;AAEZ,4BAAgB;AACd,GAAC,YAA2B;AAC1B,OAAI;AAGF,yBAFwB,MAAM,OAAO,eAAe,CAExB;YACrB,OAAO;AACd,yBAAqB,MAAM;;MAE3B;IACH,CAAC,OAAO,CAAC;;;;AAKZ,4BAAgB;EACd,MAAM,0BAAgC;AAEpC,OAAI,kBACF;GAKF,MAAMP,aAAkB,IAAI,IAAI,OAAO,SAAS,KAAK;AACrD,OAAI,CAAC,kBAAkB,cAAc,YAAY,OAAO,eAAgB,CACtE;AAGF,oBAAiB,OAAO,WAAW,CAAC;;AAItC,qBAAmB;EAGnB,MAAMM,WAA2B,YAAY,mBAAmB,IAAI;AAEpE,eAAmB;AACjB,iBAAc,SAAS;;IAExB;EAAC;EAAQ;EAAe;EAAgB;EAAkB,CAAC;CAE9D,MAAM,iBAAiB,OAAO,YAAqD;AACjF,MAAI;AACF,wBAAqB,KAAK;AAC1B,oBAAiB,KAAK;AACtB,UAAO,MAAM,OAAO,eAAe,QAAQ;WACpC,OAAO;AACd,SAAM,IAAIP,0CACR,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,UAAU,MAAM,CAAC,IAC1G,kCACA,SACA,sDACD;YACO;AACR,wBAAqB,MAAM;AAC3B,oBAAiB,OAAO,WAAW,CAAC;;;CAIxC,MAAM,uBAAuB,YAAwB;AACnD,UAAQ,QAAQ;AAChB,kBAAgB,UAA8B;GAC5C,wEAA+C,QAAQ;GACvD,SAAS;GACV,EAAE;;CAGL,MAAMS,2CACJ,YAA8B,OAAO,mBAAmB,EACxD,CAAC,OAAO,CACT;CAED,MAAMC,oCAAgD,YAA6B,OAAO,YAAY,EAAE,CAAC,OAAO,CAAC;CAEjH,MAAMC,wCACJ,YAA6B,OAAO,gBAAgB,EACpD,CAAC,OAAO,CACT;CAED,MAAMC,2CAA4E,YAAY;EAC5F,MAAMC,iBACJ,kBAAkB,WAAY,MAAM,OAAO,mBAAmB;AAChE,MAAI,eACF,mBAAkB,UAAU;AAE9B,SAAO;IACN,CAAC,OAAO,CAAC;CAEZ,MAAMC,iCACJ,OAAO,GAAG,SAA8B,OAAO,QAAQ,GAAG,KAAK,EAC/D,CAAC,OAAO,CACT;CAED,MAAMC,oCACJ,OAAO,GAAG,SAA8B,OAAO,WAAW,GAAG,KAAK,EAClE,CAAC,OAAO,CACT;CAED,MAAMC,uCACJ,OAAO,mBAAsC,OAAO,cAAc,eAAe,EACjF,CAAC,OAAO,CACT;CAED,MAAMC,iCACJ,OAAO,GAAG,SAA8B,OAAO,QAAQ,GAAG,KAAK,EAC/D,CAAC,OAAO,CACT;CAED,MAAMC,iCACJ,OAAO,YACJ,MAAM,OAAO,QAAQ,QAAQ,EAChC,CAAC,OAAO,CACT;CAED,MAAMC,gCACJ,OAAO,GAAG,SAA8B,OAAO,OAAO,GAAG,KAAK,EAC9D,CAAC,OAAO,CACT;CAED,MAAMC,sCACJ,OAAO,GAAG,SAA8B,OAAO,aAAa,GAAG,KAAK,EACpE,CAAC,OAAO,CACT;CAED,MAAMC,sCACJ,OAAO,iBAAoC;EACzC,MAAMC,SAAc,MAAM,OAAO,aAAa,aAAa;EAI3D,MAAMC,sBAA4C,MAAM,OAAO,kBAAkB;AACjF,YAAU,oBAAoB;AAC9B,aAAW,oBAAoB,WAAW,GAAG;AAC7C,eAAa,MAAM,OAAO,sBAAsB,CAAC;AAEjD,SAAO;IAET,CAAC,OAAO,CACT;CAED,MAAMC,kCACG;EACL,gBAAgB,OAAO;EACvB,eAAe,OAAO;EACtB;EACA,WAAW,OAAO;EAClB,QAAQ,OAAO;EACf;EACA;EACA,WAAW,EACT,WACD;EACD;EACA;EACA;EACA;EACA;EACA,MAAM;GACJ,SAAS,aAAa;GACtB;GACA;GACD;EACD;EACA;EACA,eAAe;EACf,WAAW;EACX,YAAY;EACZ;EACA,oBAAoB,QAAQ;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iDAAwB,OAAO,OAAO;EACvC,GACD;EACE;EACA,QAAQ;EACR,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QACE,2CAACC,iCAAiB;EAAgB;YAChC,2CAACC;GAAa,aAAa,aAAa;GAAM,iDAAwB,OAAO,OAAO;aAClF,2CAACC;IAAiB,SAAS,aAAa,oBAAoB;IAAkB;cAC5E,2CAACC;KACC,OAAO;MACL,GAAG,aAAa,OAAO;MACvB,WAAW,aAAa,OAAO;MAChC;eAED,2CAACC,0CACC,2CAACC;MACC,SAAS;MACG;MACZ,iBAAiB;gBAEjB,2CAACC;OAA0B,WAAY,YAAY,YAAY,aAAa,EAAE;OAC3E;QACyB;OACf,GACF;MACD;KACC;IACN;GACW;;AAIhC,gCAAe"}
|
|
@@ -5,6 +5,10 @@ import { CardProps } from '../../../primitives/Card/Card';
|
|
|
5
5
|
* Render props for custom UI rendering
|
|
6
6
|
*/
|
|
7
7
|
export interface BaseSignInRenderProps {
|
|
8
|
+
/**
|
|
9
|
+
* Additional data from the current flow step (e.g. `source` lookups for `KEY_VALUE_LIST`)
|
|
10
|
+
*/
|
|
11
|
+
additionalData: Record<string, unknown>;
|
|
8
12
|
/**
|
|
9
13
|
* Flow components
|
|
10
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"BaseSignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSignIn.js","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","errors: Record<string, string>","touched: Record<string, boolean>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n} from '@thunderid/browser';\nimport {FC, useEffect, useMemo, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport {FormField, useForm} from '../../../../hooks/useForm';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {cx} from '../../../../styles/emotion';\nimport composeAffixedInputs from '../../../../utils/composeAffixedInputs';\nimport {extractErrorMessage} from '../../../../utils/flowTransformer';\nimport AlertPrimitive from '../../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../../primitives/Card/Card';\nimport Spinner from '../../../primitives/Spinner/Spinner';\nimport Typography from '../../../primitives/Typography/Typography';\nimport {renderSignInComponents} from '../AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to handle input changes\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission\n */\n handleSubmit: (component: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * HTML id attribute for the form container.\n */\n id?: string;\n\n /**\n * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\n\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n id,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n serverFieldErrors = null,\n revalidateOnChangeAfterBlur = false,\n}: BaseSignInProps): ReactElement => {\n const {meta, vendor} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t, currentLanguage} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\n\n /**\n * Component type for which forms validation will be applicable\n */\n const acceptableType = [\n 'TEXT_INPUT',\n 'PASSWORD_INPUT',\n 'EMAIL_INPUT',\n 'PHONE_INPUT',\n 'OTP_INPUT',\n 'SELECT',\n 'DATE_INPUT',\n 'CUSTOM',\n ];\n\n /**\n * Handle error responses and extract meaningful error messages\n * Uses the transformer's extractErrorMessage function for consistency\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (acceptableType.includes(component.type)) {\n const identifier: string = component.ref;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: identifier,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Run declarative rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = useMemo(\n () => (components ? extractFormFields(components) : []),\n [components, extractFormFields],\n );\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isValid: isFormValid,\n setValue: setFormValue,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n revalidateTouchedFields,\n } = form;\n\n // Project server-side fieldErrors into form state. `setTouchedFields` is used instead\n // of `setTouched` so client-side `validateField` doesn't wipe server errors when the\n // client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n if (!serverFieldErrors || serverFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [serverFieldErrors, setFormErrors, setTouchedFields, clearFormErrors]);\n\n // Re-translate displayed validation errors when the UI language changes.\n // revalidateTouchedFields is stable, so this effect fires only on language change.\n useEffect(() => {\n revalidateTouchedFields();\n }, [currentLanguage, revalidateTouchedFields]);\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.keys(composedData).forEach((key: any) => {\n if (composedData[key] !== undefined && composedData[key] !== null && composedData[key] !== '') {\n filteredInputs[key] = composedData[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n vendor,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n vendor,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div id={id} className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2OA,MAAMA,qBAA0C,EAC9C,aAAa,EAAE,EACf,UACA,SACA,OAAO,eACP,IACA,YAAY,IACZ,iBAAiB,IACjB,kBAAkB,IAClB,mBAAmB,IACnB,OAAO,UACP,UAAU,YACV,WAAW,mBACX,UACA,iBAAiB,EAAE,EACnB,oBAAoB,OACpB,oBAAoB,MACpB,8BAA8B,YACK;CACnC,MAAM,EAAC,MAAM,WAAUC,sBAAc;CACrC,MAAM,EAAC,UAASC,kBAAU;CAC1B,MAAMC,kBAAwC,WAAWC,iCAAyB;CAClF,MAAM,EAAC,GAAG,oBAAmBC,wBAAgB;CAC7C,MAAM,EAAC,UAAU,cAAc,OAAO,WAAW,UAAU,cAAc,YAAY,kBAAiBC,iBAAS;CAC/G,MAAMC,SAAcC,0BAAU,OAAO,MAAM,KAAK,OAAO,KAAK,QAAQ;CAEpE,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CACvD,MAAM,CAAC,UAAU,eAAe,SAAuB,KAAK;CAE5D,MAAMC,YAAqB,qBAAqB;;;;CAKhD,MAAM,iBAAiB;EACrB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;CAMD,MAAMC,cAAmB,aACtB,UAAe;EACd,MAAMC,eAAuB,oBAAoB,OAAO,EAAE;AAG1D,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,aAAa,CAAC;AAGrE,iBAAe;AACf,aAAW;GACT,SAAS;GACT,MAAM;GACP,CAAC;IAEJ;EAAC;EAAG;EAAY;EAAc,CAC/B;;;;CAKD,MAAMC,oBAA0E,aAC7E,mBAAyD;EACxD,MAAMC,SAAsB,EAAE;EAE9B,MAAM,qBAAqB,UAAwC;AACjE,SAAM,SAAS,cAAmB;AAChC,QAAI,eAAe,SAAS,UAAU,KAAK,EAAE;KAC3C,MAAMC,aAAqB,UAAU;KACrC,MAAM,gBAAgB,wBAAwB,UAAU,WAAW;AACnE,YAAO,KAAK;MACV,cAAc;MACd,MAAM;MACN,UAAU,UAAU,YAAY;MAChC,YAAY,UAAkB;AAC5B,WAAI,UAAU,aAAa,CAAC,SAAS,MAAM,MAAM,KAAK,IACpD,QAAO,EAAE,mCAAmC;AAG9C,WAAI,iBAAiB,OAAO;QAC1B,MAAM,cAAc,cAAc,MAAM;AACxC,YAAI,YACF,QAAO,EAAE,YAAY;;AAIzB,YACG,UAAU,SAAS,iBAAiB,UAAU,YAAY,YAC3D,SACA,CAAC,6BAA6B,KAAK,MAAM,CAEzC,QAAO,EAAE,sBAAsB;AAGjC,cAAO;;MAEV,CAAC;;AAEJ,QAAI,UAAU,WACZ,mBAAkB,UAAU,WAAW;KAEzC;;AAGJ,oBAAkB,eAAe;AACjC,SAAO;IAET,CAAC,EAAE,CACJ;CAgBD,MAAM,EACJ,QAAQ,YACR,SAAS,eACT,QAAQ,YACR,SAAS,aACT,UAAU,cACV,YAAY,gBACZ,kBACA,WAAW,eACX,aAAa,iBACb,cACA,gBACA,OAAO,WACP,4BAtBuC,QAAgC;EACvE,QAN8B,cACvB,aAAa,kBAAkB,WAAW,GAAG,EAAE,EACtD,CAAC,YAAY,kBAAkB,CAChC;EAIC,eAAe,EAAE;EACjB,iBAAiB,EAAE,mCAAmC;EACtD;EACA,gBAAgB;EAChB,kBAAkB;EACnB,CAAC;AAqBF,iBAAgB;AACd,mBAAiB;AACjB,MAAI,CAAC,qBAAqB,kBAAkB,WAAW,EACrD;EAEF,MAAMC,SAAiC,EAAE;EACzC,MAAMC,UAAmC,EAAE;AAC3C,OAAK,MAAM,MAAM,kBACf,KAAI,EAAE,GAAG,cAAc,SAAS;AAC9B,UAAO,GAAG,cAAc,GAAG;AAC3B,WAAQ,GAAG,cAAc;;AAG7B,mBAAiB,QAAQ;AACzB,gBAAc,OAAO;IACpB;EAAC;EAAmB;EAAe;EAAkB;EAAgB,CAAC;AAIzE,iBAAgB;AACd,2BAAyB;IACxB,CAAC,iBAAiB,wBAAwB,CAAC;;;;;;CAO9C,MAAM,qBAAqB,MAAc,UAAwB;AAC/D,eAAa,MAAM,MAAM;;;;;;CAO3B,MAAM,mBAAmB,SAAuB;AAC9C,iBAAe,MAAM,KAAK;;;;;CAM5B,MAAM,eAAe,OACnB,WACA,MACA,mBACkB;AAElB,MAAI,CAAC,gBAAgB;AAEnB,mBAAgB;AAIhB,OAAI,CAFgD,cAAc,CAElD,QACd;;AAIJ,kBAAgB,KAAK;AACrB,cAAY,KAAK;AACjB,iBAAe;AAEf,MAAI;GACF,MAAMC,eAAgD,OAClDC,6BAAqB,MAAgC,OAAO,GAC5D;GAGJ,MAAMC,iBAAsC,EAAE;AAC9C,OAAI,aACF,QAAO,KAAK,aAAa,CAAC,SAAS,QAAa;AAC9C,QAAI,aAAa,SAAS,UAAa,aAAa,SAAS,QAAQ,aAAa,SAAS,GACzF,gBAAe,OAAO,aAAa;KAErC;GAGJ,IAAIC,UAAqC,EAAE;AAG3C,aAAU;IACR,GAAG;IACH,GAAI,UAAU,MAAM,EAAC,QAAQ,UAAU,IAAG;IAC1C,QAAQ;IACT;AAED,SAAM,WAAW,SAAS,UAAU;WAC7B,KAAK;AACZ,eAAY,IAAI;AAChB,aAAU,IAAa;YACf;AACR,mBAAgB,MAAM;;;CAK1B,MAAMC,mBAAwB,GAC5B;EACE,yBAAyB,SAAS;EAClC,yBAAyB,WAAW,OAAO;EAC3C,yBAAyB,WAAW,UAAU;EAC/C,EACD,UACD;CAED,MAAMC,eAAoB,GACxB;EACE,yBAAyB,gBAAgB;EACzC,SAAS,WAAW,yBAAyB,uBAAuB;EACpE,SAAS,WAAW,yBAAyB,uBAAuB;EACrE,EACD,eACD;CAED,MAAMC,gBAAqB,GACzB;EACE,yBAAyB,iBAAiB;EAC1C,SAAS,WAAW,yBAAyB,wBAAwB;EACrE,SAAS,WAAW,yBAAyB,wBAAwB;EACtE,EACD,gBACD;CAED,MAAMC,iBAAsB,GAAG,CAAC,yBAAyB,mBAAmB,CAAC,EAAE,iBAAiB;;;;CAKhG,MAAMC,mBAAwB,aAC3B,mBACC,uBACE,gBACA,YACA,eACA,YACA,WACA,aACA,WACA,mBACA;EACE,kBAAkB;EAClB,QAAQ;EACR;EACA,iBAAiB;EACjB,gBAAgB;EAChB;EACA;EACA,aAAa;EACb,UAAU;EACV;EACA;EACA;EACA;EACD,CACF,EACH;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAGD,KAAI,UAAU;EACZ,MAAMC,cAAqC;GACzC;GACA,OAAO;GACP,aAAa;GACb;GACA;GACA;GACA;GACA,SAAS;GACT,UAAU,gBAAgB,EAAE;GAC5B;GACA,UAAU,gBAAgB;GAC1B,OAAO,aAAa,EAAE,iBAAiB;GACvC,SAAS;GACT,oBAAoB;IAClB,MAAMC,SAAc,cAAc;AAClC,WAAO;KAAC,aAAa,OAAO;KAAQ,SAAS,OAAO;KAAQ;;GAE9D,QAAQ;GACT;AAED,SACE,oBAAC;GAAQ;GAAI,WAAW;GAAkB,eAAY;aACnD,SAAS,YAAY;IAClB;;AAKV,KAAI,UACF,QACE,oBAACC;EACK;EACJ,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,oBAACA,aAAc,qBACb,oBAAC;GAAI,WAAY,OAAkC;aACjD,oBAACC,oBAAU;IACP,GACgB;GACV;AAIpB,KAAI,CAAC,cAAc,WAAW,WAAW,EACvC,QACE,oBAACD;EACK;EACJ,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,oBAACA,aAAc,qBACb,oBAACE;GAAe,SAAQ;aACtB,oBAACC;IAAW,SAAQ;cAAS,EAAE,yCAAyC;KAAc;IACvE,GACK;GACV;AAIpB,QACE,oBAACH;EACK;EACJ,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,qBAACA,aAAc;GACZ,iBACC,oBAAC;IAAI,WAAW,OAAO;cACrB,oBAACE;KAAe,SAAQ;KAAQ,WAAW,GAAG,OAAO,iBAAiB,eAAe;eACnF,oBAACA,cAAe,yBAAa,cAAc,UAAqC;MACjE;KACb;GAEP,gBAAgB,aAAa,SAAS,KACrC,oBAAC;IAAI,WAAW,OAAO;cACpB,aAAa,KAAK,SAAc,UAC/B,oBAACA;KAEC,SAAS,QAAQ,SAAS,UAAU,UAAU;KAC9C,WAAW,GAAG,OAAO,iBAAiB,eAAe;eAErD,oBAACA,cAAe,yBAAa,QAAQ,UAAqC;OAJrE,MAKU,CACjB;KACE;GAER,oBAAC;IAAI,WAAW,OAAO;cAAmB,iBAAiB,WAAW;KAAO;MACvD;GACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDpB,MAAME,cAAmC,EAAC,YAAa,GAAG,WAAyC;CACjG,MAAMC,UACJ,oBAACC,kCACC,oBAAC,qBAAkB,GAAI,OAAQ,GAClB;AAGjB,KAAI,CAAC,YAAa,QAAO;AAEzB,QAAO,oBAACC,oCAA4B;EAAS,OAAO;YAAc;GAA+C;;AAGnH,yBAAe"}
|
|
1
|
+
{"version":3,"file":"BaseSignIn.js","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","errors: Record<string, string>","touched: Record<string, boolean>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n} from '@thunderid/browser';\nimport {FC, useEffect, useMemo, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport {FormField, useForm} from '../../../../hooks/useForm';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {cx} from '../../../../styles/emotion';\nimport composeAffixedInputs from '../../../../utils/composeAffixedInputs';\nimport {extractErrorMessage} from '../../../../utils/flowTransformer';\nimport AlertPrimitive from '../../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../../primitives/Card/Card';\nimport Spinner from '../../../primitives/Spinner/Spinner';\nimport Typography from '../../../primitives/Typography/Typography';\nimport {renderSignInComponents} from '../AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Additional data from the current flow step (e.g. `source` lookups for `KEY_VALUE_LIST`)\n */\n additionalData: Record<string, unknown>;\n\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to handle input changes\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission\n */\n handleSubmit: (component: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * HTML id attribute for the form container.\n */\n id?: string;\n\n /**\n * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\n\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n id,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n serverFieldErrors = null,\n revalidateOnChangeAfterBlur = false,\n}: BaseSignInProps): ReactElement => {\n const {meta, vendor} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t, currentLanguage} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\n\n /**\n * Component type for which forms validation will be applicable\n */\n const acceptableType = [\n 'TEXT_INPUT',\n 'PASSWORD_INPUT',\n 'EMAIL_INPUT',\n 'PHONE_INPUT',\n 'OTP_INPUT',\n 'SELECT',\n 'DATE_INPUT',\n 'CUSTOM',\n ];\n\n /**\n * Handle error responses and extract meaningful error messages\n * Uses the transformer's extractErrorMessage function for consistency\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (acceptableType.includes(component.type)) {\n const identifier: string = component.ref;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: identifier,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Run declarative rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = useMemo(\n () => (components ? extractFormFields(components) : []),\n [components, extractFormFields],\n );\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isValid: isFormValid,\n setValue: setFormValue,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n revalidateTouchedFields,\n } = form;\n\n // Project server-side fieldErrors into form state. `setTouchedFields` is used instead\n // of `setTouched` so client-side `validateField` doesn't wipe server errors when the\n // client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n if (!serverFieldErrors || serverFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [serverFieldErrors, setFormErrors, setTouchedFields, clearFormErrors]);\n\n // Re-translate displayed validation errors when the UI language changes.\n // revalidateTouchedFields is stable, so this effect fires only on language change.\n useEffect(() => {\n revalidateTouchedFields();\n }, [currentLanguage, revalidateTouchedFields]);\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.keys(composedData).forEach((key: any) => {\n if (composedData[key] !== undefined && composedData[key] !== null && composedData[key] !== '') {\n filteredInputs[key] = composedData[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n vendor,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n vendor,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n additionalData,\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div id={id} className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6C,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAmB,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAQzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAEpC;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC;IAEnD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpD;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACtC;AAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6C,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAmB,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAQzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAEpC;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC;IAEnD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpD;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACtC;AAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CA+1B3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -317,9 +317,8 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
317
317
|
const storedExecutionId = !urlParams.executionId ? sessionStorage.getItem(`${vendor}_execution_id`) : null;
|
|
318
318
|
const resumeExecutionId = urlParams.executionId || storedExecutionId;
|
|
319
319
|
if (!resumeExecutionId && !effectiveApplicationId) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
throw error;
|
|
320
|
+
setError(new ThunderIDRuntimeError("Either executionId or applicationId is required for authentication", "SIGN_IN_ERROR", "react"));
|
|
321
|
+
return;
|
|
323
322
|
}
|
|
324
323
|
try {
|
|
325
324
|
setFlowError(null);
|