@stackframe/stack 2.4.18 → 2.4.21

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,32 @@
1
1
  # @stackframe/stack
2
2
 
3
+ ## 2.4.21
4
+
5
+ ### Patch Changes
6
+
7
+ - Bugfixes
8
+ - Updated dependencies
9
+ - @stackframe/stack-sc@2.4.21
10
+ - @stackframe/stack-shared@2.4.21
11
+
12
+ ## 2.4.20
13
+
14
+ ### Patch Changes
15
+
16
+ - Support multiple projects on the same domain
17
+ - Updated dependencies
18
+ - @stackframe/stack-shared@2.4.20
19
+ - @stackframe/stack-sc@2.4.20
20
+
21
+ ## 2.4.19
22
+
23
+ ### Patch Changes
24
+
25
+ - Sync package versions
26
+ - Updated dependencies
27
+ - @stackframe/stack-sc@2.4.19
28
+ - @stackframe/stack-shared@2.4.19
29
+
3
30
  ## 2.4.18
4
31
 
5
32
  ### Patch Changes
@@ -12,18 +12,18 @@ import React__default from 'react';
12
12
  declare const Button: React__default.ForwardRefExoticComponent<Omit<Omit<ButtonProps, "ref"> & React__default.RefAttributes<HTMLButtonElement>, "ref"> & React__default.RefAttributes<HTMLButtonElement>>;
13
13
  declare const Input: React__default.ForwardRefExoticComponent<Omit<Omit<React__default.InputHTMLAttributes<HTMLInputElement> & Pick<React__default.HTMLProps<HTMLInputElement>, "ref">, "ref"> & React__default.RefAttributes<HTMLInputElement>, "ref"> & React__default.RefAttributes<HTMLInputElement>>;
14
14
  declare const Container: React__default.ForwardRefExoticComponent<Omit<{
15
- size?: number | "xs" | "sm" | "md" | "lg" | "xl" | undefined;
15
+ size?: number | "sm" | "md" | "lg" | "xs" | "xl" | undefined;
16
16
  } & Omit<React__default.HTMLProps<HTMLDivElement>, "size">, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
17
17
  declare const Separator: React__default.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_separator.SeparatorProps & React__default.RefAttributes<HTMLDivElement>, "ref"> & React__default.RefAttributes<HTMLDivElement>, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
18
18
  declare const Label: React__default.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_label.LabelProps & React__default.RefAttributes<HTMLLabelElement>, "ref"> & React__default.RefAttributes<HTMLLabelElement>, "ref"> & React__default.RefAttributes<HTMLLabelElement>>;
19
19
  declare const Link: React__default.ForwardRefExoticComponent<Omit<Omit<{
20
- size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
20
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
21
21
  href: string | url.Url;
22
22
  } & Omit<React__default.HTMLProps<HTMLLinkElement>, "size" | "href">, "ref"> & React__default.RefAttributes<HTMLAnchorElement>, "ref"> & React__default.RefAttributes<HTMLAnchorElement>>;
23
23
  declare const Text: React__default.ForwardRefExoticComponent<Omit<Omit<{
24
24
  variant?: "primary" | "secondary" | "warning" | "success" | undefined;
25
- as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | undefined;
26
- size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
25
+ as?: "h2" | "h3" | "p" | "h1" | "h4" | "h5" | "h6" | undefined;
26
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
27
27
  } & Omit<React__default.HTMLProps<HTMLParagraphElement>, "size">, "ref"> & React__default.RefAttributes<HTMLParagraphElement>, "ref"> & React__default.RefAttributes<HTMLParagraphElement>>;
28
28
  declare const Popover: React__default.ForwardRefExoticComponent<_radix_ui_react_popover.PopoverProps & React__default.RefAttributes<never>>;
29
29
  declare const PopoverTrigger: React__default.ForwardRefExoticComponent<Omit<_radix_ui_react_popover.PopoverTriggerProps & React__default.RefAttributes<HTMLButtonElement>, "ref"> & React__default.RefAttributes<HTMLButtonElement>>;
@@ -12,18 +12,18 @@ import React__default from 'react';
12
12
  declare const Button: React__default.ForwardRefExoticComponent<Omit<Omit<ButtonProps, "ref"> & React__default.RefAttributes<HTMLButtonElement>, "ref"> & React__default.RefAttributes<HTMLButtonElement>>;
13
13
  declare const Input: React__default.ForwardRefExoticComponent<Omit<Omit<React__default.InputHTMLAttributes<HTMLInputElement> & Pick<React__default.HTMLProps<HTMLInputElement>, "ref">, "ref"> & React__default.RefAttributes<HTMLInputElement>, "ref"> & React__default.RefAttributes<HTMLInputElement>>;
14
14
  declare const Container: React__default.ForwardRefExoticComponent<Omit<{
15
- size?: number | "xs" | "sm" | "md" | "lg" | "xl" | undefined;
15
+ size?: number | "sm" | "md" | "lg" | "xs" | "xl" | undefined;
16
16
  } & Omit<React__default.HTMLProps<HTMLDivElement>, "size">, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
17
17
  declare const Separator: React__default.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_separator.SeparatorProps & React__default.RefAttributes<HTMLDivElement>, "ref"> & React__default.RefAttributes<HTMLDivElement>, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
18
18
  declare const Label: React__default.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_label.LabelProps & React__default.RefAttributes<HTMLLabelElement>, "ref"> & React__default.RefAttributes<HTMLLabelElement>, "ref"> & React__default.RefAttributes<HTMLLabelElement>>;
19
19
  declare const Link: React__default.ForwardRefExoticComponent<Omit<Omit<{
20
- size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
20
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
21
21
  href: string | url.Url;
22
22
  } & Omit<React__default.HTMLProps<HTMLLinkElement>, "size" | "href">, "ref"> & React__default.RefAttributes<HTMLAnchorElement>, "ref"> & React__default.RefAttributes<HTMLAnchorElement>>;
23
23
  declare const Text: React__default.ForwardRefExoticComponent<Omit<Omit<{
24
24
  variant?: "primary" | "secondary" | "warning" | "success" | undefined;
25
- as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | undefined;
26
- size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
25
+ as?: "h2" | "h3" | "p" | "h1" | "h4" | "h5" | "h6" | undefined;
26
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
27
27
  } & Omit<React__default.HTMLProps<HTMLParagraphElement>, "size">, "ref"> & React__default.RefAttributes<HTMLParagraphElement>, "ref"> & React__default.RefAttributes<HTMLParagraphElement>>;
28
28
  declare const Popover: React__default.ForwardRefExoticComponent<_radix_ui_react_popover.PopoverProps & React__default.RefAttributes<never>>;
29
29
  declare const PopoverTrigger: React__default.ForwardRefExoticComponent<Omit<_radix_ui_react_popover.PopoverTriggerProps & React__default.RefAttributes<HTMLButtonElement>, "ref"> & React__default.RefAttributes<HTMLButtonElement>>;
@@ -8,21 +8,21 @@ import { AsyncResult, Result } from "@stackframe/stack-shared/dist/utils/results
8
8
  import { suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
9
9
  import { Store } from "@stackframe/stack-shared/dist/utils/stores";
10
10
  import { getProductionModeErrors } from "@stackframe/stack-shared/dist/interface/clientInterface";
11
- import { isBrowserLike } from "@stackframe/stack-shared/src/utils/env";
11
+ import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
12
12
  import { callOAuthCallback, signInWithOAuth } from "./auth";
13
13
  import * as NextNavigationUnscrambled from "next/navigation";
14
14
  import { constructRedirectUrl } from "../utils/url";
15
- import { filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
15
+ import { deepPlainEquals, filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
16
16
  import { resolved, runAsynchronously, wait } from "@stackframe/stack-shared/dist/utils/promises";
17
17
  import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
18
18
  import { suspend } from "@stackframe/stack-shared/dist/utils/react";
19
19
  import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
20
20
  import { isReactServer } from "@stackframe/stack-sc";
21
21
  import * as cookie from "cookie";
22
- import { Session } from "@stackframe/stack-shared/dist/sessions";
22
+ import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
23
23
  import { useTrigger } from "@stackframe/stack-shared/dist/hooks/use-trigger";
24
24
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
25
- var clientVersion = "js @stackframe/stack@2.4.18";
25
+ var clientVersion = "js @stackframe/stack@2.4.21";
26
26
  function permissionDefinitionScopeToType(scope) {
27
27
  return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
28
28
  }
@@ -68,43 +68,6 @@ function createEmptyTokenStore() {
68
68
  accessToken: null
69
69
  });
70
70
  }
71
- var storedCookieTokenStore = null;
72
- var getCookieTokenStore = () => {
73
- if (!isBrowserLike()) {
74
- throw new Error("Cannot use cookie token store on the server!");
75
- }
76
- if (storedCookieTokenStore === null) {
77
- const getCurrentValue = () => ({
78
- refreshToken: getCookie("stack-refresh"),
79
- accessToken: getCookie("stack-access")
80
- });
81
- storedCookieTokenStore = new Store(getCurrentValue());
82
- let hasSucceededInWriting = true;
83
- setInterval(() => {
84
- if (hasSucceededInWriting) {
85
- const currentValue = getCurrentValue();
86
- const oldValue = storedCookieTokenStore.get();
87
- if (JSON.stringify(currentValue) !== JSON.stringify(oldValue)) {
88
- storedCookieTokenStore.set(currentValue);
89
- }
90
- }
91
- }, 100);
92
- storedCookieTokenStore.onChange((value) => {
93
- try {
94
- setOrDeleteCookie("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
95
- setOrDeleteCookie("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
96
- hasSucceededInWriting = true;
97
- } catch (e) {
98
- if (!isBrowserLike()) {
99
- hasSucceededInWriting = false;
100
- } else {
101
- throw e;
102
- }
103
- }
104
- });
105
- }
106
- return storedCookieTokenStore;
107
- };
108
71
  var loadingSentinel = Symbol("stackAppCacheLoadingSentinel");
109
72
  function useAsyncCache(cache, dependencies, caller) {
110
73
  suspendIfSsr(caller);
@@ -212,24 +175,72 @@ var _StackClientAppImpl = class __StackClientAppImpl {
212
175
  }
213
176
  _memoryTokenStore = createEmptyTokenStore();
214
177
  _requestTokenStores = /* @__PURE__ */ new WeakMap();
178
+ _storedCookieTokenStore = null;
179
+ get _refreshTokenCookieName() {
180
+ return `stack-refresh-${this.projectId}`;
181
+ }
182
+ get _accessTokenCookieName() {
183
+ return `stack-access`;
184
+ }
185
+ _getCookieTokenStore() {
186
+ if (!isBrowserLike()) {
187
+ throw new Error("Cannot use cookie token store on the server!");
188
+ }
189
+ if (this._storedCookieTokenStore === null) {
190
+ const getCurrentValue = (old) => ({
191
+ refreshToken: getCookie(this._refreshTokenCookieName) ?? getCookie("stack-refresh"),
192
+ // keep old cookie name for backwards-compatibility
193
+ // if there is an access token in memory already, don't update the access token based on cookies (access token
194
+ // cookies may be set by another project on the same domain)
195
+ // see the comment in _accessTokenCookieName for more information
196
+ accessToken: old === null ? getCookie(this._accessTokenCookieName) : old.accessToken
197
+ });
198
+ this._storedCookieTokenStore = new Store(getCurrentValue(null));
199
+ let hasSucceededInWriting = true;
200
+ setInterval(() => {
201
+ if (hasSucceededInWriting) {
202
+ const oldValue = this._storedCookieTokenStore.get();
203
+ const currentValue = getCurrentValue(oldValue);
204
+ if (!deepPlainEquals(currentValue, oldValue)) {
205
+ this._storedCookieTokenStore.set(currentValue);
206
+ }
207
+ }
208
+ }, 100);
209
+ this._storedCookieTokenStore.onChange((value) => {
210
+ try {
211
+ setOrDeleteCookie(this._refreshTokenCookieName, value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
212
+ setOrDeleteCookie(this._accessTokenCookieName, value.accessToken, { maxAge: 60 * 60 * 24 });
213
+ hasSucceededInWriting = true;
214
+ } catch (e) {
215
+ if (!isBrowserLike()) {
216
+ hasSucceededInWriting = false;
217
+ } else {
218
+ throw e;
219
+ }
220
+ }
221
+ });
222
+ }
223
+ return this._storedCookieTokenStore;
224
+ }
215
225
  _getOrCreateTokenStore(overrideTokenStoreInit) {
216
226
  const tokenStoreInit = overrideTokenStoreInit === void 0 ? this._tokenStoreInit : overrideTokenStoreInit;
217
227
  switch (tokenStoreInit) {
218
228
  case "cookie": {
219
- return getCookieTokenStore();
229
+ return this._getCookieTokenStore();
220
230
  }
221
231
  case "nextjs-cookie": {
222
232
  if (isBrowserLike()) {
223
- return getCookieTokenStore();
233
+ return this._getCookieTokenStore();
224
234
  } else {
225
235
  const store = new Store({
226
- refreshToken: getCookie("stack-refresh"),
227
- accessToken: getCookie("stack-access")
236
+ refreshToken: getCookie(this._refreshTokenCookieName) ?? getCookie("stack-refresh"),
237
+ // keep old cookie name for backwards-compatibility
238
+ accessToken: getCookie(this._accessTokenCookieName)
228
239
  });
229
240
  store.onChange((value) => {
230
241
  try {
231
- setOrDeleteCookie("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
232
- setOrDeleteCookie("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
242
+ setOrDeleteCookie(this._refreshTokenCookieName, value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
243
+ setOrDeleteCookie(this._accessTokenCookieName, value.accessToken, { maxAge: 60 * 60 * 24 });
233
244
  } catch (e) {
234
245
  }
235
246
  });
@@ -239,21 +250,43 @@ var _StackClientAppImpl = class __StackClientAppImpl {
239
250
  case "memory": {
240
251
  return this._memoryTokenStore;
241
252
  }
242
- case null: {
243
- return createEmptyTokenStore();
244
- }
245
253
  default: {
246
- if (tokenStoreInit !== null && typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
254
+ if (tokenStoreInit === null) {
255
+ return createEmptyTokenStore();
256
+ } else if (typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
247
257
  if (this._requestTokenStores.has(tokenStoreInit))
248
258
  return this._requestTokenStores.get(tokenStoreInit);
259
+ const stackAuthHeader = tokenStoreInit.headers.get("x-stack-auth");
260
+ if (stackAuthHeader) {
261
+ let parsed2;
262
+ try {
263
+ parsed2 = JSON.parse(stackAuthHeader);
264
+ if (typeof parsed2 !== "object")
265
+ throw new Error("x-stack-auth header must be a JSON object");
266
+ if (parsed2 === null)
267
+ throw new Error("x-stack-auth header must not be null");
268
+ } catch (e) {
269
+ throw new Error(`Invalid x-stack-auth header: ${stackAuthHeader}`, { cause: e });
270
+ }
271
+ return this._getOrCreateTokenStore({
272
+ accessToken: parsed2.accessToken ?? null,
273
+ refreshToken: parsed2.refreshToken ?? null
274
+ });
275
+ }
249
276
  const cookieHeader = tokenStoreInit.headers.get("cookie");
250
277
  const parsed = cookie.parse(cookieHeader || "");
251
278
  const res = new Store({
252
- refreshToken: parsed["stack-refresh"] || null,
253
- accessToken: parsed["stack-access"] || null
279
+ refreshToken: parsed[this._refreshTokenCookieName] || parsed["stack-refresh"] || null,
280
+ // keep old cookie name for backwards-compatibility
281
+ accessToken: parsed[this._accessTokenCookieName] || null
254
282
  });
255
283
  this._requestTokenStores.set(tokenStoreInit, res);
256
284
  return res;
285
+ } else if ("accessToken" in tokenStoreInit || "refreshToken" in tokenStoreInit) {
286
+ return new Store({
287
+ refreshToken: tokenStoreInit.refreshToken,
288
+ accessToken: tokenStoreInit.accessToken
289
+ });
257
290
  }
258
291
  throw new Error(`Invalid token store ${tokenStoreInit}`);
259
292
  }
@@ -270,7 +303,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
270
303
  _sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
271
304
  _getSessionFromTokenStore(tokenStore) {
272
305
  const tokenObj = tokenStore.get();
273
- const sessionKey = Session.calculateSessionKey(tokenObj);
306
+ const sessionKey = InternalSession.calculateSessionKey(tokenObj);
274
307
  const existing = sessionKey ? this._sessionsByTokenStoreAndSessionKey.get(tokenStore)?.get(sessionKey) : null;
275
308
  if (existing)
276
309
  return existing;
@@ -444,7 +477,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
444
477
  const app = this;
445
478
  const currentUser = {
446
479
  ...this._userFromJson(json),
447
- session,
480
+ _internalSession: session,
481
+ currentSession: {
482
+ async getTokens() {
483
+ const tokens = await session.getPotentiallyExpiredTokens();
484
+ return {
485
+ accessToken: tokens?.accessToken.token ?? null,
486
+ refreshToken: tokens?.refreshToken?.token ?? null
487
+ };
488
+ }
489
+ },
448
490
  async updateSelectedTeam(team) {
449
491
  await app._updateUser({ selectedTeamId: team?.id ?? null }, session);
450
492
  },
@@ -531,6 +573,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
531
573
  get urls() {
532
574
  return getUrls(this._urlOptions);
533
575
  }
576
+ async getCrossOriginHeaders() {
577
+ return {
578
+ "x-stack-auth": JSON.stringify(await this.getCrossOriginTokenObject())
579
+ };
580
+ }
581
+ async getCrossOriginTokenObject() {
582
+ const user = await this.getUser();
583
+ if (!user)
584
+ return { accessToken: null, refreshToken: null };
585
+ const tokens = await user.currentSession.getTokens();
586
+ return tokens;
587
+ }
534
588
  async _redirectTo(handlerName, options) {
535
589
  const url = this.urls[handlerName];
536
590
  if (!url) {
@@ -982,7 +1036,16 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
982
1036
  const nonCurrentServerUser = this._serverUserFromJson(json);
983
1037
  const currentUser = {
984
1038
  ...nonCurrentServerUser,
985
- session,
1039
+ _internalSession: session,
1040
+ currentSession: {
1041
+ async getTokens() {
1042
+ const tokens = await session.getPotentiallyExpiredTokens();
1043
+ return {
1044
+ accessToken: tokens?.accessToken.token ?? null,
1045
+ refreshToken: tokens?.refreshToken?.token ?? null
1046
+ };
1047
+ }
1048
+ },
986
1049
  async delete() {
987
1050
  const res = await nonCurrentServerUser.delete();
988
1051
  await app._refreshUser(session);