@stackframe/stack 2.4.17 → 2.4.20

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.
Files changed (86) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/components/credential-sign-in.js +1 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.js +1 -1
  5. package/dist/components/credential-sign-up.js.map +1 -1
  6. package/dist/components/forgot-password.js +1 -1
  7. package/dist/components/forgot-password.js.map +1 -1
  8. package/dist/components/magic-link-sign-in.js +1 -1
  9. package/dist/components/magic-link-sign-in.js.map +1 -1
  10. package/dist/components/maybe-full-page.js +1 -1
  11. package/dist/components/maybe-full-page.js.map +1 -1
  12. package/dist/components/password-reset-inner.js +1 -1
  13. package/dist/components/password-reset-inner.js.map +1 -1
  14. package/dist/components/user-avatar.d.mts +1 -0
  15. package/dist/components/user-avatar.d.ts +1 -0
  16. package/dist/components/user-avatar.js +1 -1
  17. package/dist/components/user-avatar.js.map +1 -1
  18. package/dist/components/user-button.js +4 -4
  19. package/dist/components/user-button.js.map +1 -1
  20. package/dist/components-core/button.js.map +1 -1
  21. package/dist/components-core/index.d.mts +1 -1
  22. package/dist/components-core/index.d.ts +1 -1
  23. package/dist/components-core-joy/button.js +1 -1
  24. package/dist/components-core-joy/button.js.map +1 -1
  25. package/dist/components-page/account-settings.js +1 -1
  26. package/dist/components-page/account-settings.js.map +1 -1
  27. package/dist/components-page/stack-handler.d.mts +1 -0
  28. package/dist/components-page/stack-handler.d.ts +1 -0
  29. package/dist/esm/components/credential-sign-in.js +2 -2
  30. package/dist/esm/components/credential-sign-in.js.map +1 -1
  31. package/dist/esm/components/credential-sign-up.js +2 -2
  32. package/dist/esm/components/credential-sign-up.js.map +1 -1
  33. package/dist/esm/components/forgot-password.js +2 -2
  34. package/dist/esm/components/forgot-password.js.map +1 -1
  35. package/dist/esm/components/magic-link-sign-in.js +2 -2
  36. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  37. package/dist/esm/components/maybe-full-page.js +1 -1
  38. package/dist/esm/components/maybe-full-page.js.map +1 -1
  39. package/dist/esm/components/password-reset-inner.js +2 -2
  40. package/dist/esm/components/password-reset-inner.js.map +1 -1
  41. package/dist/esm/components/user-avatar.js +1 -1
  42. package/dist/esm/components/user-avatar.js.map +1 -1
  43. package/dist/esm/components/user-button.js +5 -5
  44. package/dist/esm/components/user-button.js.map +1 -1
  45. package/dist/esm/components-core/button.js.map +1 -1
  46. package/dist/esm/components-core-joy/button.js +1 -1
  47. package/dist/esm/components-core-joy/button.js.map +1 -1
  48. package/dist/esm/components-page/account-settings.js +1 -1
  49. package/dist/esm/components-page/account-settings.js.map +1 -1
  50. package/dist/esm/lib/auth.js +2 -3
  51. package/dist/esm/lib/auth.js.map +1 -1
  52. package/dist/esm/lib/stack-app.js +305 -192
  53. package/dist/esm/lib/stack-app.js.map +1 -1
  54. package/dist/esm/providers/stack-provider-client.js +2 -1
  55. package/dist/esm/providers/stack-provider-client.js.map +1 -1
  56. package/dist/esm/providers/styled-components-registry.js +2 -1
  57. package/dist/esm/providers/styled-components-registry.js.map +1 -1
  58. package/dist/index.d.mts +1 -0
  59. package/dist/index.d.ts +1 -0
  60. package/dist/lib/auth.d.mts +5 -3
  61. package/dist/lib/auth.d.ts +5 -3
  62. package/dist/lib/auth.js +2 -3
  63. package/dist/lib/auth.js.map +1 -1
  64. package/dist/lib/hooks.d.mts +1 -0
  65. package/dist/lib/hooks.d.ts +1 -0
  66. package/dist/lib/stack-app.d.mts +98 -18
  67. package/dist/lib/stack-app.d.ts +98 -18
  68. package/dist/lib/stack-app.js +303 -190
  69. package/dist/lib/stack-app.js.map +1 -1
  70. package/dist/providers/component-provider.d.mts +2 -2
  71. package/dist/providers/component-provider.d.ts +2 -2
  72. package/dist/providers/stack-provider-client.d.mts +1 -0
  73. package/dist/providers/stack-provider-client.d.ts +1 -0
  74. package/dist/providers/stack-provider-client.js +2 -1
  75. package/dist/providers/stack-provider-client.js.map +1 -1
  76. package/dist/providers/stack-provider.d.mts +1 -0
  77. package/dist/providers/stack-provider.d.ts +1 -0
  78. package/dist/providers/styled-components-registry.js +2 -1
  79. package/dist/providers/styled-components-registry.js.map +1 -1
  80. package/package.json +3 -3
  81. package/dist/esm/utils/next.js +0 -8
  82. package/dist/esm/utils/next.js.map +0 -1
  83. package/dist/utils/next.d.mts +0 -3
  84. package/dist/utils/next.d.ts +0 -3
  85. package/dist/utils/next.js +0 -33
  86. package/dist/utils/next.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/styled-components-registry.tsx"],"sourcesContent":["'use client';\n \nimport React, { useState } from 'react';\nimport { useServerInsertedHTML } from 'next/navigation';\nimport { ServerStyleSheet, StyleSheetManager } from 'styled-components';\n \nexport default function StyledComponentsRegistry({\n children,\n}: {\n children: React.ReactNode,\n}) {\n // Only create stylesheet once with lazy initial state\n // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state\n const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());\n \n useServerInsertedHTML(() => {\n const styles = styledComponentsStyleSheet.getStyleElement();\n styledComponentsStyleSheet.instance.clearTag();\n return <>{styles}</>;\n });\n \n if (typeof window !== 'undefined') return <>{children}</>;\n \n return (\n <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>\n {children}\n </StyleSheetManager>\n );\n}"],"mappings":";;;AAEA,SAAgB,gBAAgB;AAChC,SAAS,6BAA6B;AACtC,SAAS,kBAAkB,yBAAyB;AAczC;AAZI,SAAR,yBAA0C;AAAA,EAC/C;AACF,GAEG;AAGD,QAAM,CAAC,0BAA0B,IAAI,SAAS,MAAM,IAAI,iBAAiB,CAAC;AAE1E,wBAAsB,MAAM;AAC1B,UAAM,SAAS,2BAA2B,gBAAgB;AAC1D,+BAA2B,SAAS,SAAS;AAC7C,WAAO,gCAAG,kBAAO;AAAA,EACnB,CAAC;AAED,MAAI,OAAO,WAAW;AAAa,WAAO,gCAAG,UAAS;AAEtD,SACE,oBAAC,qBAAkB,OAAO,2BAA2B,UAClD,UACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/providers/styled-components-registry.tsx"],"sourcesContent":["'use client';\n \nimport React, { useState } from 'react';\nimport { useServerInsertedHTML } from 'next/navigation';\nimport { ServerStyleSheet, StyleSheetManager } from 'styled-components';\nimport { isBrowserLike } from '@stackframe/stack-shared/src/utils/env';\n \nexport default function StyledComponentsRegistry({\n children,\n}: {\n children: React.ReactNode,\n}) {\n // Only create stylesheet once with lazy initial state\n // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state\n const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());\n \n useServerInsertedHTML(() => {\n const styles = styledComponentsStyleSheet.getStyleElement();\n styledComponentsStyleSheet.instance.clearTag();\n return <>{styles}</>;\n });\n \n if (isBrowserLike()) return <>{children}</>;\n \n return (\n <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>\n {children}\n </StyleSheetManager>\n );\n}\n"],"mappings":";;;AAEA,SAAgB,gBAAgB;AAChC,SAAS,6BAA6B;AACtC,SAAS,kBAAkB,yBAAyB;AACpD,SAAS,qBAAqB;AAcnB;AAZI,SAAR,yBAA0C;AAAA,EAC/C;AACF,GAEG;AAGD,QAAM,CAAC,0BAA0B,IAAI,SAAS,MAAM,IAAI,iBAAiB,CAAC;AAE1E,wBAAsB,MAAM;AAC1B,UAAM,SAAS,2BAA2B,gBAAgB;AAC1D,+BAA2B,SAAS,SAAS;AAC7C,WAAO,gCAAG,kBAAO;AAAA,EACnB,CAAC;AAED,MAAI,cAAc;AAAG,WAAO,gCAAG,UAAS;AAExC,SACE,oBAAC,qBAAkB,OAAO,2BAA2B,UAClD,UACH;AAEJ;","names":[]}
package/dist/index.d.mts CHANGED
@@ -28,6 +28,7 @@ import '@stackframe/stack-shared/dist/utils/json';
28
28
  import '@stackframe/stack-shared/dist/interface/adminInterface';
29
29
  import '@stackframe/stack-shared/dist/interface/serverInterface';
30
30
  import '@stackframe/stack-shared/dist/interface/crud/email-templates';
31
+ import '@stackframe/stack-shared/dist/sessions';
31
32
  import '@radix-ui/react-tabs';
32
33
  import '@radix-ui/react-collapsible';
33
34
  import '@radix-ui/react-avatar';
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ import '@stackframe/stack-shared/dist/utils/json';
28
28
  import '@stackframe/stack-shared/dist/interface/adminInterface';
29
29
  import '@stackframe/stack-shared/dist/interface/serverInterface';
30
30
  import '@stackframe/stack-shared/dist/interface/crud/email-templates';
31
+ import '@stackframe/stack-shared/dist/sessions';
31
32
  import '@radix-ui/react-tabs';
32
33
  import '@radix-ui/react-collapsible';
33
34
  import '@radix-ui/react-avatar';
@@ -1,11 +1,13 @@
1
- import * as oauth4webapi from 'oauth4webapi';
2
1
  import { StackClientInterface } from '@stackframe/stack-shared';
3
- import { TokenStore } from '@stackframe/stack-shared/dist/interface/clientInterface';
4
2
 
5
3
  declare function signInWithOAuth(iface: StackClientInterface, { provider, redirectUrl, }: {
6
4
  provider: string;
7
5
  redirectUrl?: string;
8
6
  }): Promise<void>;
9
- declare function callOAuthCallback(iface: StackClientInterface, tokenStore: TokenStore, redirectUrl: string): Promise<oauth4webapi.OAuth2TokenEndpointResponse | null>;
7
+ declare function callOAuthCallback(iface: StackClientInterface, redirectUrl: string): Promise<{
8
+ newUser: boolean;
9
+ accessToken: string;
10
+ refreshToken: string;
11
+ } | null>;
10
12
 
11
13
  export { callOAuthCallback, signInWithOAuth };
@@ -1,11 +1,13 @@
1
- import * as oauth4webapi from 'oauth4webapi';
2
1
  import { StackClientInterface } from '@stackframe/stack-shared';
3
- import { TokenStore } from '@stackframe/stack-shared/dist/interface/clientInterface';
4
2
 
5
3
  declare function signInWithOAuth(iface: StackClientInterface, { provider, redirectUrl, }: {
6
4
  provider: string;
7
5
  redirectUrl?: string;
8
6
  }): Promise<void>;
9
- declare function callOAuthCallback(iface: StackClientInterface, tokenStore: TokenStore, redirectUrl: string): Promise<oauth4webapi.OAuth2TokenEndpointResponse | null>;
7
+ declare function callOAuthCallback(iface: StackClientInterface, redirectUrl: string): Promise<{
8
+ newUser: boolean;
9
+ accessToken: string;
10
+ refreshToken: string;
11
+ } | null>;
10
12
 
11
13
  export { callOAuthCallback, signInWithOAuth };
package/dist/lib/auth.js CHANGED
@@ -61,7 +61,7 @@ function consumeOAuthCallbackQueryParams(expectedState) {
61
61
  window.history.replaceState({}, "", newUrl.toString());
62
62
  return originalUrl;
63
63
  }
64
- async function callOAuthCallback(iface, tokenStore, redirectUrl) {
64
+ async function callOAuthCallback(iface, redirectUrl) {
65
65
  const { codeVerifier, state } = (0, import_cookie.getVerifierAndState)();
66
66
  if (!codeVerifier || !state) {
67
67
  throw new Error("Invalid OAuth callback URL parameters. It seems like the OAuth flow was interrupted, so please try again.");
@@ -74,8 +74,7 @@ async function callOAuthCallback(iface, tokenStore, redirectUrl) {
74
74
  originalUrl.searchParams,
75
75
  (0, import_url.constructRedirectUrl)(redirectUrl),
76
76
  codeVerifier,
77
- state,
78
- tokenStore
77
+ state
79
78
  );
80
79
  } catch (e) {
81
80
  throw new import_errors.StackAssertionError("Error signing in during OAuth callback. Please try again.", { cause: e });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/auth.ts"],"sourcesContent":["import { StackClientInterface } from \"@stackframe/stack-shared\";\nimport { saveVerifierAndState, getVerifierAndState } from \"./cookie\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { TokenStore } from \"@stackframe/stack-shared/dist/interface/clientInterface\";\nimport { neverResolve, wait } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\n\nexport async function signInWithOAuth(\n iface: StackClientInterface,\n {\n provider,\n redirectUrl,\n } : { \n provider: string,\n redirectUrl?: string,\n }\n) {\n redirectUrl = constructRedirectUrl(redirectUrl);\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl(\n provider,\n redirectUrl,\n codeChallenge,\n state,\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(expectedState: string): null | URL {\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 return null;\n }\n }\n\n if (expectedState !== originalUrl.searchParams.get(\"state\")) {\n // If the state doesn't match, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\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 originalUrl; \n}\n\nexport async function callOAuthCallback(\n iface: StackClientInterface,\n tokenStore: TokenStore,\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 { codeVerifier, state } = getVerifierAndState();\n if (!codeVerifier || !state) {\n throw new Error(\"Invalid OAuth callback URL parameters. It seems like the OAuth flow was interrupted, so please try again.\");\n }\n const originalUrl = consumeOAuthCallbackQueryParams(state);\n if (!originalUrl) return null;\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback)\n try {\n return await iface.callOAuthCallback(\n originalUrl.searchParams,\n constructRedirectUrl(redirectUrl),\n codeVerifier,\n state,\n tokenStore,\n );\n } catch (e) {\n throw new StackAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA0D;AAC1D,iBAAqC;AAErC,sBAAmC;AACnC,oBAAoC;AAEpC,eAAsB,gBACpB,OACA;AAAA,EACE;AAAA,EACA;AACF,GAIA;AACA,oBAAc,iCAAqB,WAAW;AAC9C,QAAM,EAAE,eAAe,MAAM,IAAI,UAAM,oCAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,SAAS,OAAO,QAAQ;AAC/B,YAAM,8BAAa;AACrB;AAOA,SAAS,gCAAgC,eAAmC;AAC1E,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,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,kBAAkB,YAAY,aAAa,IAAI,OAAO,GAAG;AAG3D,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;AACT;AAEA,eAAsB,kBACpB,OACA,YACA,aACA;AAIA,QAAM,EAAE,cAAc,MAAM,QAAI,mCAAoB;AACpD,MAAI,CAAC,gBAAgB,CAAC,OAAO;AAC3B,UAAM,IAAI,MAAM,2GAA2G;AAAA,EAC7H;AACA,QAAM,cAAc,gCAAgC,KAAK;AACzD,MAAI,CAAC;AAAa,WAAO;AAIzB,MAAI;AACF,WAAO,MAAM,MAAM;AAAA,MACjB,YAAY;AAAA,UACZ,iCAAqB,WAAW;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,UAAM,IAAI,kCAAoB,6DAA6D,EAAE,OAAO,EAAE,CAAC;AAAA,EACzG;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/auth.ts"],"sourcesContent":["import { StackClientInterface } from \"@stackframe/stack-shared\";\nimport { saveVerifierAndState, getVerifierAndState } from \"./cookie\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { neverResolve, wait } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\n\nexport async function signInWithOAuth(\n iface: StackClientInterface,\n {\n provider,\n redirectUrl,\n } : { \n provider: string,\n redirectUrl?: string,\n }\n) {\n redirectUrl = constructRedirectUrl(redirectUrl);\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl(\n provider,\n redirectUrl,\n codeChallenge,\n state,\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(expectedState: string): null | URL {\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 return null;\n }\n }\n\n if (expectedState !== originalUrl.searchParams.get(\"state\")) {\n // If the state doesn't match, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\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 originalUrl; \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 { codeVerifier, state } = getVerifierAndState();\n if (!codeVerifier || !state) {\n throw new Error(\"Invalid OAuth callback URL parameters. It seems like the OAuth flow was interrupted, so please try again.\");\n }\n const originalUrl = consumeOAuthCallbackQueryParams(state);\n if (!originalUrl) return null;\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback)\n try {\n return await iface.callOAuthCallback(\n originalUrl.searchParams,\n constructRedirectUrl(redirectUrl),\n codeVerifier,\n state,\n );\n } catch (e) {\n throw new StackAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA0D;AAC1D,iBAAqC;AACrC,sBAAmC;AACnC,oBAAoC;AAEpC,eAAsB,gBACpB,OACA;AAAA,EACE;AAAA,EACA;AACF,GAIA;AACA,oBAAc,iCAAqB,WAAW;AAC9C,QAAM,EAAE,eAAe,MAAM,IAAI,UAAM,oCAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,SAAS,OAAO,QAAQ;AAC/B,YAAM,8BAAa;AACrB;AAOA,SAAS,gCAAgC,eAAmC;AAC1E,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,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,kBAAkB,YAAY,aAAa,IAAI,OAAO,GAAG;AAG3D,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;AACT;AAEA,eAAsB,kBACpB,OACA,aACA;AAIA,QAAM,EAAE,cAAc,MAAM,QAAI,mCAAoB;AACpD,MAAI,CAAC,gBAAgB,CAAC,OAAO;AAC3B,UAAM,IAAI,MAAM,2GAA2G;AAAA,EAC7H;AACA,QAAM,cAAc,gCAAgC,KAAK;AACzD,MAAI,CAAC;AAAa,WAAO;AAIzB,MAAI;AACF,WAAO,MAAM,MAAM;AAAA,MACjB,YAAY;AAAA,UACZ,iCAAqB,WAAW;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,UAAM,IAAI,kCAAoB,6DAA6D,EAAE,OAAO,EAAE,CAAC;AAAA,EACzG;AACF;","names":[]}
@@ -5,6 +5,7 @@ import '@stackframe/stack-shared/dist/utils/json';
5
5
  import '@stackframe/stack-shared/dist/interface/adminInterface';
6
6
  import '@stackframe/stack-shared/dist/interface/serverInterface';
7
7
  import '@stackframe/stack-shared/dist/interface/crud/email-templates';
8
+ import '@stackframe/stack-shared/dist/sessions';
8
9
 
9
10
  /**
10
11
  * Returns the current user object. Equivalent to `useStackApp().useUser()`.
@@ -5,6 +5,7 @@ import '@stackframe/stack-shared/dist/utils/json';
5
5
  import '@stackframe/stack-shared/dist/interface/adminInterface';
6
6
  import '@stackframe/stack-shared/dist/interface/serverInterface';
7
7
  import '@stackframe/stack-shared/dist/interface/crud/email-templates';
8
+ import '@stackframe/stack-shared/dist/sessions';
8
9
 
9
10
  /**
10
11
  * Returns the current user object. Equivalent to `useStackApp().useUser()`.
@@ -1,11 +1,20 @@
1
1
  import { ServerUserJson, OAuthProviderConfigJson, KnownErrors } from '@stackframe/stack-shared';
2
- import { TokenStore, UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
2
+ import { UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
3
3
  import { ReadonlyJson } from '@stackframe/stack-shared/dist/utils/json';
4
4
  import { ProjectUpdateOptions, ApiKeySetCreateOptions } from '@stackframe/stack-shared/dist/interface/adminInterface';
5
5
  import { ServerUserUpdateJson, ServerTeamCustomizableJson, ServerPermissionDefinitionCustomizableJson, ServerPermissionDefinitionJson, EmailTemplateType } from '@stackframe/stack-shared/dist/interface/serverInterface';
6
6
  import { ListEmailTemplatesCrud, EmailTemplateCrud } from '@stackframe/stack-shared/dist/interface/crud/email-templates';
7
+ import { InternalSession } from '@stackframe/stack-shared/dist/sessions';
7
8
 
8
- type TokenStoreInit<HasTokenStore extends boolean = boolean> = HasTokenStore extends true ? ("cookie" | "nextjs-cookie" | "memory" | Request) : HasTokenStore extends false ? null : TokenStoreInit<true> | TokenStoreInit<false>;
9
+ type RequestLike = {
10
+ headers: {
11
+ get: (name: string) => string | null;
12
+ };
13
+ };
14
+ type TokenStoreInit<HasTokenStore extends boolean = boolean> = HasTokenStore extends true ? ("cookie" | "nextjs-cookie" | "memory" | RequestLike | {
15
+ accessToken: string;
16
+ refreshToken: string;
17
+ }) : HasTokenStore extends false ? null : TokenStoreInit<true> | TokenStoreInit<false>;
9
18
  type HandlerUrls = {
10
19
  handler: string;
11
20
  signIn: string;
@@ -36,8 +45,7 @@ type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId e
36
45
  type StackAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = ((StackServerAppConstructorOptions<HasTokenStore, ProjectId> & {
37
46
  superSecretAdminKey?: string;
38
47
  }) | (Omit<StackServerAppConstructorOptions<HasTokenStore, ProjectId>, "publishableClientKey" | "secretServerKey"> & {
39
- projectOwnerTokens: TokenStore;
40
- refreshProjectOwnerTokens: () => Promise<void>;
48
+ projectOwnerSession: InternalSession;
41
49
  }));
42
50
  type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {
43
51
  uniqueIdentifier: string;
@@ -46,17 +54,26 @@ declare const stackAppInternalsSymbol: unique symbol;
46
54
  type RedirectToOptions = {
47
55
  replace?: boolean;
48
56
  };
57
+ type Session = {
58
+ getTokens(): Promise<{
59
+ accessToken: string | null;
60
+ refreshToken: string | null;
61
+ }>;
62
+ };
63
+ /**
64
+ * Contains everything related to the current user session.
65
+ */
49
66
  type Auth<T, C> = {
50
- readonly tokenStore: TokenStore;
51
- refreshAccessToken(this: T): Promise<void>;
52
- updateSelectedTeam(this: T, team: Team | null): Promise<void>;
53
- update(this: T, user: C): Promise<void>;
67
+ readonly _internalSession: InternalSession;
68
+ readonly currentSession: Session;
54
69
  signOut(this: T): Promise<void>;
55
- sendVerificationEmail(this: T): Promise<KnownErrors["EmailAlreadyVerified"] | undefined>;
70
+ update(this: T, user: C): Promise<void>;
71
+ updateSelectedTeam(this: T, team: Team | null): Promise<void>;
72
+ sendVerificationEmail(this: T): Promise<KnownErrors["EmailAlreadyVerified"] | void>;
56
73
  updatePassword(this: T, options: {
57
74
  oldPassword: string;
58
75
  newPassword: string;
59
- }): Promise<KnownErrors["PasswordMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
76
+ }): Promise<KnownErrors["PasswordMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | void>;
60
77
  };
61
78
  type InternalAuth<T> = {
62
79
  createProject(this: T, newProject: ProjectUpdateOptions & {
@@ -230,21 +247,84 @@ type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends s
230
247
  signInWithCredential(options: {
231
248
  email: string;
232
249
  password: string;
233
- }): Promise<KnownErrors["EmailPasswordMismatch"] | undefined>;
250
+ }): Promise<KnownErrors["EmailPasswordMismatch"] | void>;
234
251
  signUpWithCredential(options: {
235
252
  email: string;
236
253
  password: string;
237
- }): Promise<KnownErrors["UserEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
254
+ }): Promise<KnownErrors["UserEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"] | void>;
238
255
  callOAuthCallback(): Promise<boolean>;
239
- sendForgotPasswordEmail(email: string): Promise<KnownErrors["UserNotFound"] | undefined>;
240
- sendMagicLinkEmail(email: string): Promise<KnownErrors["RedirectUrlNotWhitelisted"] | undefined>;
256
+ sendForgotPasswordEmail(email: string): Promise<KnownErrors["UserNotFound"] | void>;
257
+ sendMagicLinkEmail(email: string): Promise<KnownErrors["RedirectUrlNotWhitelisted"] | void>;
241
258
  resetPassword(options: {
242
259
  code: string;
243
260
  password: string;
244
- }): Promise<KnownErrors["PasswordResetError"] | undefined>;
245
- verifyPasswordResetCode(code: string): Promise<KnownErrors["PasswordResetCodeError"] | undefined>;
246
- verifyEmail(code: string): Promise<KnownErrors["EmailVerificationError"] | undefined>;
247
- signInWithMagicLink(code: string): Promise<KnownErrors["MagicLinkError"] | undefined>;
261
+ }): Promise<KnownErrors["PasswordResetError"] | void>;
262
+ verifyPasswordResetCode(code: string): Promise<KnownErrors["PasswordResetCodeError"] | void>;
263
+ verifyEmail(code: string): Promise<KnownErrors["EmailVerificationError"] | void>;
264
+ signInWithMagicLink(code: string): Promise<KnownErrors["MagicLinkError"] | void>;
265
+ /**
266
+ * With most browsers now disabling third-party cookies by default, the best way to send authenticated requests
267
+ * across different origins is to pass the tokens in a header.
268
+ *
269
+ * This function returns a header object that can be used with `fetch` or other HTTP request libraries to send
270
+ * authenticated requests.
271
+ *
272
+ * On the server, you can then pass in the `Request` object to the `tokenStore` option
273
+ * on your Stack app to fetch user details. Please note that CORS by default does not allow custom headers, so you
274
+ * must set the [`Access-Control-Allow-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)
275
+ * to include `x-stack-auth` in the CORS preflight response.
276
+ *
277
+ * Example:
278
+ *
279
+ * ```ts
280
+ * // client
281
+ * const res = await fetch("https://api.example.com", {
282
+ * headers: {
283
+ * ...await stackApp.getCrossOriginHeaders()
284
+ * // you can also add your own headers here
285
+ * },
286
+ * });
287
+ *
288
+ * // server
289
+ * function handleRequest(req: Request) {
290
+ * const user = await stackServerApp.getUser({ tokenStore: req });
291
+ * return new Response("Welcome, " + user.displayName);
292
+ * }
293
+ * ```
294
+ */
295
+ getCrossOriginHeaders(): Promise<{
296
+ "x-stack-auth": string;
297
+ }>;
298
+ /**
299
+ * With most browsers now disabling third-party cookies by default, there need to be new ways to send authenticated
300
+ * requests across different origins. While `getCrossOriginHeaders` is the recommended way to do this, there
301
+ * are some cases where you might want to send the tokens differently, for example when you are using WebSockets
302
+ * or non-HTTP protocols.
303
+ *
304
+ * This function returns a token object that can be JSON-serialized and sent to the server in any way you like.
305
+ * There, you can use the `tokenStore` option on your Stack app to fetch user details.
306
+ *
307
+ * Example:
308
+ *
309
+ * ```ts
310
+ * // client
311
+ * const res = await rpcCall(rpcEndpoint, {
312
+ * data: {
313
+ * auth: await stackApp.getCrossOriginTokenObject(),
314
+ * },
315
+ * });
316
+ *
317
+ * // server
318
+ * function handleRequest(data) {
319
+ * const user = await stackServerApp.getUser({ tokenStore: data.auth });
320
+ * return new Response("Welcome, " + user.displayName);
321
+ * }
322
+ * ```
323
+ */
324
+ getCrossOriginTokenObject(): Promise<{
325
+ accessToken: string | null;
326
+ refreshToken: string | null;
327
+ }>;
248
328
  [stackAppInternalsSymbol]: {
249
329
  toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>;
250
330
  setCurrentUser(userJsonPromise: Promise<UserJson | null>): void;
@@ -1,11 +1,20 @@
1
1
  import { ServerUserJson, OAuthProviderConfigJson, KnownErrors } from '@stackframe/stack-shared';
2
- import { TokenStore, UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
2
+ import { UserJson, UserUpdateJson, ProjectJson, ProductionModeError, TeamJson, EmailConfigJson, DomainConfigJson, ClientProjectJson } from '@stackframe/stack-shared/dist/interface/clientInterface';
3
3
  import { ReadonlyJson } from '@stackframe/stack-shared/dist/utils/json';
4
4
  import { ProjectUpdateOptions, ApiKeySetCreateOptions } from '@stackframe/stack-shared/dist/interface/adminInterface';
5
5
  import { ServerUserUpdateJson, ServerTeamCustomizableJson, ServerPermissionDefinitionCustomizableJson, ServerPermissionDefinitionJson, EmailTemplateType } from '@stackframe/stack-shared/dist/interface/serverInterface';
6
6
  import { ListEmailTemplatesCrud, EmailTemplateCrud } from '@stackframe/stack-shared/dist/interface/crud/email-templates';
7
+ import { InternalSession } from '@stackframe/stack-shared/dist/sessions';
7
8
 
8
- type TokenStoreInit<HasTokenStore extends boolean = boolean> = HasTokenStore extends true ? ("cookie" | "nextjs-cookie" | "memory" | Request) : HasTokenStore extends false ? null : TokenStoreInit<true> | TokenStoreInit<false>;
9
+ type RequestLike = {
10
+ headers: {
11
+ get: (name: string) => string | null;
12
+ };
13
+ };
14
+ type TokenStoreInit<HasTokenStore extends boolean = boolean> = HasTokenStore extends true ? ("cookie" | "nextjs-cookie" | "memory" | RequestLike | {
15
+ accessToken: string;
16
+ refreshToken: string;
17
+ }) : HasTokenStore extends false ? null : TokenStoreInit<true> | TokenStoreInit<false>;
9
18
  type HandlerUrls = {
10
19
  handler: string;
11
20
  signIn: string;
@@ -36,8 +45,7 @@ type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId e
36
45
  type StackAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = ((StackServerAppConstructorOptions<HasTokenStore, ProjectId> & {
37
46
  superSecretAdminKey?: string;
38
47
  }) | (Omit<StackServerAppConstructorOptions<HasTokenStore, ProjectId>, "publishableClientKey" | "secretServerKey"> & {
39
- projectOwnerTokens: TokenStore;
40
- refreshProjectOwnerTokens: () => Promise<void>;
48
+ projectOwnerSession: InternalSession;
41
49
  }));
42
50
  type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {
43
51
  uniqueIdentifier: string;
@@ -46,17 +54,26 @@ declare const stackAppInternalsSymbol: unique symbol;
46
54
  type RedirectToOptions = {
47
55
  replace?: boolean;
48
56
  };
57
+ type Session = {
58
+ getTokens(): Promise<{
59
+ accessToken: string | null;
60
+ refreshToken: string | null;
61
+ }>;
62
+ };
63
+ /**
64
+ * Contains everything related to the current user session.
65
+ */
49
66
  type Auth<T, C> = {
50
- readonly tokenStore: TokenStore;
51
- refreshAccessToken(this: T): Promise<void>;
52
- updateSelectedTeam(this: T, team: Team | null): Promise<void>;
53
- update(this: T, user: C): Promise<void>;
67
+ readonly _internalSession: InternalSession;
68
+ readonly currentSession: Session;
54
69
  signOut(this: T): Promise<void>;
55
- sendVerificationEmail(this: T): Promise<KnownErrors["EmailAlreadyVerified"] | undefined>;
70
+ update(this: T, user: C): Promise<void>;
71
+ updateSelectedTeam(this: T, team: Team | null): Promise<void>;
72
+ sendVerificationEmail(this: T): Promise<KnownErrors["EmailAlreadyVerified"] | void>;
56
73
  updatePassword(this: T, options: {
57
74
  oldPassword: string;
58
75
  newPassword: string;
59
- }): Promise<KnownErrors["PasswordMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
76
+ }): Promise<KnownErrors["PasswordMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | void>;
60
77
  };
61
78
  type InternalAuth<T> = {
62
79
  createProject(this: T, newProject: ProjectUpdateOptions & {
@@ -230,21 +247,84 @@ type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends s
230
247
  signInWithCredential(options: {
231
248
  email: string;
232
249
  password: string;
233
- }): Promise<KnownErrors["EmailPasswordMismatch"] | undefined>;
250
+ }): Promise<KnownErrors["EmailPasswordMismatch"] | void>;
234
251
  signUpWithCredential(options: {
235
252
  email: string;
236
253
  password: string;
237
- }): Promise<KnownErrors["UserEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
254
+ }): Promise<KnownErrors["UserEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"] | void>;
238
255
  callOAuthCallback(): Promise<boolean>;
239
- sendForgotPasswordEmail(email: string): Promise<KnownErrors["UserNotFound"] | undefined>;
240
- sendMagicLinkEmail(email: string): Promise<KnownErrors["RedirectUrlNotWhitelisted"] | undefined>;
256
+ sendForgotPasswordEmail(email: string): Promise<KnownErrors["UserNotFound"] | void>;
257
+ sendMagicLinkEmail(email: string): Promise<KnownErrors["RedirectUrlNotWhitelisted"] | void>;
241
258
  resetPassword(options: {
242
259
  code: string;
243
260
  password: string;
244
- }): Promise<KnownErrors["PasswordResetError"] | undefined>;
245
- verifyPasswordResetCode(code: string): Promise<KnownErrors["PasswordResetCodeError"] | undefined>;
246
- verifyEmail(code: string): Promise<KnownErrors["EmailVerificationError"] | undefined>;
247
- signInWithMagicLink(code: string): Promise<KnownErrors["MagicLinkError"] | undefined>;
261
+ }): Promise<KnownErrors["PasswordResetError"] | void>;
262
+ verifyPasswordResetCode(code: string): Promise<KnownErrors["PasswordResetCodeError"] | void>;
263
+ verifyEmail(code: string): Promise<KnownErrors["EmailVerificationError"] | void>;
264
+ signInWithMagicLink(code: string): Promise<KnownErrors["MagicLinkError"] | void>;
265
+ /**
266
+ * With most browsers now disabling third-party cookies by default, the best way to send authenticated requests
267
+ * across different origins is to pass the tokens in a header.
268
+ *
269
+ * This function returns a header object that can be used with `fetch` or other HTTP request libraries to send
270
+ * authenticated requests.
271
+ *
272
+ * On the server, you can then pass in the `Request` object to the `tokenStore` option
273
+ * on your Stack app to fetch user details. Please note that CORS by default does not allow custom headers, so you
274
+ * must set the [`Access-Control-Allow-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)
275
+ * to include `x-stack-auth` in the CORS preflight response.
276
+ *
277
+ * Example:
278
+ *
279
+ * ```ts
280
+ * // client
281
+ * const res = await fetch("https://api.example.com", {
282
+ * headers: {
283
+ * ...await stackApp.getCrossOriginHeaders()
284
+ * // you can also add your own headers here
285
+ * },
286
+ * });
287
+ *
288
+ * // server
289
+ * function handleRequest(req: Request) {
290
+ * const user = await stackServerApp.getUser({ tokenStore: req });
291
+ * return new Response("Welcome, " + user.displayName);
292
+ * }
293
+ * ```
294
+ */
295
+ getCrossOriginHeaders(): Promise<{
296
+ "x-stack-auth": string;
297
+ }>;
298
+ /**
299
+ * With most browsers now disabling third-party cookies by default, there need to be new ways to send authenticated
300
+ * requests across different origins. While `getCrossOriginHeaders` is the recommended way to do this, there
301
+ * are some cases where you might want to send the tokens differently, for example when you are using WebSockets
302
+ * or non-HTTP protocols.
303
+ *
304
+ * This function returns a token object that can be JSON-serialized and sent to the server in any way you like.
305
+ * There, you can use the `tokenStore` option on your Stack app to fetch user details.
306
+ *
307
+ * Example:
308
+ *
309
+ * ```ts
310
+ * // client
311
+ * const res = await rpcCall(rpcEndpoint, {
312
+ * data: {
313
+ * auth: await stackApp.getCrossOriginTokenObject(),
314
+ * },
315
+ * });
316
+ *
317
+ * // server
318
+ * function handleRequest(data) {
319
+ * const user = await stackServerApp.getUser({ tokenStore: data.auth });
320
+ * return new Response("Welcome, " + user.displayName);
321
+ * }
322
+ * ```
323
+ */
324
+ getCrossOriginTokenObject(): Promise<{
325
+ accessToken: string | null;
326
+ refreshToken: string | null;
327
+ }>;
248
328
  [stackAppInternalsSymbol]: {
249
329
  toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>;
250
330
  setCurrentUser(userJsonPromise: Promise<UserJson | null>): void;