@hexclave/next 1.0.73 → 1.0.74
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/{admin-app-impl-D867jXHk.d.ts → admin-app-impl-FZdANO62.d.ts} +10 -4
- package/dist/admin-app-impl-FZdANO62.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.d.ts +1 -1
- package/dist/clickmap/index.d.ts +1 -1
- package/dist/{client-app-B931IBrx.d.ts → client-app-BCT5p_70.d.ts} +11 -3
- package/dist/{client-app-B931IBrx.d.ts.map → client-app-BCT5p_70.d.ts.map} +1 -1
- package/dist/components/elements/sidebar-layout.js +1 -1
- package/dist/components/selected-team-switcher.d.ts +1 -1
- package/dist/components/team-icon.d.ts +1 -1
- package/dist/components/team-switcher.d.ts +1 -1
- package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/hexclave-handler.d.ts +1 -1
- package/dist/components-page/oauth-callback.js +3 -18
- package/dist/components-page/oauth-callback.js.map +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/esm/components/elements/sidebar-layout.js +1 -1
- package/dist/esm/components-page/oauth-callback.d.ts.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +4 -19
- package/dist/esm/components-page/oauth-callback.js.map +1 -1
- package/dist/esm/lib/auth.d.ts.map +1 -1
- package/dist/esm/lib/auth.js +1 -1
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/auth.test.js +2 -2
- package/dist/esm/lib/auth.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +3 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +102 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +57 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +44 -12
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +13 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js +15 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +25 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.js +67 -12
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +87 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +9 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/utils/url.js +10 -2
- package/dist/esm/utils/url.js.map +1 -1
- package/dist/esm/utils/url.test.d.ts +1 -0
- package/dist/esm/utils/url.test.js +28 -0
- package/dist/esm/utils/url.test.js.map +1 -0
- package/dist/{hexclave-provider-DkFUT3Fa.d.ts → hexclave-provider-BKxi3Vy-.d.ts} +2 -2
- package/dist/{hexclave-provider-DkFUT3Fa.d.ts.map → hexclave-provider-BKxi3Vy-.d.ts.map} +1 -1
- package/dist/{hooks-4PMrTtJr.d.ts → hooks-CUe5bc3s.d.ts} +2 -2
- package/dist/{hooks-4PMrTtJr.d.ts.map → hooks-CUe5bc3s.d.ts.map} +1 -1
- package/dist/{index-C9bAeWRr.d.ts → index-CvB7XacB.d.ts} +2 -2
- package/dist/{index-C9bAeWRr.d.ts.map → index-CvB7XacB.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +1 -1
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/auth.test.js +2 -2
- package/dist/lib/auth.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +101 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +57 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +43 -11
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +13 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js +15 -0
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +24 -0
- package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.js +67 -12
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +86 -0
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/index.d.ts +1 -1
- package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
- package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
- package/dist/lib/hexclave-app/users/index.d.ts +1 -1
- package/dist/lib/hooks.d.ts +1 -1
- package/dist/oauth-callback-tCVTRbF2.d.ts.map +1 -1
- package/dist/providers/hexclave-context.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/hexclave-provider.d.ts +1 -1
- package/dist/pushed-config-error-overlay/index.d.ts +1 -1
- package/dist/{redirect-page-urls-NUHUchgR.d.ts → redirect-page-urls-BEWG0AtP.d.ts} +2 -1
- package/dist/redirect-page-urls-BEWG0AtP.d.ts.map +1 -0
- package/dist/utils/url.js +10 -2
- package/dist/utils/url.js.map +1 -1
- package/dist/utils/url.test.d.ts +1 -0
- package/dist/utils/url.test.js +27 -0
- package/dist/utils/url.test.js.map +1 -0
- package/package.json +4 -4
- package/src/components-page/oauth-callback.tsx +0 -16
- package/src/lib/auth.test.ts +2 -2
- package/src/lib/auth.ts +3 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +126 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +75 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +73 -16
- package/src/lib/hexclave-app/apps/implementations/redirect-back-state.test.ts +29 -1
- package/src/lib/hexclave-app/apps/implementations/redirect-back-state.ts +17 -0
- package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +119 -0
- package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.ts +104 -12
- package/src/lib/hexclave-app/apps/interfaces/client-app.ts +12 -2
- package/src/utils/url.test.ts +54 -0
- package/src/utils/url.ts +12 -3
- package/dist/admin-app-impl-D867jXHk.d.ts.map +0 -1
- package/dist/redirect-page-urls-NUHUchgR.d.ts.map +0 -1
|
@@ -37,6 +37,13 @@ type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId e
|
|
|
37
37
|
* the app is never used or disposed of immediately. To disable this behavior, set this option to true.
|
|
38
38
|
*/
|
|
39
39
|
noAutomaticPrefetch?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the constructor starts browser integrations and other automatic side effects. Defaults to `true`.
|
|
42
|
+
*
|
|
43
|
+
* Set this to `false` when the app is instantiated inside a custom dashboard. Explicit method calls remain
|
|
44
|
+
* available and can still perform their documented side effects.
|
|
45
|
+
*/
|
|
46
|
+
automaticSideEffects?: boolean;
|
|
40
47
|
/**
|
|
41
48
|
* Options for analytics and session recording. Replays are enabled by default;
|
|
42
49
|
* set `{ replays: { enabled: false } }` to opt out.
|
|
@@ -196,7 +203,8 @@ type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends s
|
|
|
196
203
|
replace?: boolean;
|
|
197
204
|
}): Promise<void>;
|
|
198
205
|
getRedirectToHandlerUrl(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<string>;
|
|
199
|
-
redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>;
|
|
206
|
+
redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>; /** Raw flow metadata only. Never navigate to this value without normal redirect validation. */
|
|
207
|
+
getRawAfterAuthReturnTo(): string | null;
|
|
200
208
|
signInWithTokens(tokens: {
|
|
201
209
|
accessToken: string;
|
|
202
210
|
refreshToken: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"mappings":";;;;;;;;;;;;KAgBY,gCAAA;EACV,OAAA;IAAqB,OAAA;IAAiB,MAAA;EAAA;EACtC,mBAAA,GAAsB,MAAA;EACtB,SAAA,GAAY,SAAA;EACZ,oBAAA;EACA,IAAA,GAAO,iBAAA;EACP,mBAAA,GAAsB,OAAA,CAAQ,mBAAA;EAC9B,UAAA,GAAa,cAAA,CAAe,aAAA;EAC5B,cAAA,GAAiB,cAAA;EACjB,YAAA,GAAe,cAAA;
|
|
1
|
+
{"version":3,"file":"client-app.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol, TokenStoreInit } from \"../../common\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"ContactChannelAlreadyUsedForAuthBySomeoneElse\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n getRedirectToHandlerUrl(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<string>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n awaitPendingAuthResolutions(): Promise<void>,\n isTrustedRedirectUrl(url: string): Promise<boolean>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;AAwLA,MAAa,oBAAkD;;AAE/D,MAAa,iBAA4C"}
|
|
1
|
+
{"version":3,"file":"client-app.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, hexclaveAppInternalsSymbol, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, TokenStoreInit } from \"../../common\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Whether the constructor starts browser integrations and other automatic side effects. Defaults to `true`.\n *\n * Set this to `false` when the app is instantiated inside a custom dashboard. Explicit method calls remain\n * available and can still perform their documented side effects.\n */\n automaticSideEffects?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"ContactChannelAlreadyUsedForAuthBySomeoneElse\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n getRedirectToHandlerUrl(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<string>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n /** Raw flow metadata only. Never navigate to this value without normal redirect validation. */\n getRawAfterAuthReturnTo(): string | null,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n awaitPendingAuthResolutions(): Promise<void>,\n isTrustedRedirectUrl(url: string): Promise<boolean>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;AAkMA,MAAa,oBAAkD;;AAE/D,MAAa,iBAA4C"}
|
package/dist/esm/utils/url.js
CHANGED
|
@@ -2,10 +2,18 @@ import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
|
|
2
2
|
//#region src/utils/url.ts
|
|
3
3
|
function constructRedirectUrl(redirectUrl, callbackUrlName) {
|
|
4
4
|
if (typeof window === "undefined" || !window.location) throw new HexclaveAssertionError(`${callbackUrlName} option is required in a non-browser environment.`, { redirectUrl });
|
|
5
|
-
const retainedQueryParams = [
|
|
5
|
+
const retainedQueryParams = [
|
|
6
|
+
"after_auth_return_to",
|
|
7
|
+
"hexclave_cross_domain_state",
|
|
8
|
+
"hexclave_cross_domain_code_challenge",
|
|
9
|
+
"hexclave_cross_domain_after_callback_redirect_url"
|
|
10
|
+
];
|
|
6
11
|
const currentUrl = new URL(window.location.href);
|
|
7
12
|
const url = redirectUrl ? new URL(redirectUrl, window.location.href) : new URL(window.location.href);
|
|
8
|
-
for (const param of retainedQueryParams)
|
|
13
|
+
for (const param of retainedQueryParams) {
|
|
14
|
+
const value = currentUrl.searchParams.get(param);
|
|
15
|
+
if (value != null) url.searchParams.set(param, value);
|
|
16
|
+
}
|
|
9
17
|
url.hash = "";
|
|
10
18
|
return url.toString();
|
|
11
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","names":[],"sources":["../../../src/utils/url.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\n\n\nexport function constructRedirectUrl(redirectUrl: URL | string | undefined, callbackUrlName: string) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window === 'undefined' || !window.location) {\n throw new HexclaveAssertionError(`${callbackUrlName} option is required in a non-browser environment.`, { redirectUrl });\n }\n\n const retainedQueryParams = [\"after_auth_return_to\"];\n const currentUrl = new URL(window.location.href);\n const url = redirectUrl ? new URL(redirectUrl, window.location.href) : new URL(window.location.href);\n for (const param of retainedQueryParams) {\n
|
|
1
|
+
{"version":3,"file":"url.js","names":[],"sources":["../../../src/utils/url.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\n\n\nexport function constructRedirectUrl(redirectUrl: URL | string | undefined, callbackUrlName: string) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window === 'undefined' || !window.location) {\n throw new HexclaveAssertionError(`${callbackUrlName} option is required in a non-browser environment.`, { redirectUrl });\n }\n\n // These parameters form one continuation. Keeping only after_auth_return_to can return to the\n // callback URL but cannot complete its cross-domain PKCE handoff after an email opens in a new\n // tab.\n const retainedQueryParams = [\n \"after_auth_return_to\",\n \"hexclave_cross_domain_state\",\n \"hexclave_cross_domain_code_challenge\",\n \"hexclave_cross_domain_after_callback_redirect_url\",\n ];\n const currentUrl = new URL(window.location.href);\n const url = redirectUrl ? new URL(redirectUrl, window.location.href) : new URL(window.location.href);\n for (const param of retainedQueryParams) {\n const value = currentUrl.searchParams.get(param);\n if (value != null) {\n url.searchParams.set(param, value);\n }\n }\n url.hash = \"\";\n return url.toString();\n}\n"],"mappings":";;AAOA,SAAgB,qBAAqB,aAAuC,iBAAyB;CAEnG,IAAI,OAAO,WAAW,eAAe,CAAC,OAAO,UAC3C,MAAM,IAAI,uBAAuB,GAAG,gBAAgB,oDAAoD,EAAE,YAAY,CAAC;CAMzH,MAAM,sBAAsB;EAC1B;EACA;EACA;EACA;CACF;CACA,MAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;CAC/C,MAAM,MAAM,cAAc,IAAI,IAAI,aAAa,OAAO,SAAS,IAAI,IAAI,IAAI,IAAI,OAAO,SAAS,IAAI;CACnG,KAAK,MAAM,SAAS,qBAAqB;EACvC,MAAM,QAAQ,WAAW,aAAa,IAAI,KAAK;EAC/C,IAAI,SAAS,MACX,IAAI,aAAa,IAAI,OAAO,KAAK;CAErC;CACA,IAAI,OAAO;CACX,OAAO,IAAI,SAAS;AACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { constructRedirectUrl } from "./url.js";
|
|
3
|
+
//#region src/utils/url.test.ts
|
|
4
|
+
const previousWindow = Reflect.get(globalThis, "window");
|
|
5
|
+
const hadPreviousWindow = Reflect.has(globalThis, "window");
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
if (hadPreviousWindow) Reflect.set(globalThis, "window", previousWindow);
|
|
8
|
+
else Reflect.deleteProperty(globalThis, "window");
|
|
9
|
+
});
|
|
10
|
+
describe("constructRedirectUrl", () => {
|
|
11
|
+
it("transports the complete cross-domain return state to an email callback", () => {
|
|
12
|
+
const currentUrl = new URL("https://hosted.example.test/handler/forgot-password");
|
|
13
|
+
currentUrl.searchParams.set("after_auth_return_to", "https://customer.example.test/handler/oauth-callback?hexclave_cross_domain_auth=1");
|
|
14
|
+
currentUrl.searchParams.set("hexclave_cross_domain_state", "outer-state");
|
|
15
|
+
currentUrl.searchParams.set("hexclave_cross_domain_code_challenge", "outer-challenge");
|
|
16
|
+
currentUrl.searchParams.set("hexclave_cross_domain_after_callback_redirect_url", "https://customer.example.test/dashboard");
|
|
17
|
+
Reflect.set(globalThis, "window", { location: { href: currentUrl.toString() } });
|
|
18
|
+
expect(new URL(constructRedirectUrl("/handler/password-reset#discarded", "callbackUrl")).toString()).toBe("https://hosted.example.test/handler/password-reset?after_auth_return_to=https%3A%2F%2Fcustomer.example.test%2Fhandler%2Foauth-callback%3Fhexclave_cross_domain_auth%3D1&hexclave_cross_domain_state=outer-state&hexclave_cross_domain_code_challenge=outer-challenge&hexclave_cross_domain_after_callback_redirect_url=https%3A%2F%2Fcustomer.example.test%2Fdashboard");
|
|
19
|
+
});
|
|
20
|
+
it("does not synthesize the forgot-password page as a return target", () => {
|
|
21
|
+
Reflect.set(globalThis, "window", { location: { href: "https://hosted.example.test/handler/forgot-password" } });
|
|
22
|
+
expect(constructRedirectUrl("/handler/password-reset", "callbackUrl")).toBe("https://hosted.example.test/handler/password-reset");
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export {};
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=url.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.test.js","names":[],"sources":["../../../src/utils/url.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { constructRedirectUrl } from \"./url\";\n\nconst previousWindow = Reflect.get(globalThis, \"window\");\nconst hadPreviousWindow = Reflect.has(globalThis, \"window\");\n\nafterEach(() => {\n if (hadPreviousWindow) {\n Reflect.set(globalThis, \"window\", previousWindow);\n } else {\n Reflect.deleteProperty(globalThis, \"window\");\n }\n});\n\ndescribe(\"constructRedirectUrl\", () => {\n it(\"transports the complete cross-domain return state to an email callback\", () => {\n const currentUrl = new URL(\"https://hosted.example.test/handler/forgot-password\");\n currentUrl.searchParams.set(\"after_auth_return_to\", \"https://customer.example.test/handler/oauth-callback?hexclave_cross_domain_auth=1\");\n currentUrl.searchParams.set(\"hexclave_cross_domain_state\", \"outer-state\");\n currentUrl.searchParams.set(\"hexclave_cross_domain_code_challenge\", \"outer-challenge\");\n currentUrl.searchParams.set(\"hexclave_cross_domain_after_callback_redirect_url\", \"https://customer.example.test/dashboard\");\n Reflect.set(globalThis, \"window\", {\n location: {\n href: currentUrl.toString(),\n },\n });\n\n const callbackUrl = new URL(constructRedirectUrl(\"/handler/password-reset#discarded\", \"callbackUrl\"));\n\n expect(callbackUrl.toString()).toBe(\n \"https://hosted.example.test/handler/password-reset\"\n + \"?after_auth_return_to=https%3A%2F%2Fcustomer.example.test%2Fhandler%2Foauth-callback%3Fhexclave_cross_domain_auth%3D1\"\n + \"&hexclave_cross_domain_state=outer-state\"\n + \"&hexclave_cross_domain_code_challenge=outer-challenge\"\n + \"&hexclave_cross_domain_after_callback_redirect_url=https%3A%2F%2Fcustomer.example.test%2Fdashboard\",\n );\n });\n\n it(\"does not synthesize the forgot-password page as a return target\", () => {\n Reflect.set(globalThis, \"window\", {\n location: {\n href: \"https://hosted.example.test/handler/forgot-password\",\n },\n });\n\n expect(constructRedirectUrl(\"/handler/password-reset\", \"callbackUrl\")).toBe(\n \"https://hosted.example.test/handler/password-reset\",\n );\n });\n});\n"],"mappings":";;;AAOA,MAAM,iBAAiB,QAAQ,IAAI,YAAY,QAAQ;AACvD,MAAM,oBAAoB,QAAQ,IAAI,YAAY,QAAQ;AAE1D,gBAAgB;CACd,IAAI,mBACF,QAAQ,IAAI,YAAY,UAAU,cAAc;MAEhD,QAAQ,eAAe,YAAY,QAAQ;AAE/C,CAAC;AAED,SAAS,8BAA8B;CACrC,GAAG,gFAAgF;EACjF,MAAM,aAAa,IAAI,IAAI,qDAAqD;EAChF,WAAW,aAAa,IAAI,wBAAwB,mFAAmF;EACvI,WAAW,aAAa,IAAI,+BAA+B,aAAa;EACxE,WAAW,aAAa,IAAI,wCAAwC,iBAAiB;EACrF,WAAW,aAAa,IAAI,qDAAqD,yCAAyC;EAC1H,QAAQ,IAAI,YAAY,UAAU,EAChC,UAAU,EACR,MAAM,WAAW,SAAS,EAC5B,EACF,CAAC;EAID,OAAO,IAFiB,IAAI,qBAAqB,qCAAqC,aAAa,CAElF,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAC7B,wWAKF;CACF,CAAC;CAED,GAAG,yEAAyE;EAC1E,QAAQ,IAAI,YAAY,UAAU,EAChC,UAAU,EACR,MAAM,sDACR,EACF,CAAC;EAED,OAAO,qBAAqB,2BAA2B,aAAa,CAAC,CAAC,CAAC,KACrE,oDACF;CACF,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as StackAdminApp, a as StackClientApp, z as StackServerApp } from "./client-app-
|
|
1
|
+
import { N as StackAdminApp, a as StackClientApp, z as StackServerApp } from "./client-app-BCT5p_70.js";
|
|
2
2
|
import { t as TranslationProvider } from "./translation-provider-WOaZXqAz.js";
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
@@ -26,4 +26,4 @@ declare const HexclaveProvider: typeof NextStackProvider;
|
|
|
26
26
|
declare const StackProvider: typeof NextStackProvider;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { HexclaveProvider as n, StackProvider as r, ActiveProvider as t };
|
|
29
|
-
//# sourceMappingURL=hexclave-provider-
|
|
29
|
+
//# sourceMappingURL=hexclave-provider-BKxi3Vy-.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hexclave-provider-
|
|
1
|
+
{"version":3,"file":"hexclave-provider-BKxi3Vy-.d.ts","names":[],"sources":["../src/providers/hexclave-provider.tsx"],"mappings":";;;;;iBASS,iBAAA;EACP,QAAA;EACA,GAAA;EACA,IAAA;EACA;AAAA;EAEA,IAAA,GAAO,KAAA,CAAM,cAAA,QAAsB,mBAAA;;AARwB;;;;;EAe3D,oBAAA,GAAuB,MAAA;EACvB,QAAA,EAAU,KAAA,CAAM,SAAA;EAEhB,GAAA,EAAK,cAAA,SAAuB,cAAA,SAAuB,aAAA;AAAA,gCACpD,GAAA,CAAA,OAAA;AAAA,cAcK,cAAA,SAAc,iBAAoB;AAAA,cAI3B,gBAAA,SAAgB,iBAAiB;;cAEjC,aAAA,SAAa,iBAAiB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { s as GetCurrentUserOptions } from "./common-B2gkWlXX.js";
|
|
2
|
-
import { a as StackClientApp, ht as CurrentUser, pt as CurrentInternalUser } from "./client-app-
|
|
2
|
+
import { a as StackClientApp, ht as CurrentUser, pt as CurrentInternalUser } from "./client-app-BCT5p_70.js";
|
|
3
3
|
//#region src/lib/hooks.d.ts
|
|
4
4
|
type GetUserOptions = GetCurrentUserOptions<true> & {
|
|
5
5
|
projectIdMustMatch?: string;
|
|
@@ -40,4 +40,4 @@ declare function useStackApp<ProjectId extends string>(options?: {
|
|
|
40
40
|
}): StackClientApp<true, ProjectId>;
|
|
41
41
|
//#endregion
|
|
42
42
|
export { useStackApp as n, useUser as r, useHexclaveApp as t };
|
|
43
|
-
//# sourceMappingURL=hooks-
|
|
43
|
+
//# sourceMappingURL=hooks-CUe5bc3s.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-
|
|
1
|
+
{"version":3,"file":"hooks-CUe5bc3s.d.ts","names":[],"sources":["../src/lib/hooks.tsx"],"mappings":";;;KAQK,cAAA,GAAiB,qBAAiB;EACrC,kBAAkB;AAAA;;AAHwG;;;;iBAW5G,OAAA,CAAQ,OAAA,EAAS,cAAA;EAAmB,EAAA;EAA0B,kBAAA;AAAA,IAAmC,mBAAmB;AAAA,iBACpH,OAAA,CAAQ,OAAA,EAAS,cAAA;EAAmB,EAAA;AAAA,IAA6B,WAAW;AAAA,iBAC5E,OAAA,CAAQ,OAAA,EAAS,cAAA;EAAmB,kBAAA;AAAA,IAAmC,mBAAmB;AAAA,iBAC1F,OAAA,CAAQ,OAAA,GAAU,cAAA,GAAiB,WAAA,GAAc,mBAAA;AAHmE;AACpI;;;;AADoI,iBAqBpH,cAAA,2BAAyC,OAAA;EAAW,kBAAA,GAAqB,SAAA;AAAA,IAAmB,cAAA,OAAqB,SAAA;;;AApBrC;AAC5F;;;;iBAyCgB,WAAA,2BAAsC,OAAA;EAAW,kBAAA,GAAqB,SAAA;AAAA,IAAmB,cAAA,OAAqB,SAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as HandlerUrls } from "./common-B2gkWlXX.js";
|
|
2
|
-
import { Q as Team, a as StackClientApp } from "./client-app-
|
|
2
|
+
import { Q as Team, a as StackClientApp } from "./client-app-BCT5p_70.js";
|
|
3
3
|
import { t as AccountSettings } from "./account-settings-cTsj8rpJ.js";
|
|
4
4
|
import { t as CliAuthConfirmation } from "./cli-auth-confirm-BW3PYpKb.js";
|
|
5
5
|
import { t as EmailVerification } from "./email-verification-Cr_KKvtQ.js";
|
|
@@ -144,4 +144,4 @@ type TeamSwitcherProps<AllowNull extends boolean = false> = {
|
|
|
144
144
|
declare function TeamSwitcher<AllowNull extends boolean = false>(props: TeamSwitcherProps<AllowNull>): import("react/jsx-runtime").JSX.Element;
|
|
145
145
|
//#endregion
|
|
146
146
|
export { TeamSwitcher as a, StackHandler as c, getRedirectToPageResult as d, defineStackConfig as i, BaseHandlerProps as l, StackConfig as n, SelectedTeamSwitcher as o, defineHexclaveConfig as r, HexclaveHandler as s, HexclaveConfig as t, HexclaveHandlerClient as u };
|
|
147
|
-
//# sourceMappingURL=index-
|
|
147
|
+
//# sourceMappingURL=index-CvB7XacB.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-CvB7XacB.d.ts","names":[],"sources":["../src/components-page/hexclave-handler-client.tsx","../src/components-page/hexclave-handler.tsx","../src/components/selected-team-switcher.tsx","../src/components/team-switcher.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;KAmCK,UAAA;EACH,MAAA,SAAe,MAAA;EACf,MAAA,SAAe,MAAA;EACf,iBAAA,SAA0B,iBAAA;EAC1B,aAAA,SAAsB,aAAA;EACtB,cAAA,SAAuB,cAAA;EACvB,OAAA,SAAgB,OAAA;EAChB,aAAA,SAAsB,aAAA;EACtB,iBAAA,SAA0B,iBAAA;EAC1B,cAAA,SAAuB,cAAA;EACvB,SAAA,SAAkB,SAAA;EAClB,eAAA,SAAwB,eAAA;EACxB,mBAAA,SAA4B,mBAAA;EAC5B,GAAA,SAAY,GAAA;EACZ,UAAA,SAAmB,UAAA;AAAA;AAAA,KAGhB,UAAA;EACH,MAAA,EAAQ,OAAA;IAAU,KAAA;EAAA;IAAwB,KAAA;EAAA;EAC1C,YAAA,EAAc,OAAA,CAAQ,MAAA,oBAA0B,MAAA;AAAA;AAAA,KAG7C,oBAAA;EACC,MAAA;AAAA;EACA,MAAA;EAAuB,KAAA,EAAO,UAAU;AAAA;EACxC,MAAA;AAAA;AAAA,KA4BM,gBAAA;EACV,QAAA;EACA,cAAA,iBACc,UAAA,IAAc,UAAA,CAAW,UAAA,CAAW,CAAA;AAAA;AAAA,iBAgJ9B,uBAAA,CACpB,GAAA,EAAK,cAAA,EACL,cAAA,QAAsB,WAAA,GACrB,OAAA,CAAQ,oBAAA;AAAA,iBAiCK,qBAAA,CAAsB,KAAA,EAAO,gBAAA,GAAmB,OAAA,CAAQ,UAAA;EAAgB,QAAA;AAAA;;;KCnQnF,oBAAA,GAAuB,gBAAgB;EAAK,QAAA;AAAA;;;;EAI/C,GAAA;;;;EAKA,UAAA;;;;EAKA,MAAA;;;;EAKA,YAAA;AAAA;AAAA,iBAGO,WAAA;EAAc,GAAA;EAAK,UAAA;EAAY,MAAA;EAAQ,YAAA;EAAA,GAAiB;AAAA,GAAS,oBAAA,+BAAoB,GAAA,CAAA,OAAA;AAAA,cAKjF,eAAA,SAAe,WAAc;;cAG7B,YAAA,SAAY,WAAc;;;KC5BlC,UAAA;EACH,EAAA;EACA,WAAA;EACA,eAAA;AAAA;AAAA,KAGG,yBAAA;EACH,MAAA,IAAU,IAAA,EAAM,SAAA,gBAAyB,IAAA,UAAc,IAAA;EACvD,YAAA,GAAe,IAAA;EACf,oBAAA;EACA,SAAA,GAAY,SAAA;EACZ,SAAA;EACA,QAAA,IAAY,IAAA,EAAM,SAAA,gBAAyB,IAAA,UAAc,IAAA;EACzD,gBAAA;EAEA,QAAA;IACE,YAAA,GAAe,UAAA;EAAA;EAEjB,SAAA,GAAY,UAAA;EACZ,WAAA;IACE,MAAA;MACE,yBAAA;IAAA;EAAA;AAAA;AAAA,iBAKU,oBAAA,oCAAwD,KAAA,EAAO,yBAAyB,CAAC,SAAA,gCAAU,GAAA,CAAA,OAAA;;;KCZ9G,QAAA;EACH,EAAA;EACA,WAAA;EACA,eAAA;AAAA;AAAA,KAGG,iBAAA;EACH,IAAA,GAAO,IAAA;EACP,MAAA;EACA,KAAA,GAAQ,IAAA;EACR,SAAA,GAAY,SAAA;EACZ,SAAA;EACA,gBAAA;EACA,QAAA,IAAY,IAAA,EAAM,SAAA,gBAAyB,IAAA,UAAc,IAAA,KAAS,OAAA;EAElE,QAAA;IACE,IAAA,GAAO,QAAA;EAAA;EAET,SAAA,GAAY,QAAA;EACZ,WAAA;IACE,MAAA;MACE,yBAAA;IAAA;EAAA;AAAA;AAAA,iBAKU,YAAA,oCAAgD,KAAA,EAAO,iBAAiB,CAAC,SAAA,gCAAU,GAAA,CAAA,OAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { a as PlanUsageRow, i as PlanUsagePlanId, n as PlanUsageKind, r as PlanU
|
|
|
6
6
|
import { a as AdminWorkflowRunState, c as AdminWorkflowStepAttempt, d as AdminWorkflowUpgradeResult, f as AdminWorkflowVersion, i as AdminWorkflowRunDetails, l as AdminWorkflowSyncResult, n as AdminWorkflowDivergenceDiagnostic, o as AdminWorkflowRunsFilter, r as AdminWorkflowRun, s as AdminWorkflowStep, t as AdminWorkflow, u as AdminWorkflowTrigger } from "./workflows-DEb7pIuQ.js";
|
|
7
7
|
import { r as OAuthConnection, t as Connection } from "./index-C_kxyHao.js";
|
|
8
8
|
import { i as ServerContactChannel, t as ContactChannel } from "./index-DN04TjLM.js";
|
|
9
|
-
import { $ as TeamCreateOptions, B as StackServerAppConstructor, D as HexclaveAdminApp, E as EmailOutboxUpdateOptions, F as StackAdminAppConstructorOptions, H as EditableTeamMemberProfile, I as HexclaveServerApp, J as ServerTeamCreateOptions, K as ServerListUsersOptions, L as HexclaveServerAppConstructor, N as StackAdminApp, O as HexclaveAdminAppConstructor, Ot as User, P as StackAdminAppConstructor, Q as Team, R as HexclaveServerAppConstructorOptions, St as ServerUser, T as EmailOutboxListResult, U as ReceivedTeamInvitation, V as StackServerAppConstructorOptions, W as SentTeamInvitation, X as ServerTeamUpdateOptions, Y as ServerTeamMemberProfile, Z as ServerTeamUser, _ as AdminProjectCreateOptions, _t as OAuthProvider, a as StackClientApp, c as StackClientAppJson, d as AdminDeploymentEnvVarOptions, et as TeamInvitation, f as AdminDeploymentRunJson, ft as CurrentInternalServerUser, g as AdminProject, h as AdminOwnedProject, ht as CurrentUser, i as HexclaveClientAppJson, it as TeamUser, k as HexclaveAdminAppConstructorOptions, l as AdminDeploymentDomainJson, m as AdminDeploymentServiceJson, mt as CurrentServerUser, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, p as AdminDeploymentServiceBuildOptions, pt as CurrentInternalUser, q as ServerTeam, r as HexclaveClientAppConstructorOptions, rt as TeamUpdateOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp, tt as TeamMemberProfile, u as AdminDeploymentEnvVarJson, ut as Auth, v as AdminProjectUpdateOptions, w as EmailOutboxListOptions, x as PushedConfigSource, xt as ServerOAuthProvider, y as Project, z as StackServerApp } from "./client-app-
|
|
9
|
+
import { $ as TeamCreateOptions, B as StackServerAppConstructor, D as HexclaveAdminApp, E as EmailOutboxUpdateOptions, F as StackAdminAppConstructorOptions, H as EditableTeamMemberProfile, I as HexclaveServerApp, J as ServerTeamCreateOptions, K as ServerListUsersOptions, L as HexclaveServerAppConstructor, N as StackAdminApp, O as HexclaveAdminAppConstructor, Ot as User, P as StackAdminAppConstructor, Q as Team, R as HexclaveServerAppConstructorOptions, St as ServerUser, T as EmailOutboxListResult, U as ReceivedTeamInvitation, V as StackServerAppConstructorOptions, W as SentTeamInvitation, X as ServerTeamUpdateOptions, Y as ServerTeamMemberProfile, Z as ServerTeamUser, _ as AdminProjectCreateOptions, _t as OAuthProvider, a as StackClientApp, c as StackClientAppJson, d as AdminDeploymentEnvVarOptions, et as TeamInvitation, f as AdminDeploymentRunJson, ft as CurrentInternalServerUser, g as AdminProject, h as AdminOwnedProject, ht as CurrentUser, i as HexclaveClientAppJson, it as TeamUser, k as HexclaveAdminAppConstructorOptions, l as AdminDeploymentDomainJson, m as AdminDeploymentServiceJson, mt as CurrentServerUser, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, p as AdminDeploymentServiceBuildOptions, pt as CurrentInternalUser, q as ServerTeam, r as HexclaveClientAppConstructorOptions, rt as TeamUpdateOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp, tt as TeamMemberProfile, u as AdminDeploymentEnvVarJson, ut as Auth, v as AdminProjectUpdateOptions, w as EmailOutboxListOptions, x as PushedConfigSource, xt as ServerOAuthProvider, y as Project, z as StackServerApp } from "./client-app-BCT5p_70.js";
|
|
10
10
|
import { a as AdminProjectConfigUpdateOptions, i as AdminProjectConfig, n as AdminEmailConfig, o as OAuthProviderConfig, r as AdminOAuthProviderConfig, s as ProjectConfig, t as AdminDomainConfig } from "./index-B-MazpM_.js";
|
|
11
11
|
import { n as AnalyticsReplayOptions, t as AnalyticsOptions } from "./session-replay-CQ849yH1.js";
|
|
12
12
|
import { r as getPagePrompt } from "./url-targets-CWO0mjTr.js";
|
|
@@ -16,9 +16,9 @@ import { i as useCliAuthConfirmation, n as CliAuthConfirmationState, r as CliAut
|
|
|
16
16
|
import { t as EmailVerification } from "./email-verification-Cr_KKvtQ.js";
|
|
17
17
|
import { t as ForgotPassword } from "./forgot-password-B7RLLsC2.js";
|
|
18
18
|
import { t as PasswordReset } from "./password-reset-CxIuXeIx.js";
|
|
19
|
-
import { a as TeamSwitcher, c as StackHandler, i as defineStackConfig, n as StackConfig, o as SelectedTeamSwitcher, r as defineHexclaveConfig, s as HexclaveHandler, t as HexclaveConfig } from "./index-
|
|
20
|
-
import { n as useStackApp, r as useUser, t as useHexclaveApp } from "./hooks-
|
|
21
|
-
import { n as HexclaveProvider, r as StackProvider } from "./hexclave-provider-
|
|
19
|
+
import { a as TeamSwitcher, c as StackHandler, i as defineStackConfig, n as StackConfig, o as SelectedTeamSwitcher, r as defineHexclaveConfig, s as HexclaveHandler, t as HexclaveConfig } from "./index-CvB7XacB.js";
|
|
20
|
+
import { n as useStackApp, r as useUser, t as useHexclaveApp } from "./hooks-CUe5bc3s.js";
|
|
21
|
+
import { n as HexclaveProvider, r as StackProvider } from "./hexclave-provider-BKxi3Vy-.js";
|
|
22
22
|
import { n as StackTheme, t as HexclaveTheme } from "./theme-provider-D9_ngSbi.js";
|
|
23
23
|
import { t as AuthPage } from "./auth-page-YnM_LtbN.js";
|
|
24
24
|
import { t as SignIn } from "./sign-in-BT45jb_W.js";
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../src/lib/auth.ts"],"mappings":";;;;iBAWsB,6BAAA,CACpB,KAAA,EAAO,uBAAA,EACP,OAAA;EACE,QAAA;EACA,WAAA;EACA,gBAAA;EACA,aAAA;AAAA,GAEF,OAAA,EAAS,eAAA,GACR,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../src/lib/auth.ts"],"mappings":";;;;iBAWsB,6BAAA,CACpB,KAAA,EAAO,uBAAA,EACP,OAAA;EACE,QAAA;EACA,WAAA;EACA,gBAAA;EACA,aAAA;AAAA,GAEF,OAAA,EAAS,eAAA,GACR,OAAA;AAAA,iBA8JmB,iBAAA,CACpB,KAAA,EAAO,uBAAA,EACP,WAAA,UACA,OAAA;EACE,+BAAA;AAAA,IACD,OAAA"}
|
package/dist/lib/auth.js
CHANGED
|
@@ -12,7 +12,7 @@ async function getNewOAuthProviderOrScopeUrl(iface, options, session) {
|
|
|
12
12
|
provider: options.provider,
|
|
13
13
|
redirectUrl: (0, ___utils_url_js.constructRedirectUrl)(options.redirectUrl, "redirectUrl"),
|
|
14
14
|
errorRedirectUrl: (0, ___utils_url_js.constructRedirectUrl)(options.errorRedirectUrl, "errorRedirectUrl"),
|
|
15
|
-
afterCallbackRedirectUrl:
|
|
15
|
+
afterCallbackRedirectUrl: window.location.href,
|
|
16
16
|
codeChallenge,
|
|
17
17
|
state,
|
|
18
18
|
type: "link",
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","names":["KnownErrors","HexclaveAssertionError","KnownError","Result"],"sources":["../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownError, KnownErrors, HexclaveClientInterface } from \"@hexclave/shared\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport { HexclaveAssertionError, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { deindent } from \"@hexclave/shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\nexport async function getNewOAuthProviderOrScopeUrl(\n iface: HexclaveClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n): Promise<string> {\n const { codeChallenge, state } = await saveVerifierAndState();\n return await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl, \"redirectUrl\"),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, \"errorRedirectUrl\"),\n afterCallbackRedirectUrl: constructRedirectUrl(window.location.href, \"afterCallbackRedirectUrl\"),\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n}\n\n/**\n * Checks if the current URL has the query parameters for an OAuth callback, and if so, removes them.\n *\n * Must be synchronous for the logic in callOAuthCallback to work without race conditions.\n */\ntype OAuthCallbackConsumptionResult =\n | {\n type: \"oauth-response\",\n originalUrl: URL,\n codeVerifier: string,\n state: string,\n }\n | {\n type: \"known-error\",\n error: KnownError,\n };\n\nconst oauthErrorParams = [\"error\", \"error_description\", \"errorCode\", \"message\", \"details\"] as const;\n\nfunction removeOAuthErrorParamsFromHistory(originalUrl: URL): void {\n const newUrl = new URL(originalUrl);\n for (const param of oauthErrorParams) {\n newUrl.searchParams.delete(param);\n }\n window.history.replaceState({}, \"\", newUrl.toString());\n}\n\nfunction getProviderOAuthErrorFromUrl(originalUrl: URL): KnownError | null {\n const providerError = originalUrl.searchParams.get(\"error\");\n const providerErrorDescription = originalUrl.searchParams.get(\"error_description\");\n if (providerError == null && providerErrorDescription == null) {\n return null;\n }\n\n switch (providerError) {\n case \"access_denied\":\n case \"consent_required\": {\n return new KnownErrors.OAuthProviderAccessDenied();\n }\n case \"server_error\":\n case \"temporarily_unavailable\":\n default: {\n return new KnownErrors.OAuthProviderTemporarilyUnavailable();\n }\n }\n}\n\nfunction consumeOAuthCallbackQueryParams(options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n}): OAuthCallbackConsumptionResult | null {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n const knownErrorCode = originalUrl.searchParams.get(\"errorCode\");\n const knownErrorMessage = originalUrl.searchParams.get(\"message\");\n if (knownErrorCode && knownErrorMessage) {\n const details = originalUrl.searchParams.get(\"details\");\n let detailsJson = {};\n if (details) {\n try {\n detailsJson = JSON.parse(details);\n } catch (error) {\n throw new HexclaveAssertionError(\"OAuth callback returned malformed known-error details\", {\n details,\n cause: error,\n });\n }\n }\n\n removeOAuthErrorParamsFromHistory(originalUrl);\n\n return {\n type: \"known-error\",\n error: KnownError.fromJson({\n code: knownErrorCode,\n message: knownErrorMessage,\n details: detailsJson,\n }),\n };\n }\n\n const providerOAuthError = getProviderOAuthErrorFromUrl(originalUrl);\n if (providerOAuthError != null && !requiredParams.every(param => originalUrl.searchParams.has(param))) {\n removeOAuthErrorParamsFromHistory(originalUrl);\n return {\n type: \"known-error\",\n error: providerOAuthError,\n };\n }\n\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\n if (!options?.dontWarnAboutMissingQueryParams) {\n console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));\n }\n return null;\n }\n }\n\n const expectedState = originalUrl.searchParams.get(\"state\") ?? throwErr(\"This should never happen; isn't state required above?\");\n const cookieResult = consumeVerifierAndStateCookie(expectedState);\n\n if (!cookieResult) {\n // If the state can't be found in the cookies, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\n console.warn(deindent`\n Hexclave found an outer OAuth callback state in the query parameters, but not in cookies.\n\n This could have multiple reasons:\n - The cookie expired, because the OAuth flow took too long.\n - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.\n - The cookie was already consumed by this page, and the user already logged in.\n - You are using another OAuth client library with the same callback URL as Hexclave.\n - The user opened the OAuth callback page from their history.\n\n Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.\n `);\n return null;\n }\n\n\n const newUrl = new URL(originalUrl);\n for (const param of requiredParams) {\n newUrl.searchParams.delete(param);\n }\n\n // let's get rid of the authorization code in the history as we\n // don't redirect to `redirectUrl` if there's a validation error\n // (as the redirectUrl might be malicious!).\n //\n // We use history.replaceState instead of location.assign(...) to\n // prevent an unnecessary reload\n window.history.replaceState({}, \"\", newUrl.toString());\n\n return {\n type: \"oauth-response\",\n originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: HexclaveClientInterface,\n redirectUrl: string,\n options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n },\n) {\n // note: this part of the function (until the return) needs\n // to be synchronous, to prevent race conditions when\n // callOAuthCallback is called multiple times in parallel\n const consumed = consumeOAuthCallbackQueryParams(options);\n if (!consumed) return Result.ok(undefined);\n if (consumed.type === \"known-error\") {\n throw consumed.error;\n }\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback, and the only instance\n // of callOAuthCallback that's running)\n try {\n return Result.ok(await iface.callOAuthCallback({\n oauthParams: consumed.originalUrl.searchParams,\n redirectUri: constructRedirectUrl(redirectUrl, \"redirectUri\"),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n throw e;\n }\n throw new HexclaveAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","names":["KnownErrors","HexclaveAssertionError","KnownError","Result"],"sources":["../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownError, KnownErrors, HexclaveClientInterface } from \"@hexclave/shared\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport { HexclaveAssertionError, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { deindent } from \"@hexclave/shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\nexport async function getNewOAuthProviderOrScopeUrl(\n iface: HexclaveClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n): Promise<string> {\n const { codeChallenge, state } = await saveVerifierAndState();\n return await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl, \"redirectUrl\"),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, \"errorRedirectUrl\"),\n // Unlike callback URLs, this is the final user-facing location and may legitimately use a\n // fragment for an account-settings tab. Preserve it exactly.\n afterCallbackRedirectUrl: window.location.href,\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n}\n\n/**\n * Checks if the current URL has the query parameters for an OAuth callback, and if so, removes them.\n *\n * Must be synchronous for the logic in callOAuthCallback to work without race conditions.\n */\ntype OAuthCallbackConsumptionResult =\n | {\n type: \"oauth-response\",\n originalUrl: URL,\n codeVerifier: string,\n state: string,\n }\n | {\n type: \"known-error\",\n error: KnownError,\n };\n\nconst oauthErrorParams = [\"error\", \"error_description\", \"errorCode\", \"message\", \"details\"] as const;\n\nfunction removeOAuthErrorParamsFromHistory(originalUrl: URL): void {\n const newUrl = new URL(originalUrl);\n for (const param of oauthErrorParams) {\n newUrl.searchParams.delete(param);\n }\n window.history.replaceState({}, \"\", newUrl.toString());\n}\n\nfunction getProviderOAuthErrorFromUrl(originalUrl: URL): KnownError | null {\n const providerError = originalUrl.searchParams.get(\"error\");\n const providerErrorDescription = originalUrl.searchParams.get(\"error_description\");\n if (providerError == null && providerErrorDescription == null) {\n return null;\n }\n\n switch (providerError) {\n case \"access_denied\":\n case \"consent_required\": {\n return new KnownErrors.OAuthProviderAccessDenied();\n }\n case \"server_error\":\n case \"temporarily_unavailable\":\n default: {\n return new KnownErrors.OAuthProviderTemporarilyUnavailable();\n }\n }\n}\n\nfunction consumeOAuthCallbackQueryParams(options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n}): OAuthCallbackConsumptionResult | null {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n const knownErrorCode = originalUrl.searchParams.get(\"errorCode\");\n const knownErrorMessage = originalUrl.searchParams.get(\"message\");\n if (knownErrorCode && knownErrorMessage) {\n const details = originalUrl.searchParams.get(\"details\");\n let detailsJson = {};\n if (details) {\n try {\n detailsJson = JSON.parse(details);\n } catch (error) {\n throw new HexclaveAssertionError(\"OAuth callback returned malformed known-error details\", {\n details,\n cause: error,\n });\n }\n }\n\n removeOAuthErrorParamsFromHistory(originalUrl);\n\n return {\n type: \"known-error\",\n error: KnownError.fromJson({\n code: knownErrorCode,\n message: knownErrorMessage,\n details: detailsJson,\n }),\n };\n }\n\n const providerOAuthError = getProviderOAuthErrorFromUrl(originalUrl);\n if (providerOAuthError != null && !requiredParams.every(param => originalUrl.searchParams.has(param))) {\n removeOAuthErrorParamsFromHistory(originalUrl);\n return {\n type: \"known-error\",\n error: providerOAuthError,\n };\n }\n\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\n if (!options?.dontWarnAboutMissingQueryParams) {\n console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));\n }\n return null;\n }\n }\n\n const expectedState = originalUrl.searchParams.get(\"state\") ?? throwErr(\"This should never happen; isn't state required above?\");\n const cookieResult = consumeVerifierAndStateCookie(expectedState);\n\n if (!cookieResult) {\n // If the state can't be found in the cookies, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\n console.warn(deindent`\n Hexclave found an outer OAuth callback state in the query parameters, but not in cookies.\n\n This could have multiple reasons:\n - The cookie expired, because the OAuth flow took too long.\n - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.\n - The cookie was already consumed by this page, and the user already logged in.\n - You are using another OAuth client library with the same callback URL as Hexclave.\n - The user opened the OAuth callback page from their history.\n\n Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.\n `);\n return null;\n }\n\n\n const newUrl = new URL(originalUrl);\n for (const param of requiredParams) {\n newUrl.searchParams.delete(param);\n }\n\n // let's get rid of the authorization code in the history as we\n // don't redirect to `redirectUrl` if there's a validation error\n // (as the redirectUrl might be malicious!).\n //\n // We use history.replaceState instead of location.assign(...) to\n // prevent an unnecessary reload\n window.history.replaceState({}, \"\", newUrl.toString());\n\n return {\n type: \"oauth-response\",\n originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: HexclaveClientInterface,\n redirectUrl: string,\n options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n },\n) {\n // note: this part of the function (until the return) needs\n // to be synchronous, to prevent race conditions when\n // callOAuthCallback is called multiple times in parallel\n const consumed = consumeOAuthCallbackQueryParams(options);\n if (!consumed) return Result.ok(undefined);\n if (consumed.type === \"known-error\") {\n throw consumed.error;\n }\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback, and the only instance\n // of callOAuthCallback that's running)\n try {\n return Result.ok(await iface.callOAuthCallback({\n oauthParams: consumed.originalUrl.searchParams,\n redirectUri: constructRedirectUrl(redirectUrl, \"redirectUri\"),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n throw e;\n }\n throw new HexclaveAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":"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"}
|
package/dist/lib/auth.test.js
CHANGED
|
@@ -24,7 +24,7 @@ function createTestInterface() {
|
|
|
24
24
|
}
|
|
25
25
|
(0, vitest.describe)("getNewOAuthProviderOrScopeUrl", () => {
|
|
26
26
|
(0, vitest.it)("returns the OAuth URL without performing navigation", async () => {
|
|
27
|
-
window.history.replaceState({}, "", "/account?after_auth_return_to=%2Fsettings");
|
|
27
|
+
window.history.replaceState({}, "", "/account?after_auth_return_to=%2Fsettings#connected-accounts");
|
|
28
28
|
const iface = createTestInterface();
|
|
29
29
|
const location = await (0, __auth_js.getNewOAuthProviderOrScopeUrl)(iface, {
|
|
30
30
|
provider: "github",
|
|
@@ -39,7 +39,7 @@ function createTestInterface() {
|
|
|
39
39
|
(0, vitest.expect)(`${url.origin}${url.pathname}`).toBe("https://api.example.com/api/v1/auth/oauth/authorize/github");
|
|
40
40
|
(0, vitest.expect)(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`
|
|
41
41
|
{
|
|
42
|
-
"after_callback_redirect_url": "http://localhost:3000/account?after_auth_return_to=%2Fsettings",
|
|
42
|
+
"after_callback_redirect_url": "http://localhost:3000/account?after_auth_return_to=%2Fsettings#connected-accounts",
|
|
43
43
|
"client_id": "00000000-0000-4000-8000-000000000000",
|
|
44
44
|
"client_secret": "pck_test",
|
|
45
45
|
"code_challenge": "<stripped code challenge>",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.test.js","names":["vi","HexclaveClientInterface","KnownErrors"],"sources":["../../src/lib/auth.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport { HexclaveClientInterface, KnownErrors } from \"@hexclave/shared\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from \"./auth\";\n\nvi.mock(\"./cookie\", async (importOriginal) => {\n const actual = await importOriginal<typeof import(\"./cookie\")>();\n return {\n ...actual,\n saveVerifierAndState: async () => ({\n codeChallenge: \"<stripped code challenge>\",\n state: \"<stripped state>\",\n }),\n };\n});\n\nfunction createTestInterface() {\n return new HexclaveClientInterface({\n clientVersion: \"test\",\n getBaseUrl: () => \"https://api.example.com\",\n getApiUrls: () => [\"https://api.example.com\"],\n extraRequestHeaders: {},\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"pck_test\",\n });\n}\n\ndescribe(\"getNewOAuthProviderOrScopeUrl\", () => {\n it(\"returns the OAuth URL without performing navigation\", async () => {\n window.history.replaceState({}, \"\", \"/account?after_auth_return_to=%2Fsettings\");\n\n const iface = createTestInterface();\n const session = iface.createSession({ refreshToken: null, accessToken: null });\n\n const location = await getNewOAuthProviderOrScopeUrl(\n iface,\n {\n provider: \"github\",\n redirectUrl: \"/handler/oauth-callback\",\n errorRedirectUrl: \"/handler/error\",\n providerScope: \"repo user\",\n },\n session,\n );\n\n const url = new URL(location);\n expect(`${url.origin}${url.pathname}`).toBe(\"https://api.example.com/api/v1/auth/oauth/authorize/github\");\n expect(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`\n {\n \"after_callback_redirect_url\": \"http://localhost:3000/account?after_auth_return_to=%2Fsettings\",\n \"client_id\": \"00000000-0000-4000-8000-000000000000\",\n \"client_secret\": \"pck_test\",\n \"code_challenge\": \"<stripped code challenge>\",\n \"code_challenge_method\": \"S256\",\n \"error_redirect_url\": \"http://localhost:3000/handler/error?after_auth_return_to=%2Fsettings\",\n \"grant_type\": \"authorization_code\",\n \"provider_scope\": \"repo user\",\n \"redirect_uri\": \"http://localhost:3000/handler/oauth-callback?after_auth_return_to=%2Fsettings\",\n \"response_type\": \"code\",\n \"scope\": \"legacy\",\n \"state\": \"<stripped state>\",\n \"type\": \"link\",\n }\n `);\n });\n});\n\ndescribe(\"callOAuthCallback\", () => {\n it(\"turns provider access denial callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=access_denied&error_description=User+cancelled\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderAccessDenied.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n\n it(\"turns generic provider error callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=server_error&error_description=Provider+failed\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderTemporarilyUnavailable.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n});\n"],"mappings":";;;;;AAUAA,OAAAA,GAAG,KAAK,YAAY,OAAO,mBAAmB;CAE5C,OAAO;EACL,GAAG,MAFgB,eAA0C;EAG7D,sBAAsB,aAAa;GACjC,eAAe;GACf,OAAO;EACT;CACF;AACF,CAAC;AAED,SAAS,sBAAsB;CAC7B,OAAO,IAAIC,iBAAAA,wBAAwB;EACjC,eAAe;EACf,kBAAkB;EAClB,kBAAkB,CAAC,yBAAyB;EAC5C,qBAAqB,CAAC;EACtB,WAAW;EACX,sBAAsB;CACxB,CAAC;AACH;qBAES,uCAAuC;CAC9C,CAAA,GAAA,OAAA,GAAA,CAAG,uDAAuD,YAAY;EACpE,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"auth.test.js","names":["vi","HexclaveClientInterface","KnownErrors"],"sources":["../../src/lib/auth.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport { HexclaveClientInterface, KnownErrors } from \"@hexclave/shared\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from \"./auth\";\n\nvi.mock(\"./cookie\", async (importOriginal) => {\n const actual = await importOriginal<typeof import(\"./cookie\")>();\n return {\n ...actual,\n saveVerifierAndState: async () => ({\n codeChallenge: \"<stripped code challenge>\",\n state: \"<stripped state>\",\n }),\n };\n});\n\nfunction createTestInterface() {\n return new HexclaveClientInterface({\n clientVersion: \"test\",\n getBaseUrl: () => \"https://api.example.com\",\n getApiUrls: () => [\"https://api.example.com\"],\n extraRequestHeaders: {},\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"pck_test\",\n });\n}\n\ndescribe(\"getNewOAuthProviderOrScopeUrl\", () => {\n it(\"returns the OAuth URL without performing navigation\", async () => {\n window.history.replaceState({}, \"\", \"/account?after_auth_return_to=%2Fsettings#connected-accounts\");\n\n const iface = createTestInterface();\n const session = iface.createSession({ refreshToken: null, accessToken: null });\n\n const location = await getNewOAuthProviderOrScopeUrl(\n iface,\n {\n provider: \"github\",\n redirectUrl: \"/handler/oauth-callback\",\n errorRedirectUrl: \"/handler/error\",\n providerScope: \"repo user\",\n },\n session,\n );\n\n const url = new URL(location);\n expect(`${url.origin}${url.pathname}`).toBe(\"https://api.example.com/api/v1/auth/oauth/authorize/github\");\n expect(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`\n {\n \"after_callback_redirect_url\": \"http://localhost:3000/account?after_auth_return_to=%2Fsettings#connected-accounts\",\n \"client_id\": \"00000000-0000-4000-8000-000000000000\",\n \"client_secret\": \"pck_test\",\n \"code_challenge\": \"<stripped code challenge>\",\n \"code_challenge_method\": \"S256\",\n \"error_redirect_url\": \"http://localhost:3000/handler/error?after_auth_return_to=%2Fsettings\",\n \"grant_type\": \"authorization_code\",\n \"provider_scope\": \"repo user\",\n \"redirect_uri\": \"http://localhost:3000/handler/oauth-callback?after_auth_return_to=%2Fsettings\",\n \"response_type\": \"code\",\n \"scope\": \"legacy\",\n \"state\": \"<stripped state>\",\n \"type\": \"link\",\n }\n `);\n });\n});\n\ndescribe(\"callOAuthCallback\", () => {\n it(\"turns provider access denial callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=access_denied&error_description=User+cancelled\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderAccessDenied.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n\n it(\"turns generic provider error callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=server_error&error_description=Provider+failed\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderTemporarilyUnavailable.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n});\n"],"mappings":";;;;;AAUAA,OAAAA,GAAG,KAAK,YAAY,OAAO,mBAAmB;CAE5C,OAAO;EACL,GAAG,MAFgB,eAA0C;EAG7D,sBAAsB,aAAa;GACjC,eAAe;GACf,OAAO;EACT;CACF;AACF,CAAC;AAED,SAAS,sBAAsB;CAC7B,OAAO,IAAIC,iBAAAA,wBAAwB;EACjC,eAAe;EACf,kBAAkB;EAClB,kBAAkB,CAAC,yBAAyB;EAC5C,qBAAqB,CAAC;EACtB,WAAW;EACX,sBAAsB;CACxB,CAAC;AACH;qBAES,uCAAuC;CAC9C,CAAA,GAAA,OAAA,GAAA,CAAG,uDAAuD,YAAY;EACpE,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8DAA8D;EAElG,MAAM,QAAQ,oBAAoB;EAGlC,MAAM,WAAW,OAAA,GAAA,UAAA,8BAAA,CACf,OACA;GACE,UAAU;GACV,aAAa;GACb,kBAAkB;GAClB,eAAe;EACjB,GATc,MAAM,cAAc;GAAE,cAAc;GAAM,aAAa;EAAK,CAUpE,CACR;EAEA,MAAM,MAAM,IAAI,IAAI,QAAQ;EAC5B,CAAA,GAAA,OAAA,OAAA,CAAO,GAAG,IAAI,SAAS,IAAI,UAAU,CAAC,CAAC,KAAK,4DAA4D;EACxG,CAAA,GAAA,OAAA,OAAA,CAAO,OAAO,YAAY,IAAI,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC,sBAAsB;;;;;;;;;;;;;;;;KAgB5E;CACH,CAAC;AACH,CAAC;qBAEQ,2BAA2B;CAClC,CAAA,GAAA,OAAA,GAAA,CAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,OAAA,GAAA,OAAA,OAAA,EAAA,GAAA,UAAA,kBAAA,CAA+B,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmBC,iBAAAA,YAAY,0BAA0B,WAAW,KAAK,CAAC;EAChG,CAAA,GAAA,OAAA,OAAA,CAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;CAED,CAAA,GAAA,OAAA,GAAA,CAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,OAAA,GAAA,OAAA,OAAA,EAAA,GAAA,UAAA,kBAAA,CAA+B,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmBA,iBAAAA,YAAY,oCAAoC,WAAW,KAAK,CAAC;EAC1G,CAAA,GAAA,OAAA,OAAA,CAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;AACH,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as _HexclaveAdminAppImplIncomplete } from "../../../../admin-app-impl-
|
|
1
|
+
import { t as _HexclaveAdminAppImplIncomplete } from "../../../../admin-app-impl-FZdANO62.js";
|
|
2
2
|
export { _HexclaveAdminAppImplIncomplete };
|
package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
let vitest = require("vitest");
|
|
2
|
+
let ______common_js = require("../../common.js");
|
|
3
|
+
let ___interfaces_client_app_js = require("../interfaces/client-app.js");
|
|
4
|
+
//#region src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts
|
|
5
|
+
const baseOptions = {
|
|
6
|
+
baseUrl: "http://localhost:12345",
|
|
7
|
+
projectId: "00000000-0000-4000-8000-000000000000",
|
|
8
|
+
publishableClientKey: "stack-pk-test",
|
|
9
|
+
tokenStore: "memory",
|
|
10
|
+
redirectMethod: "none"
|
|
11
|
+
};
|
|
12
|
+
(0, vitest.describe)("HexclaveClientApp automatic side effects", () => {
|
|
13
|
+
(0, vitest.it)("does not inspect browser state when disabled", () => {
|
|
14
|
+
const previousWindow = Reflect.get(globalThis, "window");
|
|
15
|
+
const previousDocument = Reflect.get(globalThis, "document");
|
|
16
|
+
const hadPreviousWindow = Reflect.has(globalThis, "window");
|
|
17
|
+
const hadPreviousDocument = Reflect.has(globalThis, "document");
|
|
18
|
+
const browserGlobal = {};
|
|
19
|
+
Object.defineProperty(browserGlobal, "location", { get() {
|
|
20
|
+
throw new Error("Construction must not inspect the current URL when automatic side effects are disabled");
|
|
21
|
+
} });
|
|
22
|
+
Reflect.set(globalThis, "window", browserGlobal);
|
|
23
|
+
Object.defineProperty(globalThis, "document", {
|
|
24
|
+
configurable: true,
|
|
25
|
+
get() {
|
|
26
|
+
throw new Error("Construction must not access the document when automatic side effects are disabled");
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
try {
|
|
30
|
+
(0, vitest.expect)(() => new ___interfaces_client_app_js.HexclaveClientApp({
|
|
31
|
+
...baseOptions,
|
|
32
|
+
automaticSideEffects: false
|
|
33
|
+
})).not.toThrow();
|
|
34
|
+
} finally {
|
|
35
|
+
if (hadPreviousWindow) Reflect.set(globalThis, "window", previousWindow);
|
|
36
|
+
else Reflect.deleteProperty(globalThis, "window");
|
|
37
|
+
if (hadPreviousDocument) Object.defineProperty(globalThis, "document", {
|
|
38
|
+
configurable: true,
|
|
39
|
+
value: previousDocument,
|
|
40
|
+
writable: true
|
|
41
|
+
});
|
|
42
|
+
else Reflect.deleteProperty(globalThis, "document");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
(0, vitest.it)("does not initialize automatic side effects when disabled", () => {
|
|
46
|
+
const methodName = "_initializeAutomaticSideEffects";
|
|
47
|
+
const originalInitializer = Reflect.get(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName);
|
|
48
|
+
let initializationCalls = 0;
|
|
49
|
+
Reflect.set(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName, () => {
|
|
50
|
+
initializationCalls += 1;
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
new ___interfaces_client_app_js.HexclaveClientApp({
|
|
54
|
+
...baseOptions,
|
|
55
|
+
automaticSideEffects: false
|
|
56
|
+
});
|
|
57
|
+
(0, vitest.expect)(initializationCalls).toBe(0);
|
|
58
|
+
} finally {
|
|
59
|
+
Reflect.set(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName, originalInitializer);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
vitest.it.each([void 0, true])("retains automatic initialization when automaticSideEffects is %s", (automaticSideEffects) => {
|
|
63
|
+
const methodName = "_initializeAutomaticSideEffects";
|
|
64
|
+
const originalInitializer = Reflect.get(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName);
|
|
65
|
+
let initializationCalls = 0;
|
|
66
|
+
Reflect.set(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName, () => {
|
|
67
|
+
initializationCalls += 1;
|
|
68
|
+
});
|
|
69
|
+
try {
|
|
70
|
+
new ___interfaces_client_app_js.HexclaveClientApp({
|
|
71
|
+
...baseOptions,
|
|
72
|
+
automaticSideEffects
|
|
73
|
+
});
|
|
74
|
+
(0, vitest.expect)(initializationCalls).toBe(1);
|
|
75
|
+
} finally {
|
|
76
|
+
Reflect.set(___interfaces_client_app_js.HexclaveClientApp.prototype, methodName, originalInitializer);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
(0, vitest.it)("preserves the option through serialization", () => {
|
|
80
|
+
(0, vitest.expect)(new ___interfaces_client_app_js.HexclaveClientApp({
|
|
81
|
+
...baseOptions,
|
|
82
|
+
automaticSideEffects: false
|
|
83
|
+
})[______common_js.hexclaveAppInternalsSymbol].toClientJson().automaticSideEffects).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
(0, vitest.it)("preserves stable identity when deserializing with automatic side effects disabled", () => {
|
|
86
|
+
const json = {
|
|
87
|
+
baseUrl: baseOptions.baseUrl,
|
|
88
|
+
projectId: baseOptions.projectId,
|
|
89
|
+
publishableClientKey: baseOptions.publishableClientKey,
|
|
90
|
+
tokenStore: null,
|
|
91
|
+
redirectMethod: baseOptions.redirectMethod,
|
|
92
|
+
automaticSideEffects: false,
|
|
93
|
+
uniqueIdentifier: "00000000-0000-4000-8000-000000000001"
|
|
94
|
+
};
|
|
95
|
+
const first = ___interfaces_client_app_js.HexclaveClientApp[______common_js.hexclaveAppInternalsSymbol].fromClientJson(json);
|
|
96
|
+
(0, vitest.expect)(___interfaces_client_app_js.HexclaveClientApp[______common_js.hexclaveAppInternalsSymbol].fromClientJson(json)).toBe(first);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//#endregion
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=client-app-impl.automatic-side-effects.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-app-impl.automatic-side-effects.test.js","names":["HexclaveClientApp","hexclaveAppInternalsSymbol"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it } from \"vitest\";\nimport { hexclaveAppInternalsSymbol } from \"../../common\";\nimport { HexclaveClientApp, HexclaveClientAppConstructorOptions, HexclaveClientAppJson } from \"../interfaces/client-app\";\n\nconst baseOptions = {\n baseUrl: \"http://localhost:12345\",\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n} satisfies HexclaveClientAppConstructorOptions<true, string>;\n\ndescribe(\"HexclaveClientApp automatic side effects\", () => {\n it(\"does not inspect browser state when disabled\", () => {\n const previousWindow = Reflect.get(globalThis, \"window\");\n const previousDocument = Reflect.get(globalThis, \"document\");\n const hadPreviousWindow = Reflect.has(globalThis, \"window\");\n const hadPreviousDocument = Reflect.has(globalThis, \"document\");\n const browserGlobal = {};\n Object.defineProperty(browserGlobal, \"location\", {\n get() {\n throw new Error(\"Construction must not inspect the current URL when automatic side effects are disabled\");\n },\n });\n\n Reflect.set(globalThis, \"window\", browserGlobal);\n Object.defineProperty(globalThis, \"document\", {\n configurable: true,\n get() {\n throw new Error(\"Construction must not access the document when automatic side effects are disabled\");\n },\n });\n\n try {\n expect(() => new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n })).not.toThrow();\n } finally {\n if (hadPreviousWindow) {\n Reflect.set(globalThis, \"window\", previousWindow);\n } else {\n Reflect.deleteProperty(globalThis, \"window\");\n }\n if (hadPreviousDocument) {\n Object.defineProperty(globalThis, \"document\", {\n configurable: true,\n value: previousDocument,\n writable: true,\n });\n } else {\n Reflect.deleteProperty(globalThis, \"document\");\n }\n }\n });\n\n it(\"does not initialize automatic side effects when disabled\", () => {\n const methodName = \"_initializeAutomaticSideEffects\";\n const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);\n let initializationCalls = 0;\n Reflect.set(HexclaveClientApp.prototype, methodName, () => {\n initializationCalls += 1;\n });\n\n try {\n new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n });\n\n expect(initializationCalls).toBe(0);\n } finally {\n Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);\n }\n });\n\n it.each([undefined, true])(\"retains automatic initialization when automaticSideEffects is %s\", (automaticSideEffects) => {\n const methodName = \"_initializeAutomaticSideEffects\";\n const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);\n let initializationCalls = 0;\n Reflect.set(HexclaveClientApp.prototype, methodName, () => {\n initializationCalls += 1;\n });\n\n try {\n new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects,\n });\n\n expect(initializationCalls).toBe(1);\n } finally {\n Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);\n }\n });\n\n it(\"preserves the option through serialization\", () => {\n const app = new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n });\n\n expect(app[hexclaveAppInternalsSymbol].toClientJson().automaticSideEffects).toBe(false);\n });\n\n it(\"preserves stable identity when deserializing with automatic side effects disabled\", () => {\n const json: HexclaveClientAppJson<false, string> = {\n baseUrl: baseOptions.baseUrl,\n projectId: baseOptions.projectId,\n publishableClientKey: baseOptions.publishableClientKey,\n tokenStore: null,\n redirectMethod: baseOptions.redirectMethod,\n automaticSideEffects: false,\n uniqueIdentifier: \"00000000-0000-4000-8000-000000000001\",\n };\n\n const first = HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json);\n const second = HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json);\n\n expect(second).toBe(first);\n });\n});\n"],"mappings":"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"}
|