@stackframe/stack 2.8.1 → 2.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @stackframe/stack
2
2
 
3
+ ## 2.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Various changes
8
+ - Updated dependencies
9
+ - @stackframe/stack-shared@2.8.2
10
+ - @stackframe/stack-ui@2.8.2
11
+ - @stackframe/stack-sc@2.8.2
12
+
3
13
  ## 2.8.1
4
14
 
5
15
  ### Patch Changes
@@ -10,8 +10,8 @@ async function signInWithOAuth(iface, options) {
10
10
  const { codeChallenge, state } = await saveVerifierAndState();
11
11
  const location = await iface.getOAuthUrl({
12
12
  provider: options.provider,
13
- redirectUrl: constructRedirectUrl(options.redirectUrl),
14
- errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),
13
+ redirectUrl: constructRedirectUrl(options.redirectUrl, "redirectUrl"),
14
+ errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, "errorRedirectUrl"),
15
15
  codeChallenge,
16
16
  state,
17
17
  type: "authenticate",
@@ -24,9 +24,9 @@ async function addNewOAuthProviderOrScope(iface, options, session) {
24
24
  const { codeChallenge, state } = await saveVerifierAndState();
25
25
  const location = await iface.getOAuthUrl({
26
26
  provider: options.provider,
27
- redirectUrl: constructRedirectUrl(options.redirectUrl),
28
- errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),
29
- afterCallbackRedirectUrl: constructRedirectUrl(window.location.href),
27
+ redirectUrl: constructRedirectUrl(options.redirectUrl, "redirectUrl"),
28
+ errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, "errorRedirectUrl"),
29
+ afterCallbackRedirectUrl: constructRedirectUrl(window.location.href, "afterCallbackRedirectUrl"),
30
30
  codeChallenge,
31
31
  state,
32
32
  type: "link",
@@ -79,7 +79,7 @@ async function callOAuthCallback(iface, redirectUrl) {
79
79
  try {
80
80
  return Result.ok(await iface.callOAuthCallback({
81
81
  oauthParams: consumed.originalUrl.searchParams,
82
- redirectUri: constructRedirectUrl(redirectUrl),
82
+ redirectUri: constructRedirectUrl(redirectUrl, "redirectUri"),
83
83
  codeVerifier: consumed.codeVerifier,
84
84
  state: consumed.state
85
85
  }));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { KnownError, StackClientInterface } from \"@stackframe/stack-shared\";\nimport { InternalSession } from \"@stackframe/stack-shared/dist/sessions\";\nimport { StackAssertionError, throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { neverResolve } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { deindent } from \"@stackframe/stack-shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\n\nexport async function signInWithOAuth(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n }\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),\n codeChallenge,\n state,\n type: \"authenticate\",\n providerScope: options.providerScope,\n });\n window.location.assign(location);\n await neverResolve();\n}\n\nexport async function addNewOAuthProviderOrScope(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),\n afterCallbackRedirectUrl: constructRedirectUrl(window.location.href),\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n window.location.assign(location);\n await neverResolve();\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 */\nfunction consumeOAuthCallbackQueryParams() {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\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 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 Stack 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 Stack.\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 originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: StackClientInterface,\n redirectUrl: string,\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();\n if (!consumed) return Result.ok(undefined);\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),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (e instanceof KnownError) {\n throw e;\n }\n throw new StackAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":";AAIA,SAAS,kBAAwC;AAEjD,SAAS,qBAAqB,gBAAgB;AAC9C,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AACrC,SAAS,+BAA+B,4BAA4B;AAEpE,eAAsB,gBACpB,OACA,SAMA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,WAAW;AAAA,IACrD,kBAAkB,qBAAqB,QAAQ,gBAAgB;AAAA,IAC/D;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAEA,eAAsB,2BACpB,OACA,SAMA,SACA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,WAAW;AAAA,IACrD,kBAAkB,qBAAqB,QAAQ,gBAAgB;AAAA,IAC/D,0BAA0B,qBAAqB,OAAO,SAAS,IAAI;AAAA,IACnE;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAOA,SAAS,kCAAkC;AACzC,QAAM,iBAAiB,CAAC,QAAQ,OAAO;AACvC,QAAM,cAAc,IAAI,IAAI,OAAO,SAAS,IAAI;AAChD,aAAW,SAAS,gBAAgB;AAClC,QAAI,CAAC,YAAY,aAAa,IAAI,KAAK,GAAG;AACxC,cAAQ,KAAK,IAAI,MAAM,uDAAuD,KAAK,2EAA2E,CAAC;AAC/J,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,gBAAgB,YAAY,aAAa,IAAI,OAAO,KAAK,SAAS,uDAAuD;AAC/H,QAAM,eAAe,8BAA8B,aAAa;AAEhE,MAAI,CAAC,cAAc;AAGjB,YAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAWZ;AACD,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,IAAI,IAAI,WAAW;AAClC,aAAW,SAAS,gBAAgB;AAClC,WAAO,aAAa,OAAO,KAAK;AAAA,EAClC;AAQA,SAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,SAAS,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA,cAAc,aAAa;AAAA,IAC3B,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,OACA,aACA;AAIA,QAAM,WAAW,gCAAgC;AACjD,MAAI,CAAC,SAAU,QAAO,OAAO,GAAG,MAAS;AAKzC,MAAI;AACF,WAAO,OAAO,GAAG,MAAM,MAAM,kBAAkB;AAAA,MAC7C,aAAa,SAAS,YAAY;AAAA,MAClC,aAAa,qBAAqB,WAAW;AAAA,MAC7C,cAAc,SAAS;AAAA,MACvB,OAAO,SAAS;AAAA,IAClB,CAAC,CAAC;AAAA,EACJ,SAAS,GAAG;AACV,QAAI,aAAa,YAAY;AAC3B,YAAM;AAAA,IACR;AACA,UAAM,IAAI,oBAAoB,6DAA6D,EAAE,OAAO,EAAE,CAAC;AAAA,EACzG;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { KnownError, StackClientInterface } from \"@stackframe/stack-shared\";\nimport { InternalSession } from \"@stackframe/stack-shared/dist/sessions\";\nimport { StackAssertionError, throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { neverResolve } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { deindent } from \"@stackframe/stack-shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\n\nexport async function signInWithOAuth(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n }\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl, \"redirectUrl\"),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, \"errorRedirectUrl\"),\n codeChallenge,\n state,\n type: \"authenticate\",\n providerScope: options.providerScope,\n });\n window.location.assign(location);\n await neverResolve();\n}\n\nexport async function addNewOAuthProviderOrScope(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = 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 window.location.assign(location);\n await neverResolve();\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 */\nfunction consumeOAuthCallbackQueryParams() {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\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 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 Stack 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 Stack.\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 originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: StackClientInterface,\n redirectUrl: string,\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();\n if (!consumed) return Result.ok(undefined);\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 (e instanceof KnownError) {\n throw e;\n }\n throw new StackAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":";AAIA,SAAS,kBAAwC;AAEjD,SAAS,qBAAqB,gBAAgB;AAC9C,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AACrC,SAAS,+BAA+B,4BAA4B;AAEpE,eAAsB,gBACpB,OACA,SAMA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,aAAa,aAAa;AAAA,IACpE,kBAAkB,qBAAqB,QAAQ,kBAAkB,kBAAkB;AAAA,IACnF;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAEA,eAAsB,2BACpB,OACA,SAMA,SACA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,aAAa,aAAa;AAAA,IACpE,kBAAkB,qBAAqB,QAAQ,kBAAkB,kBAAkB;AAAA,IACnF,0BAA0B,qBAAqB,OAAO,SAAS,MAAM,0BAA0B;AAAA,IAC/F;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAOA,SAAS,kCAAkC;AACzC,QAAM,iBAAiB,CAAC,QAAQ,OAAO;AACvC,QAAM,cAAc,IAAI,IAAI,OAAO,SAAS,IAAI;AAChD,aAAW,SAAS,gBAAgB;AAClC,QAAI,CAAC,YAAY,aAAa,IAAI,KAAK,GAAG;AACxC,cAAQ,KAAK,IAAI,MAAM,uDAAuD,KAAK,2EAA2E,CAAC;AAC/J,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,gBAAgB,YAAY,aAAa,IAAI,OAAO,KAAK,SAAS,uDAAuD;AAC/H,QAAM,eAAe,8BAA8B,aAAa;AAEhE,MAAI,CAAC,cAAc;AAGjB,YAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAWZ;AACD,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,IAAI,IAAI,WAAW;AAClC,aAAW,SAAS,gBAAgB;AAClC,WAAO,aAAa,OAAO,KAAK;AAAA,EAClC;AAQA,SAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,SAAS,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA,cAAc,aAAa;AAAA,IAC3B,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,OACA,aACA;AAIA,QAAM,WAAW,gCAAgC;AACjD,MAAI,CAAC,SAAU,QAAO,OAAO,GAAG,MAAS;AAKzC,MAAI;AACF,WAAO,OAAO,GAAG,MAAM,MAAM,kBAAkB;AAAA,MAC7C,aAAa,SAAS,YAAY;AAAA,MAClC,aAAa,qBAAqB,aAAa,aAAa;AAAA,MAC5D,cAAc,SAAS;AAAA,MACvB,OAAO,SAAS;AAAA,IAClB,CAAC,CAAC;AAAA,EACJ,SAAS,GAAG;AACV,QAAI,aAAa,YAAY;AAC3B,YAAM;AAAA,IACR;AACA,UAAM,IAAI,oBAAoB,6DAA6D,EAAE,OAAO,EAAE,CAAC;AAAA,EACzG;AACF;","names":[]}
@@ -485,14 +485,11 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
485
485
  clientMetadata: crud.client_metadata,
486
486
  clientReadOnlyMetadata: crud.client_read_only_metadata,
487
487
  async inviteUser(options) {
488
- if (!options.callbackUrl && !await app._getCurrentUrl()) {
489
- throw new Error("Cannot invite user without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `inviteUser({ email, callbackUrl: ... })`");
490
- }
491
488
  await app._interface.sendTeamInvitation({
492
489
  teamId: crud.id,
493
490
  email: options.email,
494
491
  session,
495
- callbackUrl: options.callbackUrl ?? constructRedirectUrl(app.urls.teamInvitation)
492
+ callbackUrl: options.callbackUrl ?? constructRedirectUrl(app.urls.teamInvitation, "callbackUrl")
496
493
  });
497
494
  await app._teamInvitationsCache.refresh([session, crud.id]);
498
495
  },
@@ -531,8 +528,12 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
531
528
  isVerified: crud.is_verified,
532
529
  isPrimary: crud.is_primary,
533
530
  usedForAuth: crud.used_for_auth,
534
- async sendVerificationEmail() {
535
- await app._interface.sendCurrentUserContactChannelVerificationEmail(crud.id, constructRedirectUrl(app.urls.emailVerification), session);
531
+ async sendVerificationEmail(options) {
532
+ await app._interface.sendCurrentUserContactChannelVerificationEmail(
533
+ crud.id,
534
+ options?.callbackUrl || constructRedirectUrl(app.urls.emailVerification, "callbackUrl"),
535
+ session
536
+ );
536
537
  },
537
538
  async update(data) {
538
539
  await app._interface.updateClientContactChannel(crud.id, contactChannelUpdateOptionsToCrud(data), session);
@@ -634,6 +635,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
634
635
  oauthProviders: crud.oauth_providers,
635
636
  passkeyAuthEnabled: crud.passkey_auth_enabled,
636
637
  isMultiFactorRequired: crud.requires_totp_mfa,
638
+ isAnonymous: crud.is_anonymous,
637
639
  toClientJson() {
638
640
  return crud;
639
641
  }
@@ -760,10 +762,11 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
760
762
  if (!crud.primary_email) {
761
763
  throw new StackAssertionError("User does not have a primary email");
762
764
  }
763
- if (!options?.callbackUrl && !await app._getCurrentUrl()) {
764
- throw new Error("Cannot send verification email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendVerificationEmail({ callbackUrl: ... })`");
765
- }
766
- return await app._interface.sendVerificationEmail(crud.primary_email, options?.callbackUrl ?? constructRedirectUrl(app.urls.emailVerification), session);
765
+ return await app._interface.sendVerificationEmail(
766
+ crud.primary_email,
767
+ options?.callbackUrl ?? constructRedirectUrl(app.urls.emailVerification, "callbackUrl"),
768
+ session
769
+ );
767
770
  },
768
771
  async updatePassword(options) {
769
772
  const result = await app._interface.updatePassword(options, session);
@@ -983,16 +986,10 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
983
986
  return await this._redirectToHandler("teamInvitation", options);
984
987
  }
985
988
  async sendForgotPasswordEmail(email, options) {
986
- if (!options?.callbackUrl && !await this._getCurrentUrl()) {
987
- throw new Error("Cannot send forgot password email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendForgotPasswordEmail({ email, callbackUrl: ... })`");
988
- }
989
- return await this._interface.sendForgotPasswordEmail(email, options?.callbackUrl ?? constructRedirectUrl(this.urls.passwordReset));
989
+ return await this._interface.sendForgotPasswordEmail(email, options?.callbackUrl ?? constructRedirectUrl(this.urls.passwordReset, "callbackUrl"));
990
990
  }
991
991
  async sendMagicLinkEmail(email, options) {
992
- if (!options?.callbackUrl && !await this._getCurrentUrl()) {
993
- throw new Error("Cannot send magic link email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendMagicLinkEmail({ email, callbackUrl: ... })`");
994
- }
995
- return await this._interface.sendMagicLinkEmail(email, options?.callbackUrl ?? constructRedirectUrl(this.urls.magicLinkCallback));
992
+ return await this._interface.sendMagicLinkEmail(email, options?.callbackUrl ?? constructRedirectUrl(this.urls.magicLinkCallback, "callbackUrl"));
996
993
  }
997
994
  async resetPassword(options) {
998
995
  return await this._interface.resetPassword(options);
@@ -1179,7 +1176,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
1179
1176
  async signUpWithCredential(options) {
1180
1177
  this._ensurePersistentTokenStore();
1181
1178
  const session = await this._getSession();
1182
- const emailVerificationRedirectUrl = options.verificationCallbackUrl ?? constructRedirectUrl(this.urls.emailVerification);
1179
+ const emailVerificationRedirectUrl = options.verificationCallbackUrl ?? constructRedirectUrl(this.urls.emailVerification, "verificationCallbackUrl");
1183
1180
  const result = await this._interface.signUpWithCredential(
1184
1181
  options.email,
1185
1182
  options.password,