@mastra/auth-studio 1.3.8 → 1.3.9

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/index.d.ts CHANGED
@@ -32,6 +32,13 @@ export interface MastraAuthStudioOptions extends MastraAuthProviderOptions<Studi
32
32
  * Can also be set via MASTRA_COOKIE_DOMAIN environment variable.
33
33
  */
34
34
  cookieDomain?: string;
35
+ /**
36
+ * Lifetime of the session cookie (and Session.expiresAt) in seconds.
37
+ * Should match the identity provider's maximum session length.
38
+ * Can also be set via MASTRA_SESSION_MAX_AGE environment variable.
39
+ * Defaults to 14 days.
40
+ */
41
+ sessionMaxAgeSeconds?: number;
35
42
  }
36
43
  /**
37
44
  * Auth provider for Mastra Studio deployed instances.
@@ -50,6 +57,7 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
50
57
  private organizationId;
51
58
  private useProductionCookies;
52
59
  private cookieDomain;
60
+ private sessionMaxAgeSeconds;
53
61
  /**
54
62
  * `userId → sealed session cookie` cache. The `IOrganizationsProvider`
55
63
  * interface only hands us a `userId`, but the shared API's org endpoints are
@@ -76,6 +84,19 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
76
84
  * caller's promise is reused by every follower until it settles.
77
85
  */
78
86
  private organizationBootstrapInFlight;
87
+ /**
88
+ * Per-request response headers to forward to the browser — specifically a
89
+ * rotated `wos-session` `Set-Cookie` returned by the shared API when the
90
+ * platform `sessionAuth` middleware transparently refreshes an expired
91
+ * access token. Without this, the browser's sealed cookie would never
92
+ * rotate: platform would succeed server-to-server by refreshing on every
93
+ * request, but the next refresh would hit `invalid_grant` once WorkOS
94
+ * invalidated the previous refresh token.
95
+ *
96
+ * Keyed by the underlying `Request` (via `getWebRequest`) so we don't retain
97
+ * requests after the response is written.
98
+ */
99
+ private pendingResponseHeaders;
79
100
  constructor(options?: MastraAuthStudioOptions);
80
101
  /**
81
102
  * Authenticate an incoming request by forwarding the sealed session cookie
@@ -137,6 +158,25 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
137
158
  private verificationKey;
138
159
  private getCachedVerification;
139
160
  private cacheVerification;
161
+ /**
162
+ * Read every `Set-Cookie` header from a response, falling back to the
163
+ * single-value accessor on runtimes without `Headers.getSetCookie()`.
164
+ */
165
+ private readSetCookieHeaders;
166
+ /**
167
+ * If the shared API rotated the sealed `wos-session` cookie on this
168
+ * response, stash the `Set-Cookie` header against the inbound request so
169
+ * the server middleware can forward it to the browser, and invalidate the
170
+ * short-TTL verification cache entry for the old cookie value. Returns the
171
+ * rotated sealed value, or null when the cookie was not rotated.
172
+ */
173
+ private captureRotatedCookie;
174
+ /**
175
+ * Server middleware hook: emit any response headers the provider
176
+ * accumulated for this request (currently a rotated `Set-Cookie`) and
177
+ * clear them from the provider's per-request state.
178
+ */
179
+ consumePendingResponseHeaders(request: MastraAuthRequest): Record<string, string> | undefined;
140
180
  /**
141
181
  * Fetch the shared API's `/auth/me` and return the raw response body, or
142
182
  * `null` on any non-OK / network error. Split out so `ensureOrganization`
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,6 +20,10 @@ function getRequestHeader(request, name) {
20
20
  if (headers && typeof headers === "object") return headerFromPlainObject(headers, name);
21
21
  return null;
22
22
  }
23
+ function getWebRequest(request) {
24
+ if (request instanceof Request) return request;
25
+ return request.raw instanceof Request ? request.raw : void 0;
26
+ }
23
27
  //#endregion
24
28
  //#region ../../packages/_internal-core/dist/logger/index.js
25
29
  /**
@@ -423,6 +427,7 @@ function resolvePermissionsFromMapping(roles, mapping) {
423
427
  */
424
428
  //#endregion
425
429
  //#region src/index.ts
430
+ const DEFAULT_SESSION_MAX_AGE_SECONDS = 336 * 60 * 60;
426
431
  const COOKIE_NAME = "wos-session";
427
432
  const PROJECT_CONFIG_FILE = ".mastra-project.json";
428
433
  /**
@@ -473,6 +478,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
473
478
  organizationId;
474
479
  useProductionCookies;
475
480
  cookieDomain;
481
+ sessionMaxAgeSeconds;
476
482
  /**
477
483
  * `userId → sealed session cookie` cache. The `IOrganizationsProvider`
478
484
  * interface only hands us a `userId`, but the shared API's org endpoints are
@@ -499,6 +505,19 @@ var MastraAuthStudio = class extends MastraAuthProvider {
499
505
  * caller's promise is reused by every follower until it settles.
500
506
  */
501
507
  organizationBootstrapInFlight = /* @__PURE__ */ new Map();
508
+ /**
509
+ * Per-request response headers to forward to the browser — specifically a
510
+ * rotated `wos-session` `Set-Cookie` returned by the shared API when the
511
+ * platform `sessionAuth` middleware transparently refreshes an expired
512
+ * access token. Without this, the browser's sealed cookie would never
513
+ * rotate: platform would succeed server-to-server by refreshing on every
514
+ * request, but the next refresh would hit `invalid_grant` once WorkOS
515
+ * invalidated the previous refresh token.
516
+ *
517
+ * Keyed by the underlying `Request` (via `getWebRequest`) so we don't retain
518
+ * requests after the response is written.
519
+ */
520
+ pendingResponseHeaders = /* @__PURE__ */ new WeakMap();
502
521
  constructor(options) {
503
522
  super({
504
523
  name: "mastra-studio",
@@ -509,6 +528,9 @@ var MastraAuthStudio = class extends MastraAuthProvider {
509
528
  this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID || readOrganizationIdFromProjectConfig();
510
529
  if (this.sharedApiUrl.endsWith("/")) this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);
511
530
  this.cookieDomain = options?.cookieDomain || process.env.MASTRA_COOKIE_DOMAIN;
531
+ const envMaxAge = Number(process.env.MASTRA_SESSION_MAX_AGE);
532
+ const maxAge = options?.sessionMaxAgeSeconds ?? (envMaxAge > 0 ? envMaxAge : void 0);
533
+ this.sessionMaxAgeSeconds = maxAge && Number.isFinite(maxAge) && maxAge > 0 ? Math.floor(maxAge) : DEFAULT_SESSION_MAX_AGE_SECONDS;
512
534
  let autoDetectMastraAi = false;
513
535
  if (explicitSharedApiUrl) try {
514
536
  const hostname = new URL(this.sharedApiUrl).hostname.toLowerCase();
@@ -527,7 +549,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
527
549
  async authenticateToken(token, request) {
528
550
  let user = null;
529
551
  const sessionCookie = parseCookie(getRequestHeader(request, "Cookie"), COOKIE_NAME);
530
- if (sessionCookie) user = await this.verifySessionCookie(sessionCookie);
552
+ if (sessionCookie) user = await this.verifySessionCookie(sessionCookie, request);
531
553
  if (!user && token) user = await this.verifyBearerToken(token);
532
554
  if (!user) return null;
533
555
  if (this.organizationId && !user.memberOrgIds?.includes(this.organizationId)) return null;
@@ -601,7 +623,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
601
623
  return {
602
624
  id: metadata?.accessToken || crypto.randomUUID(),
603
625
  userId,
604
- expiresAt: new Date(now.getTime() + 1440 * 60 * 1e3),
626
+ expiresAt: new Date(now.getTime() + this.sessionMaxAgeSeconds * 1e3),
605
627
  createdAt: now,
606
628
  metadata
607
629
  };
@@ -613,7 +635,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
613
635
  return {
614
636
  id: sessionId,
615
637
  userId: user.id,
616
- expiresAt: new Date(now.getTime() + 1440 * 60 * 1e3),
638
+ expiresAt: new Date(now.getTime() + this.sessionMaxAgeSeconds * 1e3),
617
639
  createdAt: now
618
640
  };
619
641
  }
@@ -650,7 +672,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
650
672
  return {
651
673
  id: newSessionId,
652
674
  userId: user.id,
653
- expiresAt: new Date(now.getTime() + 1440 * 60 * 1e3),
675
+ expiresAt: new Date(now.getTime() + this.sessionMaxAgeSeconds * 1e3),
654
676
  createdAt: now
655
677
  };
656
678
  } catch (error) {
@@ -673,7 +695,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
673
695
  "HttpOnly",
674
696
  "SameSite=Lax",
675
697
  "Path=/",
676
- "Max-Age=86400"
698
+ `Max-Age=${this.sessionMaxAgeSeconds}`
677
699
  ];
678
700
  if (this.useProductionCookies && this.cookieDomain) {
679
701
  parts.push("Secure");
@@ -697,7 +719,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
697
719
  }
698
720
  async getCurrentUser(request) {
699
721
  const sessionCookie = parseCookie(request.headers.get("Cookie"), COOKIE_NAME);
700
- if (sessionCookie) return this.verifySessionCookie(sessionCookie);
722
+ if (sessionCookie) return this.verifySessionCookie(sessionCookie, request);
701
723
  const authHeader = request.headers.get("Authorization");
702
724
  if (authHeader?.startsWith("Bearer ")) return this.verifyBearerToken(authHeader.slice(7));
703
725
  return null;
@@ -850,6 +872,57 @@ var MastraAuthStudio = class extends MastraAuthProvider {
850
872
  }
851
873
  }
852
874
  /**
875
+ * Read every `Set-Cookie` header from a response, falling back to the
876
+ * single-value accessor on runtimes without `Headers.getSetCookie()`.
877
+ */
878
+ readSetCookieHeaders(res) {
879
+ const headers = res.headers;
880
+ if (typeof headers.getSetCookie === "function") return headers.getSetCookie();
881
+ const single = res.headers.get("Set-Cookie");
882
+ return single ? [single] : [];
883
+ }
884
+ /**
885
+ * If the shared API rotated the sealed `wos-session` cookie on this
886
+ * response, stash the `Set-Cookie` header against the inbound request so
887
+ * the server middleware can forward it to the browser, and invalidate the
888
+ * short-TTL verification cache entry for the old cookie value. Returns the
889
+ * rotated sealed value, or null when the cookie was not rotated.
890
+ */
891
+ captureRotatedCookie(res, oldSessionCookie, oldCacheKey, request) {
892
+ const setCookies = this.readSetCookieHeaders(res);
893
+ if (setCookies.length === 0) return null;
894
+ const rotatedCookieHeader = setCookies.find((h) => parseCookieFromHeader(h, COOKIE_NAME) !== null);
895
+ if (!rotatedCookieHeader) return null;
896
+ const rotatedValue = parseCookieFromHeader(rotatedCookieHeader, COOKIE_NAME);
897
+ if (!rotatedValue || rotatedValue === oldSessionCookie) return null;
898
+ const reissued = this.getSessionHeaders({
899
+ id: rotatedValue,
900
+ userId: "",
901
+ expiresAt: /* @__PURE__ */ new Date(),
902
+ createdAt: /* @__PURE__ */ new Date()
903
+ });
904
+ this.verifiedCredentials.delete(oldCacheKey);
905
+ if (request) {
906
+ const rawRequest = getWebRequest(request);
907
+ if (rawRequest) this.pendingResponseHeaders.set(rawRequest, reissued);
908
+ else this.logger.warn("captureRotatedCookie: renewed session cookie cannot be forwarded (no web Request)");
909
+ }
910
+ return rotatedValue;
911
+ }
912
+ /**
913
+ * Server middleware hook: emit any response headers the provider
914
+ * accumulated for this request (currently a rotated `Set-Cookie`) and
915
+ * clear them from the provider's per-request state.
916
+ */
917
+ consumePendingResponseHeaders(request) {
918
+ const rawRequest = getWebRequest(request);
919
+ if (!rawRequest) return void 0;
920
+ const headers = this.pendingResponseHeaders.get(rawRequest);
921
+ if (!headers) return void 0;
922
+ this.pendingResponseHeaders.delete(rawRequest);
923
+ return headers;
924
+ }
925
+ /**
853
926
  * Fetch the shared API's `/auth/me` and return the raw response body, or
854
927
  * `null` on any non-OK / network error. Split out so `ensureOrganization`
855
928
  * and `isOrganizationAdmin` can reuse it without duplicating the shape.
@@ -870,7 +943,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
870
943
  * Forward a sealed session cookie to the shared API's /auth/me endpoint
871
944
  * to validate it and get user info.
872
945
  */
873
- async verifySessionCookie(sessionCookie) {
946
+ async verifySessionCookie(sessionCookie, request) {
874
947
  const cacheKey = await this.verificationKey("cookie", sessionCookie);
875
948
  const cached = this.getCachedVerification(cacheKey);
876
949
  if (cached) {
@@ -882,6 +955,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
882
955
  headers: { Cookie: `${COOKIE_NAME}=${sessionCookie}` },
883
956
  signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
884
957
  });
958
+ const rotated = this.captureRotatedCookie(res, sessionCookie, cacheKey, request);
885
959
  if (!res.ok) {
886
960
  this.logger.warn("verifySessionCookie: shared API returned non-OK status", {
887
961
  status: res.status,
@@ -891,7 +965,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
891
965
  return null;
892
966
  }
893
967
  const data = await res.json();
894
- this.rememberUserSession(data.user.id, sessionCookie);
968
+ this.rememberUserSession(data.user.id, rotated ?? sessionCookie);
895
969
  const sessionUser = {
896
970
  id: data.user.id,
897
971
  email: data.user.email,
@@ -903,7 +977,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
903
977
  memberOrgIds: data.memberOrgIds
904
978
  };
905
979
  const user = await this.asPinnedOrganizationMember(sessionUser, sessionCookie);
906
- if (user.organizationId) this.cacheVerification(cacheKey, user);
980
+ if (user.organizationId && !rotated) this.cacheVerification(cacheKey, user);
907
981
  return user;
908
982
  } catch (error) {
909
983
  this.logger.error("verifySessionCookie: fetch to shared API failed", {
@@ -975,7 +1049,7 @@ function isAdminRole(role) {
975
1049
  }
976
1050
  /**
977
1051
  * Parse a cookie value from a Set-Cookie header.
978
- * Set-Cookie format: "name=value; HttpOnly; SameSite=Lax; Path=/; Max-Age=86400"
1052
+ * Set-Cookie format: "name=value; HttpOnly; SameSite=Lax; Path=/; Max-Age=1209600"
979
1053
  */
980
1054
  function parseCookieFromHeader(setCookieHeader, name) {
981
1055
  const parts = setCookieHeader.split(";");