@hexclave/tanstack-start 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/oauth-button.d.ts.map +1 -1
- package/dist/components/oauth-button.js.map +1 -1
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/components-page/account-settings/api-keys/api-keys-page.js +2 -2
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +2 -2
- package/dist/components-page/stack-handler-client.js +5 -1
- package/dist/components-page/stack-handler-client.js.map +1 -1
- package/dist/esm/components/oauth-button.d.ts.map +1 -1
- package/dist/esm/components/oauth-button.js.map +1 -1
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +2 -2
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +2 -2
- package/dist/esm/components-page/stack-handler-client.js +6 -2
- package/dist/esm/components-page/stack-handler-client.js.map +1 -1
- package/dist/esm/generated/global-css.d.ts +1 -1
- package/dist/esm/generated/global-css.js +1 -1
- package/dist/esm/generated/global-css.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js +67 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +18 -2
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/generated/global-css.d.ts +1 -1
- package/dist/generated/global-css.js +1 -1
- package/dist/generated/global-css.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js +66 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +18 -2
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-button.d.ts","names":[],"sources":["../../src/components/oauth-button.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"oauth-button.d.ts","names":[],"sources":["../../src/components/oauth-button.tsx"],"mappings":";;;iBAwBgB,WAAA,CAAA;EACd,QAAA;EACA,IAAA;EACA,MAAA;EACA;AAAA;EAEA,QAAA;EACA,IAAA;EACA,MAAA;EACA,cAAA,SAAuB,OAAA;AAAA,IACxB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-button.js","names":["BrandIcons","SimpleTooltip","Button"],"sources":["../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { BrandIcons, Button, SimpleTooltip } from '@hexclave/ui';\nimport Color, { ColorInstance } from 'color';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '../lib/hooks';\nimport { useTranslation } from '../lib/translations';\nimport { useInIframe } from './use-in-iframe';\n\nconst iconSize = 22;\n\nconst changeColor = (c: ColorInstance, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n isMock = false,\n onAuthenticate,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n isMock?: boolean,\n onAuthenticate?: () => Promise<void>,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n const isIframe = useInIframe();\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n setLastUsed(localStorage.getItem('_HEXCLAVE.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon:
|
|
1
|
+
{"version":3,"file":"oauth-button.js","names":["BrandIcons","SimpleTooltip","Button"],"sources":["../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { BrandIcons, Button, SimpleTooltip } from '@hexclave/ui';\nimport Color, { ColorInstance } from 'color';\nimport type { ReactElement } from 'react';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '../lib/hooks';\nimport { useTranslation } from '../lib/translations';\nimport { useInIframe } from './use-in-iframe';\n\nconst iconSize = 22;\n\nconst changeColor = (c: ColorInstance, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n isMock = false,\n onAuthenticate,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n isMock?: boolean,\n onAuthenticate?: () => Promise<void>,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n const isIframe = useInIframe();\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n setLastUsed(localStorage.getItem('_HEXCLAVE.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon: ReactElement | null,\n border?: string,\n };\n switch (provider) {\n case 'google': {\n style = {\n backgroundColor: '#fff',\n textColor: '#000',\n name: 'Google',\n border: '1px solid #ddd',\n icon: <BrandIcons.Google iconSize={iconSize} />,\n };\n break;\n }\n case 'github': {\n style = {\n backgroundColor: '#111',\n textColor: '#fff',\n border: '1px solid #333',\n name: 'GitHub',\n icon: <BrandIcons.GitHub iconSize={iconSize} />,\n };\n break;\n }\n case 'facebook': {\n style = {\n backgroundColor: '#1877F2',\n textColor: '#fff',\n name: 'Facebook',\n icon: <BrandIcons.Facebook iconSize={iconSize} />,\n };\n break;\n }\n case 'microsoft': {\n style = {\n backgroundColor: '#2f2f2f',\n textColor: '#fff',\n name: 'Microsoft',\n icon: <BrandIcons.Microsoft iconSize={iconSize} />,\n };\n break;\n }\n case 'spotify': {\n style = {\n backgroundColor: '#1DB954',\n textColor: '#fff',\n name: 'Spotify',\n icon: <BrandIcons.Spotify iconSize={iconSize} />,\n };\n break;\n }\n case 'discord': {\n style = {\n backgroundColor: '#5865F2',\n textColor: '#fff',\n name: 'Discord',\n icon: <BrandIcons.Discord iconSize={iconSize} />,\n };\n break;\n }\n case 'gitlab': {\n style = {\n backgroundColor: \"#111\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Gitlab\",\n icon: <BrandIcons.Gitlab iconSize={iconSize} />,\n };\n break;\n }\n case 'apple': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Apple\",\n icon: <BrandIcons.Apple iconSize={iconSize} />,\n };\n break;\n }\n case \"bitbucket\": {\n style = {\n backgroundColor: \"#fff\",\n textColor: \"#000\",\n border: \"1px solid #ddd\",\n name: \"Bitbucket\",\n icon: <BrandIcons.Bitbucket iconSize={iconSize} />,\n };\n break;\n }\n case 'linkedin': {\n style = {\n backgroundColor: \"#0073b1\",\n textColor: \"#fff\",\n name: \"LinkedIn\",\n icon: <BrandIcons.LinkedIn iconSize={iconSize} />,\n };\n break;\n }\n case 'x': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n name: \"X\",\n icon: <BrandIcons.X iconSize={iconSize} />,\n };\n break;\n }\n case 'twitch': {\n style = {\n backgroundColor: \"#6441a5\",\n textColor: \"#fff\",\n name: \"Twitch\",\n icon: <BrandIcons.Twitch iconSize={iconSize} />,\n };\n break;\n }\n default: {\n style = {\n name: provider,\n icon: null,\n };\n }\n }\n\n const styleSheet = `\n .stack-oauth-button-${styleId} {\n background-color: ${style.backgroundColor} !important;\n color: ${style.textColor} !important;\n border: ${style.border} !important;\n }\n .stack-oauth-button-${styleId}:hover {\n background-color: ${changeColor(Color(style.backgroundColor), 10)} !important;\n }\n `;\n\n return (\n <>\n <style>{styleSheet}</style>\n <SimpleTooltip\n disabled={!isIframe}\n tooltip={isIframe ? \"This auth provider is not supported in an iframe for security reasons.\" : undefined}\n className='stack-scope w-full inline-flex'\n >\n <Button\n onClick={async () => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n localStorage.setItem('_HEXCLAVE.lastUsed', provider);\n await (onAuthenticate ? onAuthenticate() : stackApp.signInWithOAuth(provider));\n }}\n className={`stack-oauth-button-${styleId} stack-scope relative w-full`}\n disabled={isIframe}\n >\n {!isMock && lastUsed === provider && (\n <span className=\"absolute -top-2 -right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-md\">\n last\n </span>\n )}\n <div className='flex items-center w-full gap-4'>\n {style.icon}\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with {provider}', { provider: style.name }) :\n t('Sign in with {provider}', { provider: style.name })\n }\n </span>\n </div>\n </Button>\n </SimpleTooltip>\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -5,10 +5,10 @@ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/
|
|
|
5
5
|
let _hexclave_ui = require("@hexclave/ui");
|
|
6
6
|
let react = require("react");
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let _hexclave_shared_dist_utils_dates = require("@hexclave/shared/dist/utils/dates");
|
|
8
9
|
let _________lib_hooks_js = require("../../../lib/hooks.js");
|
|
9
10
|
let _________lib_translations_js = require("../../../lib/translations.js");
|
|
10
11
|
let ___page_layout_js = require("../page-layout.js");
|
|
11
|
-
let _hexclave_shared_dist_utils_dates = require("@hexclave/shared/dist/utils/dates");
|
|
12
12
|
|
|
13
13
|
//#region src/components-page/account-settings/active-sessions/active-sessions-page.tsx
|
|
14
14
|
function ActiveSessionsPage(props) {
|
|
@@ -3,11 +3,11 @@ const require_chunk = require('../../../chunk-BE-pF4vm.js');
|
|
|
3
3
|
let _hexclave_ui = require("@hexclave/ui");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
-
let _________components_api_key_dialogs_js = require("../../../components/api-key-dialogs.js");
|
|
7
|
-
let _________components_api_key_table_js = require("../../../components/api-key-table.js");
|
|
8
6
|
let _________lib_hooks_js = require("../../../lib/hooks.js");
|
|
9
7
|
let _________lib_translations_js = require("../../../lib/translations.js");
|
|
10
8
|
let ___page_layout_js = require("../page-layout.js");
|
|
9
|
+
let _________components_api_key_dialogs_js = require("../../../components/api-key-dialogs.js");
|
|
10
|
+
let _________components_api_key_table_js = require("../../../components/api-key-table.js");
|
|
11
11
|
|
|
12
12
|
//#region src/components-page/account-settings/api-keys/api-keys-page.tsx
|
|
13
13
|
function ApiKeysPage(props) {
|
|
@@ -4,10 +4,10 @@ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/er
|
|
|
4
4
|
let _hexclave_ui = require("@hexclave/ui");
|
|
5
5
|
let react = require("react");
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
-
let _________components_api_key_dialogs_js = require("../../../components/api-key-dialogs.js");
|
|
8
|
-
let _________components_api_key_table_js = require("../../../components/api-key-table.js");
|
|
9
7
|
let _________lib_hooks_js = require("../../../lib/hooks.js");
|
|
10
8
|
let _________lib_translations_js = require("../../../lib/translations.js");
|
|
9
|
+
let _________components_api_key_dialogs_js = require("../../../components/api-key-dialogs.js");
|
|
10
|
+
let _________components_api_key_table_js = require("../../../components/api-key-table.js");
|
|
11
11
|
let ___section_js = require("../section.js");
|
|
12
12
|
|
|
13
13
|
//#region src/components-page/account-settings/teams/team-api-keys-section.tsx
|
|
@@ -154,6 +154,7 @@ function renderComponent(props) {
|
|
|
154
154
|
}
|
|
155
155
|
function StackHandlerClient(props) {
|
|
156
156
|
const stackApp = (0, ___lib_hooks_js.useStackApp)();
|
|
157
|
+
const clientOrigin = useClientOriginAfterHydration();
|
|
157
158
|
const navigate = stackApp.useNavigate();
|
|
158
159
|
const navigateRef = (0, react.useRef)(navigate);
|
|
159
160
|
navigateRef.current = navigate;
|
|
@@ -185,7 +186,7 @@ function StackHandlerClient(props) {
|
|
|
185
186
|
return !(0, ___lib_stack_app_url_targets_js.isLocalHandlerUrlTarget)({
|
|
186
187
|
targetUrl: url,
|
|
187
188
|
handlerPath,
|
|
188
|
-
currentOrigin:
|
|
189
|
+
currentOrigin: clientOrigin
|
|
189
190
|
});
|
|
190
191
|
};
|
|
191
192
|
const result = renderComponent({
|
|
@@ -236,6 +237,9 @@ function filterUndefinedINU(value) {
|
|
|
236
237
|
function toAbsoluteOrRelativeRedirectTarget(url) {
|
|
237
238
|
return url.origin === "http://example.com" ? (0, _hexclave_shared_dist_utils_urls.getRelativePart)(url) : url.toString();
|
|
238
239
|
}
|
|
240
|
+
function useClientOriginAfterHydration() {
|
|
241
|
+
return (0, react.useSyncExternalStore)(() => () => {}, () => window.location.origin, () => void 0);
|
|
242
|
+
}
|
|
239
243
|
|
|
240
244
|
//#endregion
|
|
241
245
|
exports.StackHandlerClient = StackHandlerClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","HexclaveAssertionError","stackAppInternalsSymbol","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@hexclave/shared/dist/utils/objects\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { getRelativePart } from \"@hexclave/shared/dist/utils/urls\";\nimport { useEffect, useMemo } from 'react';\nimport { useRef } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n shouldRedirectToPage?: (name: keyof HandlerUrls) => boolean,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, shouldRedirectToPage, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n if (shouldRedirectToPage?.('signIn')) return { redirectToPage: 'signIn' as const };\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n if (shouldRedirectToPage?.('signUp')) return { redirectToPage: 'signUp' as const };\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n if (shouldRedirectToPage?.('emailVerification')) return { redirectToPage: 'emailVerification' as const };\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n if (shouldRedirectToPage?.('passwordReset')) return { redirectToPage: 'passwordReset' as const };\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n if (shouldRedirectToPage?.('forgotPassword')) return { redirectToPage: 'forgotPassword' as const };\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n if (shouldRedirectToPage?.('signOut')) return { redirectToPage: 'signOut' as const };\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n if (shouldRedirectToPage?.('oauthCallback')) return { redirectToPage: 'oauthCallback' as const };\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n if (shouldRedirectToPage?.('magicLinkCallback')) return { redirectToPage: 'magicLinkCallback' as const };\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n if (shouldRedirectToPage?.('teamInvitation')) return { redirectToPage: 'teamInvitation' as const };\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n if (shouldRedirectToPage?.('cliAuthConfirm')) return { redirectToPage: 'cliAuthConfirm' as const };\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n if (shouldRedirectToPage?.('mfa')) return { redirectToPage: 'mfa' as const };\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n if (shouldRedirectToPage?.('onboarding')) return { redirectToPage: 'onboarding' as const };\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new HexclaveAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const navigate = stackApp.useNavigate();\n const navigateRef = useRef(navigate);\n navigateRef.current = navigate;\n const currentLocation = props.location ?? (typeof window === \"undefined\" ? new URL(stackApp.urls.handler, placeholderOrigin).pathname : window.location.pathname);\n const searchParamsSource = new URLSearchParams(typeof window === \"undefined\" ? \"\" : window.location.search);\n const redirectTargets: (string | undefined)[] = [];\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const shouldRedirectToPage = (name: keyof HandlerUrls): boolean => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.hexclave_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return false;\n }\n return !isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: typeof window === \"undefined\" ? undefined : window.location.origin,\n });\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n shouldRedirectToPage,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n const redirectToPage = (result != null && typeof result === 'object' && 'redirectToPage' in result) ? result.redirectToPage : undefined;\n\n useEffect(() => {\n if (redirectToPage == null) return;\n runAsynchronouslyWithAlert(\n stackApp[stackAppInternalsSymbol].redirectToHandler(redirectToPage, { replace: true })\n );\n }, [redirectToPage, stackApp]);\n\n if (redirectToPage != null) {\n return (\n <MessageCard title=\"Redirecting...\" fullPage={props.fullPage} />\n );\n }\n\n if (result && 'redirect' in result) {\n redirectTargets.push(result.redirect);\n }\n\n const redirectTarget = redirectTargets[0];\n const shouldRenderRedirectFallback = redirectTarget != null && stackApp[stackAppInternalsSymbol].getRedirectMethod() === \"none\";\n useEffect(() => {\n if (redirectTarget == null || shouldRenderRedirectFallback) {\n return;\n }\n navigateRef.current(redirectTarget);\n }, [redirectTarget, shouldRenderRedirectFallback]);\n\n if (redirectTarget != null && shouldRenderRedirectFallback) {\n return (\n <MessageCard\n title=\"Continue\"\n fullPage={props.fullPage}\n primaryButtonText=\"Continue\"\n primaryAction={() => window.location.assign(redirectTarget)}\n >\n Continue to the next page.\n </MessageCard>\n );\n }\n\n if (redirectTarget != null) {\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","HexclaveAssertionError","stackAppInternalsSymbol","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@hexclave/shared/dist/utils/objects\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { getRelativePart } from \"@hexclave/shared/dist/utils/urls\";\nimport { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { useRef } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n shouldRedirectToPage?: (name: keyof HandlerUrls) => boolean,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, shouldRedirectToPage, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n if (shouldRedirectToPage?.('signIn')) return { redirectToPage: 'signIn' as const };\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n if (shouldRedirectToPage?.('signUp')) return { redirectToPage: 'signUp' as const };\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n if (shouldRedirectToPage?.('emailVerification')) return { redirectToPage: 'emailVerification' as const };\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n if (shouldRedirectToPage?.('passwordReset')) return { redirectToPage: 'passwordReset' as const };\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n if (shouldRedirectToPage?.('forgotPassword')) return { redirectToPage: 'forgotPassword' as const };\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n if (shouldRedirectToPage?.('signOut')) return { redirectToPage: 'signOut' as const };\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n if (shouldRedirectToPage?.('oauthCallback')) return { redirectToPage: 'oauthCallback' as const };\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n if (shouldRedirectToPage?.('magicLinkCallback')) return { redirectToPage: 'magicLinkCallback' as const };\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n if (shouldRedirectToPage?.('teamInvitation')) return { redirectToPage: 'teamInvitation' as const };\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n if (shouldRedirectToPage?.('cliAuthConfirm')) return { redirectToPage: 'cliAuthConfirm' as const };\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n if (shouldRedirectToPage?.('mfa')) return { redirectToPage: 'mfa' as const };\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n if (shouldRedirectToPage?.('onboarding')) return { redirectToPage: 'onboarding' as const };\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new HexclaveAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n const clientOrigin = useClientOriginAfterHydration();\n\n const navigate = stackApp.useNavigate();\n const navigateRef = useRef(navigate);\n navigateRef.current = navigate;\n const currentLocation = props.location ?? (typeof window === \"undefined\" ? new URL(stackApp.urls.handler, placeholderOrigin).pathname : window.location.pathname);\n const searchParamsSource = new URLSearchParams(typeof window === \"undefined\" ? \"\" : window.location.search);\n const redirectTargets: (string | undefined)[] = [];\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const shouldRedirectToPage = (name: keyof HandlerUrls): boolean => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.hexclave_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return false;\n }\n return !isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: clientOrigin,\n });\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n shouldRedirectToPage,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n const redirectToPage = (result != null && typeof result === 'object' && 'redirectToPage' in result) ? result.redirectToPage : undefined;\n\n useEffect(() => {\n if (redirectToPage == null) return;\n runAsynchronouslyWithAlert(\n stackApp[stackAppInternalsSymbol].redirectToHandler(redirectToPage, { replace: true })\n );\n }, [redirectToPage, stackApp]);\n\n if (redirectToPage != null) {\n return (\n <MessageCard title=\"Redirecting...\" fullPage={props.fullPage} />\n );\n }\n\n if (result && 'redirect' in result) {\n redirectTargets.push(result.redirect);\n }\n\n const redirectTarget = redirectTargets[0];\n const shouldRenderRedirectFallback = redirectTarget != null && stackApp[stackAppInternalsSymbol].getRedirectMethod() === \"none\";\n useEffect(() => {\n if (redirectTarget == null || shouldRenderRedirectFallback) {\n return;\n }\n navigateRef.current(redirectTarget);\n }, [redirectTarget, shouldRenderRedirectFallback]);\n\n if (redirectTarget != null && shouldRenderRedirectFallback) {\n return (\n <MessageCard\n title=\"Continue\"\n fullPage={props.fullPage}\n primaryButtonText=\"Continue\"\n primaryAction={() => window.location.assign(redirectTarget)}\n >\n Continue to the next page.\n </MessageCard>\n );\n }\n\n if (redirectTarget != null) {\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n\nfunction useClientOriginAfterHydration(): string | undefined {\n // The first hydrated render must match SSR. After hydration, React re-checks\n // the snapshot and lets us distinguish same-path cross-origin handler URLs.\n return useSyncExternalStore(\n () => () => {},\n () => window.location.origin,\n () => undefined,\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-button.d.ts","names":[],"sources":["../../../src/components/oauth-button.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"oauth-button.d.ts","names":[],"sources":["../../../src/components/oauth-button.tsx"],"mappings":";;;iBAwBgB,WAAA,CAAA;EACd,QAAA;EACA,IAAA;EACA,MAAA;EACA;AAAA;EAEA,QAAA;EACA,IAAA;EACA,MAAA;EACA,cAAA,SAAuB,OAAA;AAAA,IACxB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-button.js","names":[],"sources":["../../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { BrandIcons, Button, SimpleTooltip } from '@hexclave/ui';\nimport Color, { ColorInstance } from 'color';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '../lib/hooks';\nimport { useTranslation } from '../lib/translations';\nimport { useInIframe } from './use-in-iframe';\n\nconst iconSize = 22;\n\nconst changeColor = (c: ColorInstance, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n isMock = false,\n onAuthenticate,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n isMock?: boolean,\n onAuthenticate?: () => Promise<void>,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n const isIframe = useInIframe();\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n setLastUsed(localStorage.getItem('_HEXCLAVE.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon:
|
|
1
|
+
{"version":3,"file":"oauth-button.js","names":[],"sources":["../../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { BrandIcons, Button, SimpleTooltip } from '@hexclave/ui';\nimport Color, { ColorInstance } from 'color';\nimport type { ReactElement } from 'react';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '../lib/hooks';\nimport { useTranslation } from '../lib/translations';\nimport { useInIframe } from './use-in-iframe';\n\nconst iconSize = 22;\n\nconst changeColor = (c: ColorInstance, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n isMock = false,\n onAuthenticate,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n isMock?: boolean,\n onAuthenticate?: () => Promise<void>,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n const isIframe = useInIframe();\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n setLastUsed(localStorage.getItem('_HEXCLAVE.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon: ReactElement | null,\n border?: string,\n };\n switch (provider) {\n case 'google': {\n style = {\n backgroundColor: '#fff',\n textColor: '#000',\n name: 'Google',\n border: '1px solid #ddd',\n icon: <BrandIcons.Google iconSize={iconSize} />,\n };\n break;\n }\n case 'github': {\n style = {\n backgroundColor: '#111',\n textColor: '#fff',\n border: '1px solid #333',\n name: 'GitHub',\n icon: <BrandIcons.GitHub iconSize={iconSize} />,\n };\n break;\n }\n case 'facebook': {\n style = {\n backgroundColor: '#1877F2',\n textColor: '#fff',\n name: 'Facebook',\n icon: <BrandIcons.Facebook iconSize={iconSize} />,\n };\n break;\n }\n case 'microsoft': {\n style = {\n backgroundColor: '#2f2f2f',\n textColor: '#fff',\n name: 'Microsoft',\n icon: <BrandIcons.Microsoft iconSize={iconSize} />,\n };\n break;\n }\n case 'spotify': {\n style = {\n backgroundColor: '#1DB954',\n textColor: '#fff',\n name: 'Spotify',\n icon: <BrandIcons.Spotify iconSize={iconSize} />,\n };\n break;\n }\n case 'discord': {\n style = {\n backgroundColor: '#5865F2',\n textColor: '#fff',\n name: 'Discord',\n icon: <BrandIcons.Discord iconSize={iconSize} />,\n };\n break;\n }\n case 'gitlab': {\n style = {\n backgroundColor: \"#111\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Gitlab\",\n icon: <BrandIcons.Gitlab iconSize={iconSize} />,\n };\n break;\n }\n case 'apple': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Apple\",\n icon: <BrandIcons.Apple iconSize={iconSize} />,\n };\n break;\n }\n case \"bitbucket\": {\n style = {\n backgroundColor: \"#fff\",\n textColor: \"#000\",\n border: \"1px solid #ddd\",\n name: \"Bitbucket\",\n icon: <BrandIcons.Bitbucket iconSize={iconSize} />,\n };\n break;\n }\n case 'linkedin': {\n style = {\n backgroundColor: \"#0073b1\",\n textColor: \"#fff\",\n name: \"LinkedIn\",\n icon: <BrandIcons.LinkedIn iconSize={iconSize} />,\n };\n break;\n }\n case 'x': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n name: \"X\",\n icon: <BrandIcons.X iconSize={iconSize} />,\n };\n break;\n }\n case 'twitch': {\n style = {\n backgroundColor: \"#6441a5\",\n textColor: \"#fff\",\n name: \"Twitch\",\n icon: <BrandIcons.Twitch iconSize={iconSize} />,\n };\n break;\n }\n default: {\n style = {\n name: provider,\n icon: null,\n };\n }\n }\n\n const styleSheet = `\n .stack-oauth-button-${styleId} {\n background-color: ${style.backgroundColor} !important;\n color: ${style.textColor} !important;\n border: ${style.border} !important;\n }\n .stack-oauth-button-${styleId}:hover {\n background-color: ${changeColor(Color(style.backgroundColor), 10)} !important;\n }\n `;\n\n return (\n <>\n <style>{styleSheet}</style>\n <SimpleTooltip\n disabled={!isIframe}\n tooltip={isIframe ? \"This auth provider is not supported in an iframe for security reasons.\" : undefined}\n className='stack-scope w-full inline-flex'\n >\n <Button\n onClick={async () => {\n // Hexclave rebrand: UI hint key — straight rename (dot delimiter preserved).\n localStorage.setItem('_HEXCLAVE.lastUsed', provider);\n await (onAuthenticate ? onAuthenticate() : stackApp.signInWithOAuth(provider));\n }}\n className={`stack-oauth-button-${styleId} stack-scope relative w-full`}\n disabled={isIframe}\n >\n {!isMock && lastUsed === provider && (\n <span className=\"absolute -top-2 -right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-md\">\n last\n </span>\n )}\n <div className='flex items-center w-full gap-4'>\n {style.icon}\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with {provider}', { provider: style.name }) :\n t('Sign in with {provider}', { provider: style.name })\n }\n </span>\n </div>\n </Button>\n </SimpleTooltip>\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,10 +3,10 @@ import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
|
3
3
|
import { ActionCell, Badge, Button, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@hexclave/ui";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { fromNow } from "@hexclave/shared/dist/utils/dates";
|
|
6
7
|
import { useUser } from "../../../lib/hooks.js";
|
|
7
8
|
import { useTranslation } from "../../../lib/translations.js";
|
|
8
9
|
import { PageLayout } from "../page-layout.js";
|
|
9
|
-
import { fromNow } from "@hexclave/shared/dist/utils/dates";
|
|
10
10
|
|
|
11
11
|
//#region src/components-page/account-settings/active-sessions/active-sessions-page.tsx
|
|
12
12
|
function ActiveSessionsPage(props) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Button } from "@hexclave/ui";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
5
|
-
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
6
4
|
import { useUser } from "../../../lib/hooks.js";
|
|
7
5
|
import { useTranslation } from "../../../lib/translations.js";
|
|
8
6
|
import { PageLayout } from "../page-layout.js";
|
|
7
|
+
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
8
|
+
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
9
9
|
|
|
10
10
|
//#region src/components-page/account-settings/api-keys/api-keys-page.tsx
|
|
11
11
|
function ApiKeysPage(props) {
|
|
@@ -2,10 +2,10 @@ import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
|
|
2
2
|
import { Button } from "@hexclave/ui";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
6
|
-
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
7
5
|
import { useStackApp, useUser } from "../../../lib/hooks.js";
|
|
8
6
|
import { useTranslation } from "../../../lib/translations.js";
|
|
7
|
+
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
8
|
+
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
9
9
|
import { Section } from "../section.js";
|
|
10
10
|
|
|
11
11
|
//#region src/components-page/account-settings/teams/team-api-keys-section.tsx
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
|
4
4
|
import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
|
|
5
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
5
|
+
import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
|
|
6
6
|
import { SignIn, SignUp } from "../index.js";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
8
8
|
import { useStackApp as useStackApp$1 } from "../lib/hooks.js";
|
|
@@ -152,6 +152,7 @@ function renderComponent(props) {
|
|
|
152
152
|
}
|
|
153
153
|
function StackHandlerClient(props) {
|
|
154
154
|
const stackApp = useStackApp$1();
|
|
155
|
+
const clientOrigin = useClientOriginAfterHydration();
|
|
155
156
|
const navigate = stackApp.useNavigate();
|
|
156
157
|
const navigateRef = useRef(navigate);
|
|
157
158
|
navigateRef.current = navigate;
|
|
@@ -183,7 +184,7 @@ function StackHandlerClient(props) {
|
|
|
183
184
|
return !isLocalHandlerUrlTarget({
|
|
184
185
|
targetUrl: url,
|
|
185
186
|
handlerPath,
|
|
186
|
-
currentOrigin:
|
|
187
|
+
currentOrigin: clientOrigin
|
|
187
188
|
});
|
|
188
189
|
};
|
|
189
190
|
const result = renderComponent({
|
|
@@ -234,6 +235,9 @@ function filterUndefinedINU(value) {
|
|
|
234
235
|
function toAbsoluteOrRelativeRedirectTarget(url) {
|
|
235
236
|
return url.origin === "http://example.com" ? getRelativePart(url) : url.toString();
|
|
236
237
|
}
|
|
238
|
+
function useClientOriginAfterHydration() {
|
|
239
|
+
return useSyncExternalStore(() => () => {}, () => window.location.origin, () => void 0);
|
|
240
|
+
}
|
|
237
241
|
|
|
238
242
|
//#endregion
|
|
239
243
|
export { StackHandlerClient };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-handler-client.js","names":["useStackApp","MessageCard"],"sources":["../../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@hexclave/shared/dist/utils/objects\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { getRelativePart } from \"@hexclave/shared/dist/utils/urls\";\nimport { useEffect, useMemo } from 'react';\nimport { useRef } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n shouldRedirectToPage?: (name: keyof HandlerUrls) => boolean,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, shouldRedirectToPage, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n if (shouldRedirectToPage?.('signIn')) return { redirectToPage: 'signIn' as const };\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n if (shouldRedirectToPage?.('signUp')) return { redirectToPage: 'signUp' as const };\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n if (shouldRedirectToPage?.('emailVerification')) return { redirectToPage: 'emailVerification' as const };\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n if (shouldRedirectToPage?.('passwordReset')) return { redirectToPage: 'passwordReset' as const };\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n if (shouldRedirectToPage?.('forgotPassword')) return { redirectToPage: 'forgotPassword' as const };\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n if (shouldRedirectToPage?.('signOut')) return { redirectToPage: 'signOut' as const };\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n if (shouldRedirectToPage?.('oauthCallback')) return { redirectToPage: 'oauthCallback' as const };\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n if (shouldRedirectToPage?.('magicLinkCallback')) return { redirectToPage: 'magicLinkCallback' as const };\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n if (shouldRedirectToPage?.('teamInvitation')) return { redirectToPage: 'teamInvitation' as const };\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n if (shouldRedirectToPage?.('cliAuthConfirm')) return { redirectToPage: 'cliAuthConfirm' as const };\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n if (shouldRedirectToPage?.('mfa')) return { redirectToPage: 'mfa' as const };\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n if (shouldRedirectToPage?.('onboarding')) return { redirectToPage: 'onboarding' as const };\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new HexclaveAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const navigate = stackApp.useNavigate();\n const navigateRef = useRef(navigate);\n navigateRef.current = navigate;\n const currentLocation = props.location ?? (typeof window === \"undefined\" ? new URL(stackApp.urls.handler, placeholderOrigin).pathname : window.location.pathname);\n const searchParamsSource = new URLSearchParams(typeof window === \"undefined\" ? \"\" : window.location.search);\n const redirectTargets: (string | undefined)[] = [];\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const shouldRedirectToPage = (name: keyof HandlerUrls): boolean => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.hexclave_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return false;\n }\n return !isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: typeof window === \"undefined\" ? undefined : window.location.origin,\n });\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n shouldRedirectToPage,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n const redirectToPage = (result != null && typeof result === 'object' && 'redirectToPage' in result) ? result.redirectToPage : undefined;\n\n useEffect(() => {\n if (redirectToPage == null) return;\n runAsynchronouslyWithAlert(\n stackApp[stackAppInternalsSymbol].redirectToHandler(redirectToPage, { replace: true })\n );\n }, [redirectToPage, stackApp]);\n\n if (redirectToPage != null) {\n return (\n <MessageCard title=\"Redirecting...\" fullPage={props.fullPage} />\n );\n }\n\n if (result && 'redirect' in result) {\n redirectTargets.push(result.redirect);\n }\n\n const redirectTarget = redirectTargets[0];\n const shouldRenderRedirectFallback = redirectTarget != null && stackApp[stackAppInternalsSymbol].getRedirectMethod() === \"none\";\n useEffect(() => {\n if (redirectTarget == null || shouldRenderRedirectFallback) {\n return;\n }\n navigateRef.current(redirectTarget);\n }, [redirectTarget, shouldRenderRedirectFallback]);\n\n if (redirectTarget != null && shouldRenderRedirectFallback) {\n return (\n <MessageCard\n title=\"Continue\"\n fullPage={props.fullPage}\n primaryButtonText=\"Continue\"\n primaryAction={() => window.location.assign(redirectTarget)}\n >\n Continue to the next page.\n </MessageCard>\n );\n }\n\n if (redirectTarget != null) {\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stack-handler-client.js","names":["useStackApp","MessageCard"],"sources":["../../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@hexclave/shared/dist/utils/objects\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { getRelativePart } from \"@hexclave/shared/dist/utils/urls\";\nimport { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { useRef } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n shouldRedirectToPage?: (name: keyof HandlerUrls) => boolean,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, shouldRedirectToPage, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n if (shouldRedirectToPage?.('signIn')) return { redirectToPage: 'signIn' as const };\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n if (shouldRedirectToPage?.('signUp')) return { redirectToPage: 'signUp' as const };\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n if (shouldRedirectToPage?.('emailVerification')) return { redirectToPage: 'emailVerification' as const };\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n if (shouldRedirectToPage?.('passwordReset')) return { redirectToPage: 'passwordReset' as const };\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n if (shouldRedirectToPage?.('forgotPassword')) return { redirectToPage: 'forgotPassword' as const };\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n if (shouldRedirectToPage?.('signOut')) return { redirectToPage: 'signOut' as const };\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n if (shouldRedirectToPage?.('oauthCallback')) return { redirectToPage: 'oauthCallback' as const };\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n if (shouldRedirectToPage?.('magicLinkCallback')) return { redirectToPage: 'magicLinkCallback' as const };\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n if (shouldRedirectToPage?.('teamInvitation')) return { redirectToPage: 'teamInvitation' as const };\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n if (shouldRedirectToPage?.('cliAuthConfirm')) return { redirectToPage: 'cliAuthConfirm' as const };\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n if (shouldRedirectToPage?.('mfa')) return { redirectToPage: 'mfa' as const };\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n if (shouldRedirectToPage?.('onboarding')) return { redirectToPage: 'onboarding' as const };\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new HexclaveAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n const clientOrigin = useClientOriginAfterHydration();\n\n const navigate = stackApp.useNavigate();\n const navigateRef = useRef(navigate);\n navigateRef.current = navigate;\n const currentLocation = props.location ?? (typeof window === \"undefined\" ? new URL(stackApp.urls.handler, placeholderOrigin).pathname : window.location.pathname);\n const searchParamsSource = new URLSearchParams(typeof window === \"undefined\" ? \"\" : window.location.search);\n const redirectTargets: (string | undefined)[] = [];\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const shouldRedirectToPage = (name: keyof HandlerUrls): boolean => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.hexclave_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return false;\n }\n return !isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: clientOrigin,\n });\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n shouldRedirectToPage,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n const redirectToPage = (result != null && typeof result === 'object' && 'redirectToPage' in result) ? result.redirectToPage : undefined;\n\n useEffect(() => {\n if (redirectToPage == null) return;\n runAsynchronouslyWithAlert(\n stackApp[stackAppInternalsSymbol].redirectToHandler(redirectToPage, { replace: true })\n );\n }, [redirectToPage, stackApp]);\n\n if (redirectToPage != null) {\n return (\n <MessageCard title=\"Redirecting...\" fullPage={props.fullPage} />\n );\n }\n\n if (result && 'redirect' in result) {\n redirectTargets.push(result.redirect);\n }\n\n const redirectTarget = redirectTargets[0];\n const shouldRenderRedirectFallback = redirectTarget != null && stackApp[stackAppInternalsSymbol].getRedirectMethod() === \"none\";\n useEffect(() => {\n if (redirectTarget == null || shouldRenderRedirectFallback) {\n return;\n }\n navigateRef.current(redirectTarget);\n }, [redirectTarget, shouldRenderRedirectFallback]);\n\n if (redirectTarget != null && shouldRenderRedirectFallback) {\n return (\n <MessageCard\n title=\"Continue\"\n fullPage={props.fullPage}\n primaryButtonText=\"Continue\"\n primaryAction={() => window.location.assign(redirectTarget)}\n >\n Continue to the next page.\n </MessageCard>\n );\n }\n\n if (redirectTarget != null) {\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n\nfunction useClientOriginAfterHydration(): string | undefined {\n // The first hydrated render must match SSR. After hydration, React re-checks\n // the snapshot and lets us distinguish same-path cross-origin handler URLs.\n return useSyncExternalStore(\n () => () => {},\n () => window.location.origin,\n () => undefined,\n );\n}\n"],"mappings":"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"}
|