@stytch/react 20.0.0-next.7 → 20.0.0-next.8
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/CHANGELOG.md +6 -0
- package/dist/cjs/b2b/index.cjs +5 -5
- package/dist/cjs/b2b/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +5 -5
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/{shadcn-CEwpX1ov.js → shadcn-Du-ZeW8t.js} +11 -8
- package/dist/cjs/shadcn-Du-ZeW8t.js.map +1 -0
- package/dist/cjs-dev/b2b/index.cjs +5 -5
- package/dist/cjs-dev/b2b/index.cjs.map +1 -1
- package/dist/cjs-dev/index.cjs +5 -5
- package/dist/cjs-dev/index.cjs.map +1 -1
- package/dist/cjs-dev/{shadcn-CFfLoRN4.js → shadcn-BZDGkwFh.js} +11 -8
- package/dist/cjs-dev/shadcn-BZDGkwFh.js.map +1 -0
- package/dist/esm/_virtual/index3.mjs +3 -5
- package/dist/esm/_virtual/index3.mjs.map +1 -1
- package/dist/esm/_virtual/index4.mjs +5 -3
- package/dist/esm/_virtual/index4.mjs.map +1 -1
- package/dist/esm/packages/web/src/adminPortal/utils/theme.mjs +1 -1
- package/dist/esm/packages/web/src/ui/b2b/components/B2BOneTap.mjs +5 -5
- package/dist/esm/packages/web/src/ui/b2b/components/B2BOneTap.mjs.map +1 -1
- package/dist/esm/packages/web/src/ui/b2c/components/GoogleOneTap.mjs +5 -5
- package/dist/esm/packages/web/src/ui/b2c/components/GoogleOneTap.mjs.map +1 -1
- package/dist/esm/packages/web/src/ui/hooks/useIsMounted.mjs +10 -7
- package/dist/esm/packages/web/src/ui/hooks/useIsMounted.mjs.map +1 -1
- package/dist/esm/packages/web/src/utils/crypto.mjs +1 -1
- package/dist/esm-dev/packages/web/src/ui/b2b/components/B2BOneTap.mjs +5 -5
- package/dist/esm-dev/packages/web/src/ui/b2b/components/B2BOneTap.mjs.map +1 -1
- package/dist/esm-dev/packages/web/src/ui/b2c/components/GoogleOneTap.mjs +5 -5
- package/dist/esm-dev/packages/web/src/ui/b2c/components/GoogleOneTap.mjs.map +1 -1
- package/dist/esm-dev/packages/web/src/ui/hooks/useIsMounted.mjs +10 -7
- package/dist/esm-dev/packages/web/src/ui/hooks/useIsMounted.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/shadcn-CEwpX1ov.js.map +0 -1
- package/dist/cjs-dev/shadcn-CFfLoRN4.js.map +0 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { __require as requireLodash_merge } from '../node_modules/lodash.merge/index.mjs';
|
|
1
|
+
import { __require as requireBs58 } from '../node_modules/bs58/index.mjs';
|
|
3
2
|
|
|
4
|
-
var
|
|
5
|
-
var merge = /*@__PURE__*/getDefaultExportFromCjs(lodash_mergeExports);
|
|
3
|
+
var bs58Exports = requireBs58();
|
|
6
4
|
|
|
7
|
-
export {
|
|
5
|
+
export { bs58Exports as b };
|
|
8
6
|
//# sourceMappingURL=index3.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index3.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index3.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getDefaultExportFromCjs } from './_commonjsHelpers.mjs';
|
|
2
|
+
import { __require as requireLodash_merge } from '../node_modules/lodash.merge/index.mjs';
|
|
2
3
|
|
|
3
|
-
var
|
|
4
|
+
var lodash_mergeExports = requireLodash_merge();
|
|
5
|
+
var merge = /*@__PURE__*/getDefaultExportFromCjs(lodash_mergeExports);
|
|
4
6
|
|
|
5
|
-
export {
|
|
7
|
+
export { merge as default };
|
|
6
8
|
//# sourceMappingURL=index4.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import merge from '../../../../../_virtual/
|
|
1
|
+
import merge from '../../../../../_virtual/index4.mjs';
|
|
2
2
|
import 'react';
|
|
3
3
|
import createTheme from '../../../../../node_modules/@mui/material/styles/createTheme.mjs';
|
|
4
4
|
import selectClasses from '../../../../../node_modules/@mui/material/Select/selectClasses.mjs';
|
|
@@ -2,7 +2,7 @@ import React__default, { useState, useCallback, useEffect } from 'react';
|
|
|
2
2
|
import { readB2BInternals } from '../../../utils/internal.mjs';
|
|
3
3
|
import LastUsed from '../../components/molecules/LastUsed.mjs';
|
|
4
4
|
import { OneTapErrors } from '../../components/organisms/OneTapError.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { useIsMounted } from '../../hooks/useIsMounted.mjs';
|
|
6
6
|
import { useStytch, useConfig, useGlobalReducer } from '../GlobalContextProvider.mjs';
|
|
7
7
|
import { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap.mjs';
|
|
8
8
|
import { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod.mjs';
|
|
@@ -17,7 +17,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
17
17
|
const config = useConfig();
|
|
18
18
|
const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();
|
|
19
19
|
const [oneTapError, setOneTapError] = useState();
|
|
20
|
-
const
|
|
20
|
+
const isMounted = useIsMounted();
|
|
21
21
|
const [state, dispatch] = useGlobalReducer();
|
|
22
22
|
const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();
|
|
23
23
|
/*
|
|
@@ -47,7 +47,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
47
47
|
* prompt() is called, One Tap falls back to the element-does-not-exist behavior.
|
|
48
48
|
* Fix: add a check for whether the component is still rendered immediately before we
|
|
49
49
|
* call prompt, preventing this race condition
|
|
50
|
-
*/ if (
|
|
50
|
+
*/ if (!isMounted.current) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
let oneTapCallback;
|
|
@@ -81,7 +81,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
81
81
|
});
|
|
82
82
|
// Check if the component has become unmounted during the async OT render process
|
|
83
83
|
// Kill the rest of the logic if so
|
|
84
|
-
if (
|
|
84
|
+
if (!isMounted.current) {
|
|
85
85
|
client.cancel();
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
@@ -97,7 +97,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
97
97
|
return client;
|
|
98
98
|
}, [
|
|
99
99
|
stytch,
|
|
100
|
-
|
|
100
|
+
isMounted,
|
|
101
101
|
state.flowState.organization,
|
|
102
102
|
config.oauthOptions?.signupRedirectURL,
|
|
103
103
|
config.oauthOptions?.loginRedirectURL,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"B2BOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/B2BOneTap.tsx"],"sourcesContent":["import { DEV, logger } from '@stytch/core';\nimport { B2BOAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport type { CredentialResponse } from 'google-one-tap';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { readB2BInternals } from '../../../utils/internal';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { useIsUnmounted } from '../../hooks/useIsMounted';\nimport { useConfig, useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport { AppScreens } from '../types/AppScreens';\nimport { OAuthB2BButton } from './OAuthB2BButton';\n\nexport type B2BOneTapProps = {\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nexport const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside }: B2BOneTapProps) => {\n const stytch = useStytch();\n const config = useConfig();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const isUnmounted = useIsUnmounted();\n const [state, dispatch] = useGlobalReducer();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n const { oneTap } = readB2BInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'default_provider_not_allowed') {\n setOneTapError(OneTapErrors.DefaultProviderNotAllowed);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n /**\n * One tap is composed of two calls, an init() call and a prompt() call\n * the init() call takes in a parent_id where one tap should be shown\n * prompt() does the actual showing. if the element does not exist,\n * we show One Tap in the upper right corner\n * if the element does exist, One Tap's lifecycle is tied to the lifecycle of said element\n * here, we call init() then prompt() in the useeffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (isUnmounted.current) {\n return;\n }\n\n let oneTapCallback: (response: CredentialResponse) => void;\n if (state.flowState.organization) {\n oneTapCallback = oneTap.createOnSuccessHandler({\n organizationId: state.flowState.organization.organization_id,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n } else {\n oneTapCallback = oneTap.createOnDiscoverySuccessHandler({\n discoveryRedirectUrl: config.oauthOptions?.discoveryRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n }\n const renderResult = await client.render({\n callback: oneTapCallback,\n style: {\n position: OneTapPositions.floating,\n },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (isUnmounted.current) {\n client.cancel();\n return;\n }\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n stytch,\n isUnmounted,\n state.flowState.organization,\n config.oauthOptions?.signupRedirectURL,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.discoveryRedirectURL,\n dispatch,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n if (isOnlyFloatingOneTap) {\n return null;\n }\n\n const fallbackButton = (\n <OAuthB2BButton\n providerType={B2BOAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n discoveryRedirectUrl={config.oauthOptions?.discoveryRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedMethod(B2BOAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === B2BOAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["B2BGoogleOneTap","customScopes","providerParams","cancelOnTapOutside","stytch","useStytch","config","useConfig","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","oneTapError","setOneTapError","useState","isUnmounted","useIsUnmounted","state","dispatch","useGlobalReducer","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","attemptToLoadOneTap","useCallback","oneTap","readB2BInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","DefaultProviderNotAllowed","logger","error","client","current","oneTapCallback","flowState","organization","createOnSuccessHandler","organizationId","organization_id","signupRedirectUrl","oauthOptions","signupRedirectURL","loginRedirectUrl","loginRedirectURL","onSuccess","redirectOnSuccess","onError","type","screen","AppScreens","Error","createOnDiscoverySuccessHandler","discoveryRedirectUrl","discoveryRedirectURL","renderResult","render","callback","style","position","OneTapPositions","floating","cancel","OriginNotAllowedForClient","InvalidOAuthClient","useEffect","then","$client","catch","err","fallbackButton","React","OAuthB2BButton","providerType","B2BOAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"B2BOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/B2BOneTap.tsx"],"sourcesContent":["import { DEV, logger } from '@stytch/core';\nimport { B2BOAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport type { CredentialResponse } from 'google-one-tap';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { readB2BInternals } from '../../../utils/internal';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { useIsMounted } from '../../hooks/useIsMounted';\nimport { useConfig, useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport { AppScreens } from '../types/AppScreens';\nimport { OAuthB2BButton } from './OAuthB2BButton';\n\nexport type B2BOneTapProps = {\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nexport const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside }: B2BOneTapProps) => {\n const stytch = useStytch();\n const config = useConfig();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const isMounted = useIsMounted();\n const [state, dispatch] = useGlobalReducer();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n const { oneTap } = readB2BInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'default_provider_not_allowed') {\n setOneTapError(OneTapErrors.DefaultProviderNotAllowed);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n /**\n * One tap is composed of two calls, an init() call and a prompt() call\n * the init() call takes in a parent_id where one tap should be shown\n * prompt() does the actual showing. if the element does not exist,\n * we show One Tap in the upper right corner\n * if the element does exist, One Tap's lifecycle is tied to the lifecycle of said element\n * here, we call init() then prompt() in the useeffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (!isMounted.current) {\n return;\n }\n\n let oneTapCallback: (response: CredentialResponse) => void;\n if (state.flowState.organization) {\n oneTapCallback = oneTap.createOnSuccessHandler({\n organizationId: state.flowState.organization.organization_id,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n } else {\n oneTapCallback = oneTap.createOnDiscoverySuccessHandler({\n discoveryRedirectUrl: config.oauthOptions?.discoveryRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n }\n const renderResult = await client.render({\n callback: oneTapCallback,\n style: {\n position: OneTapPositions.floating,\n },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (!isMounted.current) {\n client.cancel();\n return;\n }\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n stytch,\n isMounted,\n state.flowState.organization,\n config.oauthOptions?.signupRedirectURL,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.discoveryRedirectURL,\n dispatch,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n if (isOnlyFloatingOneTap) {\n return null;\n }\n\n const fallbackButton = (\n <OAuthB2BButton\n providerType={B2BOAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n discoveryRedirectUrl={config.oauthOptions?.discoveryRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedMethod(B2BOAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === B2BOAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["B2BGoogleOneTap","customScopes","providerParams","cancelOnTapOutside","stytch","useStytch","config","useConfig","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","oneTapError","setOneTapError","useState","isMounted","useIsMounted","state","dispatch","useGlobalReducer","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","attemptToLoadOneTap","useCallback","oneTap","readB2BInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","DefaultProviderNotAllowed","logger","error","client","current","oneTapCallback","flowState","organization","createOnSuccessHandler","organizationId","organization_id","signupRedirectUrl","oauthOptions","signupRedirectURL","loginRedirectUrl","loginRedirectURL","onSuccess","redirectOnSuccess","onError","type","screen","AppScreens","Error","createOnDiscoverySuccessHandler","discoveryRedirectUrl","discoveryRedirectURL","renderResult","render","callback","style","position","OneTapPositions","floating","cancel","OriginNotAllowedForClient","InvalidOAuthClient","useEffect","then","$client","catch","err","fallbackButton","React","OAuthB2BButton","providerType","B2BOAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV"],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { CircularProgress } from '../../components/atoms/CircularProgress.mjs';
|
|
|
7
7
|
import LastUsed from '../../components/molecules/LastUsed.mjs';
|
|
8
8
|
import { OneTapErrors } from '../../components/organisms/OneTapError.mjs';
|
|
9
9
|
import { usePresentation } from '../../components/PresentationConfig.mjs';
|
|
10
|
-
import {
|
|
10
|
+
import { useIsMounted } from '../../hooks/useIsMounted.mjs';
|
|
11
11
|
import { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap.mjs';
|
|
12
12
|
import { useConfig, useStytch } from '../GlobalContextProvider.mjs';
|
|
13
13
|
import { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth.mjs';
|
|
@@ -38,7 +38,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
38
38
|
const [oneTapError, setOneTapError] = useState();
|
|
39
39
|
const resizeCount = useRef(0);
|
|
40
40
|
const timeout = useRef();
|
|
41
|
-
const
|
|
41
|
+
const isMounted = useIsMounted();
|
|
42
42
|
const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();
|
|
43
43
|
const { options } = usePresentation();
|
|
44
44
|
/*
|
|
@@ -120,7 +120,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
120
120
|
* prompt() is called, One Tap falls back to the element-does-not-exist behavior.
|
|
121
121
|
* Fix: add a check for whether the component is still rendered immediately before we
|
|
122
122
|
* call prompt, preventing this race condition
|
|
123
|
-
*/ if (
|
|
123
|
+
*/ if (!isMounted.current) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
126
|
const renderResult = await client.render({
|
|
@@ -137,7 +137,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
137
137
|
});
|
|
138
138
|
// Check if the component has become unmounted during the async OT render process
|
|
139
139
|
// Kill the rest of the logic if so
|
|
140
|
-
if (
|
|
140
|
+
if (!isMounted.current) {
|
|
141
141
|
client.cancel();
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
@@ -156,7 +156,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
156
156
|
}, [
|
|
157
157
|
shouldRenderOneTap,
|
|
158
158
|
stytch,
|
|
159
|
-
|
|
159
|
+
isMounted,
|
|
160
160
|
config.oauthOptions?.loginRedirectURL,
|
|
161
161
|
config.oauthOptions?.signupRedirectURL,
|
|
162
162
|
position,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2c/components/GoogleOneTap.tsx"],"sourcesContent":["import { DEV, logger, StringLiteralFromEnum } from '@stytch/core';\nimport { OAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { OneTapProvider } from '../../../oneTap/OneTapProvider';\nimport { getRenderedOneTapMode } from '../../../oneTap/positionModes';\nimport { readB2CInternals } from '../../../utils/internal';\nimport { CircularProgress } from '../../components/atoms/CircularProgress';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport { useIsUnmounted } from '../../hooks/useIsMounted';\nimport { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth';\nimport styles from './GoogleOneTap.module.css';\nimport { OAuthButton } from './OAuthButton';\n\ntype Props = {\n position?: StringLiteralFromEnum<OneTapPositions>;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nconst OAUTH_BUTTON_HEIGHT = 38;\n\n// See WebComponents.tsx - when using shadow DOM, the Google script cannot see the\n// mount point, so we render it outside and use slot to bring it back in\nconst OneTapMountNode = ({ enableShadowDOM }: { enableShadowDOM: boolean | undefined }) =>\n enableShadowDOM ? (\n <slot name=\"one-tap\"></slot>\n ) : (\n <div data-prompt_parent_id=\"g_id_onload\" id=\"google-parent-prompt\" />\n );\n\nexport const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutside }: Props) => {\n const oneTapRenderMode = getRenderedOneTapMode(position);\n const shouldRenderEmbeddedOneTap = oneTapRenderMode === 'embedded';\n const shouldRenderOneTap = !!oneTapRenderMode;\n\n const config = useConfig();\n const stytch = useStytch();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap(config);\n const [pending, setPending] = useState(shouldRenderEmbeddedOneTap);\n const [canDisplayOneTap, setCanDisplayOneTap] = useState(true);\n const [height, setHeight] = useState(OAUTH_BUTTON_HEIGHT);\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const resizeCount = useRef(0);\n const timeout = useRef<number>();\n const isUnmounted = useIsUnmounted();\n const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();\n const { options } = usePresentation();\n\n /*\n * Begin One Tap Render Smoothing Logic\n */\n // Gets height of rendered one-tap UI, and sets the container height to that.\n // Animation is added for a smoother transition,\n const onResize = useCallback<ResizeObserverCallback>(([el]) => {\n if (timeout.current != null) {\n clearTimeout(timeout.current);\n }\n // On initial load, the one-tap ui rapidly changes heights 3 times. Checking\n // the resizeCount lets us debounce the first 2 resizes, so they will get\n // cancelled, but if they don't, it will resize after the short delay.\n if (resizeCount.current > 1) {\n // While setting the height, if the contentRect height is 0, it could also mean that the\n // oauthOptions props are being changed, and in that scenario if we can continue to display\n // one tap, we are setting the container height to the current height. If one tap cannot display\n // one tap, we will set the container height to the height of the button component.\n // Else we will set the height to the contentRect height.\n setHeight((currentHeight) =>\n el.contentRect.height === 0 ? (canDisplayOneTap ? currentHeight : OAUTH_BUTTON_HEIGHT) : el.contentRect.height,\n );\n } else {\n timeout.current = window.setTimeout(\n () =>\n setHeight((currentHeight) =>\n el.contentRect.height === 0\n ? canDisplayOneTap\n ? currentHeight\n : OAUTH_BUTTON_HEIGHT\n : el.contentRect.height,\n ),\n 100,\n );\n }\n resizeCount.current++;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- SDK-1354\n }, []);\n\n // If we are in embedded mode, initialize the resize observer and bind it to the React callback\n useEffect(() => {\n if (shouldRenderEmbeddedOneTap) {\n const el = document.getElementById('google-parent-prompt');\n if (el) {\n const resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(el);\n return () => resizeObserver.disconnect();\n }\n }\n }, [onResize, shouldRenderEmbeddedOneTap]);\n /*\n * End One Tap Render Smoothing Logic\n */\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n if (!shouldRenderOneTap) {\n return;\n }\n\n const { oneTap } = readB2CInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'no_signup_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredSignupRedirectUrls);\n } else if (clientResult.reason === 'no_login_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredLoginRedirectUrls);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n const onOneTapCancelled = (showError?: boolean) => {\n setCanDisplayOneTap(false);\n setHeight(OAUTH_BUTTON_HEIGHT);\n if (showError) {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n };\n\n /**\n * One Tap is composed of two calls, an init() call and a prompt() call.\n * The init() call takes in a parent_id where One Tap should be shown\n * prompt() does the actual showing.\n * If the element does not exist, we show One Tap in the upper right corner.\n * If the element does exist, One Tap's lifecycle is tied to the lifecycle of said element.\n * Here, we call init() then prompt() in the useEffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (isUnmounted.current) {\n return;\n }\n\n const renderResult = await client.render({\n callback: oneTap.createOnSuccessHandler({\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n }),\n onOneTapCancelled,\n style: { position },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (isUnmounted.current) {\n client.cancel();\n return;\n }\n\n setCanDisplayOneTap(renderResult.success);\n setPending(false);\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n shouldRenderOneTap,\n stytch,\n isUnmounted,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.signupRedirectURL,\n position,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n setCanDisplayOneTap(false);\n setPending(false);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n // Fallback Google auth button in case One Tap cannot be displayed\n const fallbackButton = (\n <OAuthButton\n providerType={OAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedOAuth(OAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === OAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (isOnlyFloatingOneTap) {\n return <OneTapMountNode enableShadowDOM={options.enableShadowDOM} />;\n }\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n if (shouldRenderEmbeddedOneTap && OneTapProvider.willGoogleOneTapShowEmbedded()) {\n return (\n <div className={classNames(styles.container, { [styles.pending]: pending })} style={{ height: height + 'px' }}>\n {pending && <CircularProgress size={25} />}\n {canDisplayOneTap ? <OneTapMountNode enableShadowDOM={options.enableShadowDOM} /> : fallbackButton}\n </div>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["OAUTH_BUTTON_HEIGHT","OneTapMountNode","enableShadowDOM","React","slot","name","div","data-prompt_parent_id","id","GoogleOneTap","position","customScopes","providerParams","cancelOnTapOutside","oneTapRenderMode","getRenderedOneTapMode","shouldRenderEmbeddedOneTap","shouldRenderOneTap","config","useConfig","stytch","useStytch","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","pending","setPending","useState","canDisplayOneTap","setCanDisplayOneTap","height","setHeight","oneTapError","setOneTapError","resizeCount","useRef","timeout","isUnmounted","useIsUnmounted","lastUsedMethod","setLastUsedOAuth","useLastUsedOAuth","options","usePresentation","onResize","useCallback","el","current","clearTimeout","currentHeight","contentRect","window","setTimeout","useEffect","document","getElementById","resizeObserver","ResizeObserver","observe","disconnect","attemptToLoadOneTap","oneTap","readB2CInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","NoConfiguredSignupRedirectUrls","NoConfiguredLoginRedirectUrls","logger","error","client","onOneTapCancelled","showError","OriginNotAllowedForClient","renderResult","render","callback","createOnSuccessHandler","loginRedirectUrl","oauthOptions","loginRedirectURL","signupRedirectUrl","signupRedirectURL","onSuccess","redirectOnSuccess","style","cancel","InvalidOAuthClient","then","$client","catch","err","fallbackButton","OAuthButton","providerType","OAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","OneTapProvider","willGoogleOneTapShowEmbedded","className","classNames","styles","container","CircularProgress","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GoogleOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2c/components/GoogleOneTap.tsx"],"sourcesContent":["import { DEV, logger, StringLiteralFromEnum } from '@stytch/core';\nimport { OAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { OneTapProvider } from '../../../oneTap/OneTapProvider';\nimport { getRenderedOneTapMode } from '../../../oneTap/positionModes';\nimport { readB2CInternals } from '../../../utils/internal';\nimport { CircularProgress } from '../../components/atoms/CircularProgress';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport { useIsMounted } from '../../hooks/useIsMounted';\nimport { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth';\nimport styles from './GoogleOneTap.module.css';\nimport { OAuthButton } from './OAuthButton';\n\ntype Props = {\n position?: StringLiteralFromEnum<OneTapPositions>;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nconst OAUTH_BUTTON_HEIGHT = 38;\n\n// See WebComponents.tsx - when using shadow DOM, the Google script cannot see the\n// mount point, so we render it outside and use slot to bring it back in\nconst OneTapMountNode = ({ enableShadowDOM }: { enableShadowDOM: boolean | undefined }) =>\n enableShadowDOM ? (\n <slot name=\"one-tap\"></slot>\n ) : (\n <div data-prompt_parent_id=\"g_id_onload\" id=\"google-parent-prompt\" />\n );\n\nexport const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutside }: Props) => {\n const oneTapRenderMode = getRenderedOneTapMode(position);\n const shouldRenderEmbeddedOneTap = oneTapRenderMode === 'embedded';\n const shouldRenderOneTap = !!oneTapRenderMode;\n\n const config = useConfig();\n const stytch = useStytch();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap(config);\n const [pending, setPending] = useState(shouldRenderEmbeddedOneTap);\n const [canDisplayOneTap, setCanDisplayOneTap] = useState(true);\n const [height, setHeight] = useState(OAUTH_BUTTON_HEIGHT);\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const resizeCount = useRef(0);\n const timeout = useRef<number>();\n const isMounted = useIsMounted();\n const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();\n const { options } = usePresentation();\n\n /*\n * Begin One Tap Render Smoothing Logic\n */\n // Gets height of rendered one-tap UI, and sets the container height to that.\n // Animation is added for a smoother transition,\n const onResize = useCallback<ResizeObserverCallback>(([el]) => {\n if (timeout.current != null) {\n clearTimeout(timeout.current);\n }\n // On initial load, the one-tap ui rapidly changes heights 3 times. Checking\n // the resizeCount lets us debounce the first 2 resizes, so they will get\n // cancelled, but if they don't, it will resize after the short delay.\n if (resizeCount.current > 1) {\n // While setting the height, if the contentRect height is 0, it could also mean that the\n // oauthOptions props are being changed, and in that scenario if we can continue to display\n // one tap, we are setting the container height to the current height. If one tap cannot display\n // one tap, we will set the container height to the height of the button component.\n // Else we will set the height to the contentRect height.\n setHeight((currentHeight) =>\n el.contentRect.height === 0 ? (canDisplayOneTap ? currentHeight : OAUTH_BUTTON_HEIGHT) : el.contentRect.height,\n );\n } else {\n timeout.current = window.setTimeout(\n () =>\n setHeight((currentHeight) =>\n el.contentRect.height === 0\n ? canDisplayOneTap\n ? currentHeight\n : OAUTH_BUTTON_HEIGHT\n : el.contentRect.height,\n ),\n 100,\n );\n }\n resizeCount.current++;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- SDK-1354\n }, []);\n\n // If we are in embedded mode, initialize the resize observer and bind it to the React callback\n useEffect(() => {\n if (shouldRenderEmbeddedOneTap) {\n const el = document.getElementById('google-parent-prompt');\n if (el) {\n const resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(el);\n return () => resizeObserver.disconnect();\n }\n }\n }, [onResize, shouldRenderEmbeddedOneTap]);\n /*\n * End One Tap Render Smoothing Logic\n */\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n if (!shouldRenderOneTap) {\n return;\n }\n\n const { oneTap } = readB2CInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'no_signup_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredSignupRedirectUrls);\n } else if (clientResult.reason === 'no_login_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredLoginRedirectUrls);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n const onOneTapCancelled = (showError?: boolean) => {\n setCanDisplayOneTap(false);\n setHeight(OAUTH_BUTTON_HEIGHT);\n if (showError) {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n };\n\n /**\n * One Tap is composed of two calls, an init() call and a prompt() call.\n * The init() call takes in a parent_id where One Tap should be shown\n * prompt() does the actual showing.\n * If the element does not exist, we show One Tap in the upper right corner.\n * If the element does exist, One Tap's lifecycle is tied to the lifecycle of said element.\n * Here, we call init() then prompt() in the useEffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (!isMounted.current) {\n return;\n }\n\n const renderResult = await client.render({\n callback: oneTap.createOnSuccessHandler({\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n }),\n onOneTapCancelled,\n style: { position },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (!isMounted.current) {\n client.cancel();\n return;\n }\n\n setCanDisplayOneTap(renderResult.success);\n setPending(false);\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n shouldRenderOneTap,\n stytch,\n isMounted,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.signupRedirectURL,\n position,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n setCanDisplayOneTap(false);\n setPending(false);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n // Fallback Google auth button in case One Tap cannot be displayed\n const fallbackButton = (\n <OAuthButton\n providerType={OAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedOAuth(OAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === OAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (isOnlyFloatingOneTap) {\n return <OneTapMountNode enableShadowDOM={options.enableShadowDOM} />;\n }\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n if (shouldRenderEmbeddedOneTap && OneTapProvider.willGoogleOneTapShowEmbedded()) {\n return (\n <div className={classNames(styles.container, { [styles.pending]: pending })} style={{ height: height + 'px' }}>\n {pending && <CircularProgress size={25} />}\n {canDisplayOneTap ? <OneTapMountNode enableShadowDOM={options.enableShadowDOM} /> : fallbackButton}\n </div>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["OAUTH_BUTTON_HEIGHT","OneTapMountNode","enableShadowDOM","React","slot","name","div","data-prompt_parent_id","id","GoogleOneTap","position","customScopes","providerParams","cancelOnTapOutside","oneTapRenderMode","getRenderedOneTapMode","shouldRenderEmbeddedOneTap","shouldRenderOneTap","config","useConfig","stytch","useStytch","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","pending","setPending","useState","canDisplayOneTap","setCanDisplayOneTap","height","setHeight","oneTapError","setOneTapError","resizeCount","useRef","timeout","isMounted","useIsMounted","lastUsedMethod","setLastUsedOAuth","useLastUsedOAuth","options","usePresentation","onResize","useCallback","el","current","clearTimeout","currentHeight","contentRect","window","setTimeout","useEffect","document","getElementById","resizeObserver","ResizeObserver","observe","disconnect","attemptToLoadOneTap","oneTap","readB2CInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","NoConfiguredSignupRedirectUrls","NoConfiguredLoginRedirectUrls","logger","error","client","onOneTapCancelled","showError","OriginNotAllowedForClient","renderResult","render","callback","createOnSuccessHandler","loginRedirectUrl","oauthOptions","loginRedirectURL","signupRedirectUrl","signupRedirectURL","onSuccess","redirectOnSuccess","style","cancel","InvalidOAuthClient","then","$client","catch","err","fallbackButton","OAuthButton","providerType","OAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","OneTapProvider","willGoogleOneTapShowEmbedded","className","classNames","styles","container","CircularProgress","size"],"mappings":"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"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { useRef, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
useEffect(()=>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const useIsMounted = ()=>{
|
|
4
|
+
const isMounted = useRef(false);
|
|
5
|
+
useEffect(()=>{
|
|
6
|
+
isMounted.current = true;
|
|
7
|
+
return ()=>{
|
|
8
|
+
isMounted.current = false;
|
|
9
|
+
};
|
|
10
|
+
}, []);
|
|
11
|
+
return isMounted;
|
|
9
12
|
};
|
|
10
13
|
|
|
11
|
-
export {
|
|
14
|
+
export { useIsMounted };
|
|
12
15
|
//# sourceMappingURL=useIsMounted.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIsMounted.mjs","sources":["../../../../../../../../web/src/ui/hooks/useIsMounted.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef } from 'react';\n\nexport const
|
|
1
|
+
{"version":3,"file":"useIsMounted.mjs","sources":["../../../../../../../../web/src/ui/hooks/useIsMounted.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef } from 'react';\n\nexport const useIsMounted = (): MutableRefObject<boolean> => {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return isMounted;\n};\n"],"names":["useIsMounted","isMounted","useRef","useEffect","current"],"mappings":";;MAEaA,YAAAA,GAAe,IAAA;AAC1B,IAAA,MAAMC,YAAYC,MAAAA,CAAO,KAAA,CAAA;IAEzBC,SAAAA,CAAU,IAAA;AACRF,QAAAA,SAAAA,CAAUG,OAAO,GAAG,IAAA;QACpB,OAAO,IAAA;AACLH,YAAAA,SAAAA,CAAUG,OAAO,GAAG,KAAA;AACtB,QAAA,CAAA;AACF,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,OAAOH,SAAAA;AACT;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as bs58Exports } from '../../../../_virtual/
|
|
1
|
+
import { b as bs58Exports } from '../../../../_virtual/index3.mjs';
|
|
2
2
|
import 'react';
|
|
3
3
|
import { GenericWalletIcon } from '../assets/genericWallet.mjs';
|
|
4
4
|
import { usePresentation, getButtonId } from '../ui/components/PresentationConfig.mjs';
|
|
@@ -2,7 +2,7 @@ import React__default, { useState, useCallback, useEffect } from 'react';
|
|
|
2
2
|
import { readB2BInternals } from '../../../utils/internal.mjs';
|
|
3
3
|
import LastUsed from '../../components/molecules/LastUsed.mjs';
|
|
4
4
|
import { OneTapErrors, ErrorMessages } from '../../components/organisms/OneTapError.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { useIsMounted } from '../../hooks/useIsMounted.mjs';
|
|
6
6
|
import { useStytch, useConfig, useGlobalReducer } from '../GlobalContextProvider.mjs';
|
|
7
7
|
import { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap.mjs';
|
|
8
8
|
import { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod.mjs';
|
|
@@ -18,7 +18,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
18
18
|
const config = useConfig();
|
|
19
19
|
const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();
|
|
20
20
|
const [oneTapError, setOneTapError] = useState();
|
|
21
|
-
const
|
|
21
|
+
const isMounted = useIsMounted();
|
|
22
22
|
const [state, dispatch] = useGlobalReducer();
|
|
23
23
|
const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();
|
|
24
24
|
/*
|
|
@@ -48,7 +48,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
48
48
|
* prompt() is called, One Tap falls back to the element-does-not-exist behavior.
|
|
49
49
|
* Fix: add a check for whether the component is still rendered immediately before we
|
|
50
50
|
* call prompt, preventing this race condition
|
|
51
|
-
*/ if (
|
|
51
|
+
*/ if (!isMounted.current) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
let oneTapCallback;
|
|
@@ -82,7 +82,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
82
82
|
});
|
|
83
83
|
// Check if the component has become unmounted during the async OT render process
|
|
84
84
|
// Kill the rest of the logic if so
|
|
85
|
-
if (
|
|
85
|
+
if (!isMounted.current) {
|
|
86
86
|
client.cancel();
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
@@ -98,7 +98,7 @@ const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside })=>
|
|
|
98
98
|
return client;
|
|
99
99
|
}, [
|
|
100
100
|
stytch,
|
|
101
|
-
|
|
101
|
+
isMounted,
|
|
102
102
|
state.flowState.organization,
|
|
103
103
|
config.oauthOptions?.signupRedirectURL,
|
|
104
104
|
config.oauthOptions?.loginRedirectURL,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"B2BOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/B2BOneTap.tsx"],"sourcesContent":["import { DEV, logger } from '@stytch/core';\nimport { B2BOAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport type { CredentialResponse } from 'google-one-tap';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { readB2BInternals } from '../../../utils/internal';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { useIsUnmounted } from '../../hooks/useIsMounted';\nimport { useConfig, useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport { AppScreens } from '../types/AppScreens';\nimport { OAuthB2BButton } from './OAuthB2BButton';\n\nexport type B2BOneTapProps = {\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nexport const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside }: B2BOneTapProps) => {\n const stytch = useStytch();\n const config = useConfig();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const isUnmounted = useIsUnmounted();\n const [state, dispatch] = useGlobalReducer();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n const { oneTap } = readB2BInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'default_provider_not_allowed') {\n setOneTapError(OneTapErrors.DefaultProviderNotAllowed);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n /**\n * One tap is composed of two calls, an init() call and a prompt() call\n * the init() call takes in a parent_id where one tap should be shown\n * prompt() does the actual showing. if the element does not exist,\n * we show One Tap in the upper right corner\n * if the element does exist, One Tap's lifecycle is tied to the lifecycle of said element\n * here, we call init() then prompt() in the useeffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (isUnmounted.current) {\n return;\n }\n\n let oneTapCallback: (response: CredentialResponse) => void;\n if (state.flowState.organization) {\n oneTapCallback = oneTap.createOnSuccessHandler({\n organizationId: state.flowState.organization.organization_id,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n } else {\n oneTapCallback = oneTap.createOnDiscoverySuccessHandler({\n discoveryRedirectUrl: config.oauthOptions?.discoveryRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n }\n const renderResult = await client.render({\n callback: oneTapCallback,\n style: {\n position: OneTapPositions.floating,\n },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (isUnmounted.current) {\n client.cancel();\n return;\n }\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n stytch,\n isUnmounted,\n state.flowState.organization,\n config.oauthOptions?.signupRedirectURL,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.discoveryRedirectURL,\n dispatch,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n if (isOnlyFloatingOneTap) {\n return null;\n }\n\n const fallbackButton = (\n <OAuthB2BButton\n providerType={B2BOAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n discoveryRedirectUrl={config.oauthOptions?.discoveryRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedMethod(B2BOAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === B2BOAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["B2BGoogleOneTap","customScopes","providerParams","cancelOnTapOutside","stytch","useStytch","config","useConfig","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","oneTapError","setOneTapError","useState","isUnmounted","useIsUnmounted","state","dispatch","useGlobalReducer","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","attemptToLoadOneTap","useCallback","oneTap","readB2BInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","DefaultProviderNotAllowed","logger","error","client","current","oneTapCallback","flowState","organization","createOnSuccessHandler","organizationId","organization_id","signupRedirectUrl","oauthOptions","signupRedirectURL","loginRedirectUrl","loginRedirectURL","onSuccess","redirectOnSuccess","onError","type","screen","AppScreens","Error","createOnDiscoverySuccessHandler","discoveryRedirectUrl","discoveryRedirectURL","renderResult","render","callback","style","position","OneTapPositions","floating","cancel","OriginNotAllowedForClient","InvalidOAuthClient","useEffect","then","$client","catch","err","fallbackButton","React","OAuthB2BButton","providerType","B2BOAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","ErrorMessages"],"mappings":";;;;;;;;;;;;;;;AAsBO,MAAMA,kBAAkB,CAAC,EAAEC,YAAY,EAAEC,cAAc,EAAEC,kBAAkB,EAAkB,GAAA;AAClG,IAAA,MAAMC,MAAAA,GAASC,SAAAA,EAAAA;AACf,IAAA,MAAMC,MAAAA,GAASC,SAAAA,EAAAA;AACf,IAAA,MAAMC,oBAAAA,GAAuBC,uBAAAA,EAAAA;IAC7B,MAAM,CAACC,WAAAA,EAAaC,cAAAA,CAAe,GAAGC,QAAAA,EAAAA;AACtC,IAAA,MAAMC,WAAAA,GAAcC,cAAAA,EAAAA;IACpB,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGC,gBAAAA,EAAAA;IAE1B,MAAM,CAACC,cAAAA,EAAgBC,iBAAAA,CAAkB,GAAGC,qBAAAA,EAAAA;AAE5C;;AAEC;AAED,IAAA,MAAMC,sBAAsBC,WAAAA,CAAY,UAAA;AACtC,QAAA,MAAM,EAAEC,MAAM,EAAE,GAAGC,gBAAAA,CAAiBpB,MAAAA,CAAAA;QACpC,MAAMqB,YAAAA,GAAe,MAAMF,MAAAA,CAAOG,kBAAkB,EAAA;QACpD,IAAI,CAACD,YAAAA,CAAaE,OAAO,EAAE;YACzB,IAAIF,YAAAA,CAAaG,MAAM,KAAK,wBAAA,EAA0B;AACpDjB,gBAAAA,cAAAA,CAAekB,aAAaC,uBAAuB,CAAA;AACrD,YAAA,CAAA,MAAO,IAAIL,YAAAA,CAAaG,MAAM,KAAK,8BAAA,EAAgC;AACjEjB,gBAAAA,cAAAA,CAAekB,aAAaE,yBAAyB,CAAA;YACvD,CAAA,MAAO;gBACLC,MAAAA,CAAOC,KAAK,CAAC,6CAAA,EAA+CR,YAAAA,CAAAA;AAC9D,YAAA;AACA,YAAA;AACF,QAAA;QACA,MAAM,EAAES,MAAM,EAAE,GAAGT,YAAAA;AAEnB;;;;;;;;;;QAWA,IAAIZ,WAAAA,CAAYsB,OAAO,EAAE;AACvB,YAAA;AACF,QAAA;QAEA,IAAIC,cAAAA;AACJ,QAAA,IAAIrB,KAAAA,CAAMsB,SAAS,CAACC,YAAY,EAAE;YAChCF,cAAAA,GAAiBb,MAAAA,CAAOgB,sBAAsB,CAAC;AAC7CC,gBAAAA,cAAAA,EAAgBzB,KAAAA,CAAMsB,SAAS,CAACC,YAAY,CAACG,eAAe;gBAC5DC,iBAAAA,EAAmBpC,MAAAA,CAAOqC,YAAY,EAAEC,iBAAAA;gBACxCC,gBAAAA,EAAkBvC,MAAAA,CAAOqC,YAAY,EAAEG,gBAAAA;AACvCC,gBAAAA,SAAAA,EAAWxB,OAAOyB,iBAAiB;AACnCC,gBAAAA,OAAAA,EAAS,IAAMjC,QAAAA,CAAS;wBAAEkC,IAAAA,EAAM,YAAA;AAAcC,wBAAAA,MAAAA,EAAQC,WAAWC;AAAM,qBAAA;AACzE,aAAA,CAAA;QACF,CAAA,MAAO;YACLjB,cAAAA,GAAiBb,MAAAA,CAAO+B,+BAA+B,CAAC;gBACtDC,oBAAAA,EAAsBjD,MAAAA,CAAOqC,YAAY,EAAEa,oBAAAA;AAC3CT,gBAAAA,SAAAA,EAAWxB,OAAOyB,iBAAiB;AACnCC,gBAAAA,OAAAA,EAAS,IAAMjC,QAAAA,CAAS;wBAAEkC,IAAAA,EAAM,YAAA;AAAcC,wBAAAA,MAAAA,EAAQC,WAAWC;AAAM,qBAAA;AACzE,aAAA,CAAA;AACF,QAAA;AACA,QAAA,MAAMI,YAAAA,GAAe,MAAMvB,MAAAA,CAAOwB,MAAM,CAAC;YACvCC,QAAAA,EAAUvB,cAAAA;YACVwB,KAAAA,EAAO;AACLC,gBAAAA,QAAAA,EAAUC,gBAAgBC;AAC5B,aAAA;AACA5D,YAAAA;AACF,SAAA,CAAA;;;QAIA,IAAIU,WAAAA,CAAYsB,OAAO,EAAE;AACvBD,YAAAA,MAAAA,CAAO8B,MAAM,EAAA;AACb,YAAA;AACF,QAAA;QAEA,IAAI,CAACP,YAAAA,CAAa9B,OAAO,EAAE;YACzB,IAAI8B,YAAAA,CAAa7B,MAAM,KAAK,qBAAA,EAAuB;AACjDjB,gBAAAA,cAAAA,CAAekB,aAAaoC,yBAAyB,CAAA;AACvD,YAAA;YACA,IAAIR,YAAAA,CAAa7B,MAAM,KAAK,gBAAA,EAAkB;AAC5CjB,gBAAAA,cAAAA,CAAekB,aAAaqC,kBAAkB,CAAA;AAChD,YAAA;YACAlC,MAAAA,CAAOC,KAAK,CAAC,iCAAA,EAAmCwB,YAAAA,CAAAA;AAClD,QAAA;QACA,OAAOvB,MAAAA;IACT,CAAA,EAAG;AACD9B,QAAAA,MAAAA;AACAS,QAAAA,WAAAA;QACAE,KAAAA,CAAMsB,SAAS,CAACC,YAAY;AAC5BhC,QAAAA,MAAAA,CAAOqC,YAAY,EAAEC,iBAAAA;AACrBtC,QAAAA,MAAAA,CAAOqC,YAAY,EAAEG,gBAAAA;AACrBxC,QAAAA,MAAAA,CAAOqC,YAAY,EAAEa,oBAAAA;AACrBxC,QAAAA,QAAAA;AACAb,QAAAA;AACD,KAAA,CAAA;IAEDgE,SAAAA,CAAU,IAAA;QACR,IAAIjC,MAAAA;QACJb,mBAAAA,EAAAA,CACG+C,IAAI,CAAC,CAACC,OAAAA,GAAanC,SAASmC,OAAAA,CAAAA,CAC5BC,KAAK,CAAC,CAACC,GAAAA,GAAAA;YACNvC,MAAAA,CAAOC,KAAK,CAAC,iCAAA,EAAmCsC,GAAAA,CAAAA;AAClD,QAAA,CAAA,CAAA;AACF,QAAA,OAAO,IAAMrC,MAAAA,EAAQ8B,MAAAA,EAAAA;IACvB,CAAA,EAAG;AAAC3C,QAAAA;AAAoB,KAAA,CAAA;AACxB;;AAEC,MAED,IAAIb,oBAAAA,EAAsB;QACxB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,MAAMgE,+BACJC,cAAA,CAAA,aAAA,CAACC,cAAAA,EAAAA;AACCC,QAAAA,YAAAA,EAAcC,kBAAkBC,MAAM;QACtChC,gBAAAA,EAAkBvC,MAAAA,CAAOqC,YAAY,EAAEG,gBAAAA;QACvCJ,iBAAAA,EAAmBpC,MAAAA,CAAOqC,YAAY,EAAEC,iBAAAA;QACxCW,oBAAAA,EAAsBjD,MAAAA,CAAOqC,YAAY,EAAEa,oBAAAA;QAC3CvD,YAAAA,EAAcA,YAAAA;QACdC,cAAAA,EAAgBA,cAAAA;QAChB6C,SAAAA,EAAW,IAAM5B,iBAAAA,CAAkByD,iBAAAA,CAAkBC,MAAM;;AAI/D,IAAA,MAAMC,uBACJ5D,cAAAA,KAAmB0D,iBAAAA,CAAkBC,MAAM,iBAAGJ,cAAA,CAAA,aAAA,CAACM,gBAAUP,cAAAA,CAAAA,GAA6BA,cAAAA;AAExF,IAAA,IAAI9D,WAAAA,EAAa;QACf,qBACE+D,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA,EACGO,kBAAIP,cAAA,CAAA,aAAA,CAACQ,aAAAA,EAAAA;YAAchD,KAAAA,EAAOvB;AAC1BoE,SAAAA,CAAAA,CAAAA,EAAAA,oBAAAA,CAAAA;AAGP,IAAA;IAEA,OAAOA,oBAAAA;AACT;;;;"}
|
|
1
|
+
{"version":3,"file":"B2BOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2b/components/B2BOneTap.tsx"],"sourcesContent":["import { DEV, logger } from '@stytch/core';\nimport { B2BOAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport type { CredentialResponse } from 'google-one-tap';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { readB2BInternals } from '../../../utils/internal';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { useIsMounted } from '../../hooks/useIsMounted';\nimport { useConfig, useGlobalReducer, useStytch } from '../GlobalContextProvider';\nimport { useIsOnlyFloatingOneTap } from '../hooks/useIsOnlyFloatingOneTap';\nimport { useLastUsedAuthMethod } from '../hooks/useLastUsedAuthMethod';\nimport { AppScreens } from '../types/AppScreens';\nimport { OAuthB2BButton } from './OAuthB2BButton';\n\nexport type B2BOneTapProps = {\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nexport const B2BGoogleOneTap = ({ customScopes, providerParams, cancelOnTapOutside }: B2BOneTapProps) => {\n const stytch = useStytch();\n const config = useConfig();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap();\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const isMounted = useIsMounted();\n const [state, dispatch] = useGlobalReducer();\n\n const [lastUsedMethod, setLastUsedMethod] = useLastUsedAuthMethod();\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n const { oneTap } = readB2BInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'default_provider_not_allowed') {\n setOneTapError(OneTapErrors.DefaultProviderNotAllowed);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n /**\n * One tap is composed of two calls, an init() call and a prompt() call\n * the init() call takes in a parent_id where one tap should be shown\n * prompt() does the actual showing. if the element does not exist,\n * we show One Tap in the upper right corner\n * if the element does exist, One Tap's lifecycle is tied to the lifecycle of said element\n * here, we call init() then prompt() in the useeffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (!isMounted.current) {\n return;\n }\n\n let oneTapCallback: (response: CredentialResponse) => void;\n if (state.flowState.organization) {\n oneTapCallback = oneTap.createOnSuccessHandler({\n organizationId: state.flowState.organization.organization_id,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n } else {\n oneTapCallback = oneTap.createOnDiscoverySuccessHandler({\n discoveryRedirectUrl: config.oauthOptions?.discoveryRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n onError: () => dispatch({ type: 'transition', screen: AppScreens.Error }),\n });\n }\n const renderResult = await client.render({\n callback: oneTapCallback,\n style: {\n position: OneTapPositions.floating,\n },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (!isMounted.current) {\n client.cancel();\n return;\n }\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n stytch,\n isMounted,\n state.flowState.organization,\n config.oauthOptions?.signupRedirectURL,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.discoveryRedirectURL,\n dispatch,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n if (isOnlyFloatingOneTap) {\n return null;\n }\n\n const fallbackButton = (\n <OAuthB2BButton\n providerType={B2BOAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n discoveryRedirectUrl={config.oauthOptions?.discoveryRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedMethod(B2BOAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === B2BOAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["B2BGoogleOneTap","customScopes","providerParams","cancelOnTapOutside","stytch","useStytch","config","useConfig","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","oneTapError","setOneTapError","useState","isMounted","useIsMounted","state","dispatch","useGlobalReducer","lastUsedMethod","setLastUsedMethod","useLastUsedAuthMethod","attemptToLoadOneTap","useCallback","oneTap","readB2BInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","DefaultProviderNotAllowed","logger","error","client","current","oneTapCallback","flowState","organization","createOnSuccessHandler","organizationId","organization_id","signupRedirectUrl","oauthOptions","signupRedirectURL","loginRedirectUrl","loginRedirectURL","onSuccess","redirectOnSuccess","onError","type","screen","AppScreens","Error","createOnDiscoverySuccessHandler","discoveryRedirectUrl","discoveryRedirectURL","renderResult","render","callback","style","position","OneTapPositions","floating","cancel","OriginNotAllowedForClient","InvalidOAuthClient","useEffect","then","$client","catch","err","fallbackButton","React","OAuthB2BButton","providerType","B2BOAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","ErrorMessages"],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { CircularProgress } from '../../components/atoms/CircularProgress.mjs';
|
|
|
7
7
|
import LastUsed from '../../components/molecules/LastUsed.mjs';
|
|
8
8
|
import { OneTapErrors, ErrorMessages } from '../../components/organisms/OneTapError.mjs';
|
|
9
9
|
import { usePresentation } from '../../components/PresentationConfig.mjs';
|
|
10
|
-
import {
|
|
10
|
+
import { useIsMounted } from '../../hooks/useIsMounted.mjs';
|
|
11
11
|
import { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap.mjs';
|
|
12
12
|
import { useConfig, useStytch } from '../GlobalContextProvider.mjs';
|
|
13
13
|
import { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth.mjs';
|
|
@@ -39,7 +39,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
39
39
|
const [oneTapError, setOneTapError] = useState();
|
|
40
40
|
const resizeCount = useRef(0);
|
|
41
41
|
const timeout = useRef();
|
|
42
|
-
const
|
|
42
|
+
const isMounted = useIsMounted();
|
|
43
43
|
const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();
|
|
44
44
|
const { options } = usePresentation();
|
|
45
45
|
/*
|
|
@@ -121,7 +121,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
121
121
|
* prompt() is called, One Tap falls back to the element-does-not-exist behavior.
|
|
122
122
|
* Fix: add a check for whether the component is still rendered immediately before we
|
|
123
123
|
* call prompt, preventing this race condition
|
|
124
|
-
*/ if (
|
|
124
|
+
*/ if (!isMounted.current) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
const renderResult = await client.render({
|
|
@@ -138,7 +138,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
138
138
|
});
|
|
139
139
|
// Check if the component has become unmounted during the async OT render process
|
|
140
140
|
// Kill the rest of the logic if so
|
|
141
|
-
if (
|
|
141
|
+
if (!isMounted.current) {
|
|
142
142
|
client.cancel();
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
@@ -157,7 +157,7 @@ const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutsi
|
|
|
157
157
|
}, [
|
|
158
158
|
shouldRenderOneTap,
|
|
159
159
|
stytch,
|
|
160
|
-
|
|
160
|
+
isMounted,
|
|
161
161
|
config.oauthOptions?.loginRedirectURL,
|
|
162
162
|
config.oauthOptions?.signupRedirectURL,
|
|
163
163
|
position,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2c/components/GoogleOneTap.tsx"],"sourcesContent":["import { DEV, logger, StringLiteralFromEnum } from '@stytch/core';\nimport { OAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { OneTapProvider } from '../../../oneTap/OneTapProvider';\nimport { getRenderedOneTapMode } from '../../../oneTap/positionModes';\nimport { readB2CInternals } from '../../../utils/internal';\nimport { CircularProgress } from '../../components/atoms/CircularProgress';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport { useIsUnmounted } from '../../hooks/useIsMounted';\nimport { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth';\nimport styles from './GoogleOneTap.module.css';\nimport { OAuthButton } from './OAuthButton';\n\ntype Props = {\n position?: StringLiteralFromEnum<OneTapPositions>;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nconst OAUTH_BUTTON_HEIGHT = 38;\n\n// See WebComponents.tsx - when using shadow DOM, the Google script cannot see the\n// mount point, so we render it outside and use slot to bring it back in\nconst OneTapMountNode = ({ enableShadowDOM }: { enableShadowDOM: boolean | undefined }) =>\n enableShadowDOM ? (\n <slot name=\"one-tap\"></slot>\n ) : (\n <div data-prompt_parent_id=\"g_id_onload\" id=\"google-parent-prompt\" />\n );\n\nexport const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutside }: Props) => {\n const oneTapRenderMode = getRenderedOneTapMode(position);\n const shouldRenderEmbeddedOneTap = oneTapRenderMode === 'embedded';\n const shouldRenderOneTap = !!oneTapRenderMode;\n\n const config = useConfig();\n const stytch = useStytch();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap(config);\n const [pending, setPending] = useState(shouldRenderEmbeddedOneTap);\n const [canDisplayOneTap, setCanDisplayOneTap] = useState(true);\n const [height, setHeight] = useState(OAUTH_BUTTON_HEIGHT);\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const resizeCount = useRef(0);\n const timeout = useRef<number>();\n const isUnmounted = useIsUnmounted();\n const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();\n const { options } = usePresentation();\n\n /*\n * Begin One Tap Render Smoothing Logic\n */\n // Gets height of rendered one-tap UI, and sets the container height to that.\n // Animation is added for a smoother transition,\n const onResize = useCallback<ResizeObserverCallback>(([el]) => {\n if (timeout.current != null) {\n clearTimeout(timeout.current);\n }\n // On initial load, the one-tap ui rapidly changes heights 3 times. Checking\n // the resizeCount lets us debounce the first 2 resizes, so they will get\n // cancelled, but if they don't, it will resize after the short delay.\n if (resizeCount.current > 1) {\n // While setting the height, if the contentRect height is 0, it could also mean that the\n // oauthOptions props are being changed, and in that scenario if we can continue to display\n // one tap, we are setting the container height to the current height. If one tap cannot display\n // one tap, we will set the container height to the height of the button component.\n // Else we will set the height to the contentRect height.\n setHeight((currentHeight) =>\n el.contentRect.height === 0 ? (canDisplayOneTap ? currentHeight : OAUTH_BUTTON_HEIGHT) : el.contentRect.height,\n );\n } else {\n timeout.current = window.setTimeout(\n () =>\n setHeight((currentHeight) =>\n el.contentRect.height === 0\n ? canDisplayOneTap\n ? currentHeight\n : OAUTH_BUTTON_HEIGHT\n : el.contentRect.height,\n ),\n 100,\n );\n }\n resizeCount.current++;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- SDK-1354\n }, []);\n\n // If we are in embedded mode, initialize the resize observer and bind it to the React callback\n useEffect(() => {\n if (shouldRenderEmbeddedOneTap) {\n const el = document.getElementById('google-parent-prompt');\n if (el) {\n const resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(el);\n return () => resizeObserver.disconnect();\n }\n }\n }, [onResize, shouldRenderEmbeddedOneTap]);\n /*\n * End One Tap Render Smoothing Logic\n */\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n if (!shouldRenderOneTap) {\n return;\n }\n\n const { oneTap } = readB2CInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'no_signup_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredSignupRedirectUrls);\n } else if (clientResult.reason === 'no_login_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredLoginRedirectUrls);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n const onOneTapCancelled = (showError?: boolean) => {\n setCanDisplayOneTap(false);\n setHeight(OAUTH_BUTTON_HEIGHT);\n if (showError) {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n };\n\n /**\n * One Tap is composed of two calls, an init() call and a prompt() call.\n * The init() call takes in a parent_id where One Tap should be shown\n * prompt() does the actual showing.\n * If the element does not exist, we show One Tap in the upper right corner.\n * If the element does exist, One Tap's lifecycle is tied to the lifecycle of said element.\n * Here, we call init() then prompt() in the useEffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (isUnmounted.current) {\n return;\n }\n\n const renderResult = await client.render({\n callback: oneTap.createOnSuccessHandler({\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n }),\n onOneTapCancelled,\n style: { position },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (isUnmounted.current) {\n client.cancel();\n return;\n }\n\n setCanDisplayOneTap(renderResult.success);\n setPending(false);\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n shouldRenderOneTap,\n stytch,\n isUnmounted,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.signupRedirectURL,\n position,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n setCanDisplayOneTap(false);\n setPending(false);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n // Fallback Google auth button in case One Tap cannot be displayed\n const fallbackButton = (\n <OAuthButton\n providerType={OAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedOAuth(OAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === OAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (isOnlyFloatingOneTap) {\n return <OneTapMountNode enableShadowDOM={options.enableShadowDOM} />;\n }\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n if (shouldRenderEmbeddedOneTap && OneTapProvider.willGoogleOneTapShowEmbedded()) {\n return (\n <div className={classNames(styles.container, { [styles.pending]: pending })} style={{ height: height + 'px' }}>\n {pending && <CircularProgress size={25} />}\n {canDisplayOneTap ? <OneTapMountNode enableShadowDOM={options.enableShadowDOM} /> : fallbackButton}\n </div>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["OAUTH_BUTTON_HEIGHT","OneTapMountNode","enableShadowDOM","React","slot","name","div","data-prompt_parent_id","id","GoogleOneTap","position","customScopes","providerParams","cancelOnTapOutside","oneTapRenderMode","getRenderedOneTapMode","shouldRenderEmbeddedOneTap","shouldRenderOneTap","config","useConfig","stytch","useStytch","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","pending","setPending","useState","canDisplayOneTap","setCanDisplayOneTap","height","setHeight","oneTapError","setOneTapError","resizeCount","useRef","timeout","isUnmounted","useIsUnmounted","lastUsedMethod","setLastUsedOAuth","useLastUsedOAuth","options","usePresentation","onResize","useCallback","el","current","clearTimeout","currentHeight","contentRect","window","setTimeout","useEffect","document","getElementById","resizeObserver","ResizeObserver","observe","disconnect","attemptToLoadOneTap","oneTap","readB2CInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","NoConfiguredSignupRedirectUrls","NoConfiguredLoginRedirectUrls","logger","error","client","onOneTapCancelled","showError","OriginNotAllowedForClient","renderResult","render","callback","createOnSuccessHandler","loginRedirectUrl","oauthOptions","loginRedirectURL","signupRedirectUrl","signupRedirectURL","onSuccess","redirectOnSuccess","style","cancel","InvalidOAuthClient","then","$client","catch","err","fallbackButton","OAuthButton","providerType","OAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","ErrorMessages","OneTapProvider","willGoogleOneTapShowEmbedded","className","classNames","styles","container","CircularProgress","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GoogleOneTap.mjs","sources":["../../../../../../../../../web/src/ui/b2c/components/GoogleOneTap.tsx"],"sourcesContent":["import { DEV, logger, StringLiteralFromEnum } from '@stytch/core';\nimport { OAuthProviders, OneTapPositions } from '@stytch/core/public';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { GoogleOneTapClient } from '../../../oneTap/GoogleOneTapClient';\nimport { OneTapProvider } from '../../../oneTap/OneTapProvider';\nimport { getRenderedOneTapMode } from '../../../oneTap/positionModes';\nimport { readB2CInternals } from '../../../utils/internal';\nimport { CircularProgress } from '../../components/atoms/CircularProgress';\nimport LastUsed from '../../components/molecules/LastUsed';\nimport { ErrorMessages, OneTapErrors } from '../../components/organisms/OneTapError';\nimport { usePresentation } from '../../components/PresentationConfig';\nimport { useIsMounted } from '../../hooks/useIsMounted';\nimport { useIsOnlyFloatingOneTap } from '../../hooks/useIsOnlyFloatingOneTap';\nimport { useConfig, useStytch } from '../GlobalContextProvider';\nimport { useLastUsedOAuth } from '../screens/Main/useLastUsedOAuth';\nimport styles from './GoogleOneTap.module.css';\nimport { OAuthButton } from './OAuthButton';\n\ntype Props = {\n position?: StringLiteralFromEnum<OneTapPositions>;\n customScopes?: string[];\n providerParams?: Record<string, string>;\n cancelOnTapOutside?: boolean;\n};\n\nconst OAUTH_BUTTON_HEIGHT = 38;\n\n// See WebComponents.tsx - when using shadow DOM, the Google script cannot see the\n// mount point, so we render it outside and use slot to bring it back in\nconst OneTapMountNode = ({ enableShadowDOM }: { enableShadowDOM: boolean | undefined }) =>\n enableShadowDOM ? (\n <slot name=\"one-tap\"></slot>\n ) : (\n <div data-prompt_parent_id=\"g_id_onload\" id=\"google-parent-prompt\" />\n );\n\nexport const GoogleOneTap = ({ position, customScopes, providerParams, cancelOnTapOutside }: Props) => {\n const oneTapRenderMode = getRenderedOneTapMode(position);\n const shouldRenderEmbeddedOneTap = oneTapRenderMode === 'embedded';\n const shouldRenderOneTap = !!oneTapRenderMode;\n\n const config = useConfig();\n const stytch = useStytch();\n const isOnlyFloatingOneTap = useIsOnlyFloatingOneTap(config);\n const [pending, setPending] = useState(shouldRenderEmbeddedOneTap);\n const [canDisplayOneTap, setCanDisplayOneTap] = useState(true);\n const [height, setHeight] = useState(OAUTH_BUTTON_HEIGHT);\n const [oneTapError, setOneTapError] = useState<OneTapErrors>();\n const resizeCount = useRef(0);\n const timeout = useRef<number>();\n const isMounted = useIsMounted();\n const [lastUsedMethod, setLastUsedOAuth] = useLastUsedOAuth();\n const { options } = usePresentation();\n\n /*\n * Begin One Tap Render Smoothing Logic\n */\n // Gets height of rendered one-tap UI, and sets the container height to that.\n // Animation is added for a smoother transition,\n const onResize = useCallback<ResizeObserverCallback>(([el]) => {\n if (timeout.current != null) {\n clearTimeout(timeout.current);\n }\n // On initial load, the one-tap ui rapidly changes heights 3 times. Checking\n // the resizeCount lets us debounce the first 2 resizes, so they will get\n // cancelled, but if they don't, it will resize after the short delay.\n if (resizeCount.current > 1) {\n // While setting the height, if the contentRect height is 0, it could also mean that the\n // oauthOptions props are being changed, and in that scenario if we can continue to display\n // one tap, we are setting the container height to the current height. If one tap cannot display\n // one tap, we will set the container height to the height of the button component.\n // Else we will set the height to the contentRect height.\n setHeight((currentHeight) =>\n el.contentRect.height === 0 ? (canDisplayOneTap ? currentHeight : OAUTH_BUTTON_HEIGHT) : el.contentRect.height,\n );\n } else {\n timeout.current = window.setTimeout(\n () =>\n setHeight((currentHeight) =>\n el.contentRect.height === 0\n ? canDisplayOneTap\n ? currentHeight\n : OAUTH_BUTTON_HEIGHT\n : el.contentRect.height,\n ),\n 100,\n );\n }\n resizeCount.current++;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- SDK-1354\n }, []);\n\n // If we are in embedded mode, initialize the resize observer and bind it to the React callback\n useEffect(() => {\n if (shouldRenderEmbeddedOneTap) {\n const el = document.getElementById('google-parent-prompt');\n if (el) {\n const resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(el);\n return () => resizeObserver.disconnect();\n }\n }\n }, [onResize, shouldRenderEmbeddedOneTap]);\n /*\n * End One Tap Render Smoothing Logic\n */\n\n /*\n * Begin One Tap Loading / Initialization Logic\n */\n //\n const attemptToLoadOneTap = useCallback(async () => {\n if (!shouldRenderOneTap) {\n return;\n }\n\n const { oneTap } = readB2CInternals(stytch);\n const clientResult = await oneTap.createOneTapClient();\n if (!clientResult.success) {\n if (clientResult.reason === 'oauth_config_not_found') {\n setOneTapError(OneTapErrors.NoConfiguredOAuthClient);\n } else if (clientResult.reason === 'no_signup_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredSignupRedirectUrls);\n } else if (clientResult.reason === 'no_login_redirect_urls_set') {\n setOneTapError(OneTapErrors.NoConfiguredLoginRedirectUrls);\n } else {\n logger.error('Unable to load One Tap settings for project', clientResult);\n }\n return;\n }\n const { client } = clientResult;\n\n const onOneTapCancelled = (showError?: boolean) => {\n setCanDisplayOneTap(false);\n setHeight(OAUTH_BUTTON_HEIGHT);\n if (showError) {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n };\n\n /**\n * One Tap is composed of two calls, an init() call and a prompt() call.\n * The init() call takes in a parent_id where One Tap should be shown\n * prompt() does the actual showing.\n * If the element does not exist, we show One Tap in the upper right corner.\n * If the element does exist, One Tap's lifecycle is tied to the lifecycle of said element.\n * Here, we call init() then prompt() in the useEffect. If the component unmounts before\n * prompt() is called, One Tap falls back to the element-does-not-exist behavior.\n * Fix: add a check for whether the component is still rendered immediately before we\n * call prompt, preventing this race condition\n */\n if (!isMounted.current) {\n return;\n }\n\n const renderResult = await client.render({\n callback: oneTap.createOnSuccessHandler({\n loginRedirectUrl: config.oauthOptions?.loginRedirectURL,\n signupRedirectUrl: config.oauthOptions?.signupRedirectURL,\n onSuccess: oneTap.redirectOnSuccess,\n }),\n onOneTapCancelled,\n style: { position },\n cancelOnTapOutside,\n });\n\n // Check if the component has become unmounted during the async OT render process\n // Kill the rest of the logic if so\n if (!isMounted.current) {\n client.cancel();\n return;\n }\n\n setCanDisplayOneTap(renderResult.success);\n setPending(false);\n\n if (!renderResult.success) {\n if (renderResult.reason === 'unregistered_origin') {\n setOneTapError(OneTapErrors.OriginNotAllowedForClient);\n }\n if (renderResult.reason === 'invalid_client') {\n setOneTapError(OneTapErrors.InvalidOAuthClient);\n }\n logger.error('Unable to render One Tap prompt', renderResult);\n }\n return client;\n }, [\n shouldRenderOneTap,\n stytch,\n isMounted,\n config.oauthOptions?.loginRedirectURL,\n config.oauthOptions?.signupRedirectURL,\n position,\n cancelOnTapOutside,\n ]);\n\n useEffect(() => {\n let client: GoogleOneTapClient | undefined;\n attemptToLoadOneTap()\n .then(($client) => (client = $client))\n .catch((err) => {\n logger.error('Unable to render One Tap prompt', err);\n setCanDisplayOneTap(false);\n setPending(false);\n });\n return () => client?.cancel();\n }, [attemptToLoadOneTap]);\n /*\n * End One Tap Loading / Initialization Logic\n */\n\n // Fallback Google auth button in case One Tap cannot be displayed\n const fallbackButton = (\n <OAuthButton\n providerType={OAuthProviders.Google}\n loginRedirectUrl={config.oauthOptions?.loginRedirectURL}\n signupRedirectUrl={config.oauthOptions?.signupRedirectURL}\n customScopes={customScopes}\n providerParams={providerParams}\n onSuccess={() => setLastUsedOAuth(OAuthProviders.Google)}\n />\n );\n\n const fallbackWithLastUsed =\n lastUsedMethod === OAuthProviders.Google ? <LastUsed>{fallbackButton}</LastUsed> : fallbackButton;\n\n if (isOnlyFloatingOneTap) {\n return <OneTapMountNode enableShadowDOM={options.enableShadowDOM} />;\n }\n\n if (oneTapError) {\n return (\n <>\n {DEV(<ErrorMessages error={oneTapError} />)}\n {fallbackWithLastUsed}\n </>\n );\n }\n\n if (shouldRenderEmbeddedOneTap && OneTapProvider.willGoogleOneTapShowEmbedded()) {\n return (\n <div className={classNames(styles.container, { [styles.pending]: pending })} style={{ height: height + 'px' }}>\n {pending && <CircularProgress size={25} />}\n {canDisplayOneTap ? <OneTapMountNode enableShadowDOM={options.enableShadowDOM} /> : fallbackButton}\n </div>\n );\n }\n\n return fallbackWithLastUsed;\n};\n"],"names":["OAUTH_BUTTON_HEIGHT","OneTapMountNode","enableShadowDOM","React","slot","name","div","data-prompt_parent_id","id","GoogleOneTap","position","customScopes","providerParams","cancelOnTapOutside","oneTapRenderMode","getRenderedOneTapMode","shouldRenderEmbeddedOneTap","shouldRenderOneTap","config","useConfig","stytch","useStytch","isOnlyFloatingOneTap","useIsOnlyFloatingOneTap","pending","setPending","useState","canDisplayOneTap","setCanDisplayOneTap","height","setHeight","oneTapError","setOneTapError","resizeCount","useRef","timeout","isMounted","useIsMounted","lastUsedMethod","setLastUsedOAuth","useLastUsedOAuth","options","usePresentation","onResize","useCallback","el","current","clearTimeout","currentHeight","contentRect","window","setTimeout","useEffect","document","getElementById","resizeObserver","ResizeObserver","observe","disconnect","attemptToLoadOneTap","oneTap","readB2CInternals","clientResult","createOneTapClient","success","reason","OneTapErrors","NoConfiguredOAuthClient","NoConfiguredSignupRedirectUrls","NoConfiguredLoginRedirectUrls","logger","error","client","onOneTapCancelled","showError","OriginNotAllowedForClient","renderResult","render","callback","createOnSuccessHandler","loginRedirectUrl","oauthOptions","loginRedirectURL","signupRedirectUrl","signupRedirectURL","onSuccess","redirectOnSuccess","style","cancel","InvalidOAuthClient","then","$client","catch","err","fallbackButton","OAuthButton","providerType","OAuthProviders","Google","fallbackWithLastUsed","LastUsed","DEV","ErrorMessages","OneTapProvider","willGoogleOneTapShowEmbedded","className","classNames","styles","container","CircularProgress","size"],"mappings":"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"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { useRef, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
useEffect(()=>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const useIsMounted = ()=>{
|
|
4
|
+
const isMounted = useRef(false);
|
|
5
|
+
useEffect(()=>{
|
|
6
|
+
isMounted.current = true;
|
|
7
|
+
return ()=>{
|
|
8
|
+
isMounted.current = false;
|
|
9
|
+
};
|
|
10
|
+
}, []);
|
|
11
|
+
return isMounted;
|
|
9
12
|
};
|
|
10
13
|
|
|
11
|
-
export {
|
|
14
|
+
export { useIsMounted };
|
|
12
15
|
//# sourceMappingURL=useIsMounted.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIsMounted.mjs","sources":["../../../../../../../../web/src/ui/hooks/useIsMounted.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef } from 'react';\n\nexport const
|
|
1
|
+
{"version":3,"file":"useIsMounted.mjs","sources":["../../../../../../../../web/src/ui/hooks/useIsMounted.ts"],"sourcesContent":["import { MutableRefObject, useEffect, useRef } from 'react';\n\nexport const useIsMounted = (): MutableRefObject<boolean> => {\n const isMounted = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n return isMounted;\n};\n"],"names":["useIsMounted","isMounted","useRef","useEffect","current"],"mappings":";;MAEaA,YAAAA,GAAe,IAAA;AAC1B,IAAA,MAAMC,YAAYC,MAAAA,CAAO,KAAA,CAAA;IAEzBC,SAAAA,CAAU,IAAA;AACRF,QAAAA,SAAAA,CAAUG,OAAO,GAAG,IAAA;QACpB,OAAO,IAAA;AACLH,YAAAA,SAAAA,CAAUG,OAAO,GAAG,KAAA;AACtB,QAAA,CAAA;AACF,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,OAAOH,SAAAA;AACT;;;;"}
|