@mastra/auth-studio 1.3.2 → 1.3.3-alpha.0

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,16 @@
1
1
  # @mastra/auth-studio
2
2
 
3
+ ## 1.3.3-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Speed up Factory hot paths: ([#20261](https://github.com/mastra-ai/mastra/pull/20261))
8
+
9
+ - Much lower latency on authenticated requests — successful auth verifications are cached briefly instead of hitting the platform on every request, and credential verification requests time out after 15 seconds instead of hanging
10
+ - Faster GitHub repository listing and connecting
11
+ - Opening the same session concurrently no longer provisions duplicate sandboxes, and stuck sandbox commands now fail with a clear error instead of hanging
12
+ - Factory run dispatching stays fast as work-item history grows
13
+
3
14
  ## 1.3.2
4
15
 
5
16
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var crypto$1 = require('crypto');
4
+
5
+ // src/index.ts
6
+
3
7
  // ../../packages/_internals/auth/dist/chunk-LZCWL5CT.js
4
8
  var RESOURCE_EXPANSIONS = {
5
9
  stored: [
@@ -266,6 +270,8 @@ function getRequestHeader2(request, name) {
266
270
  return request.raw?.headers.get(name) ?? request.headers?.get(name) ?? request.header(name) ?? null;
267
271
  }
268
272
  var COOKIE_NAME = "wos-session";
273
+ var VERIFY_FETCH_TIMEOUT_MS = 15e3;
274
+ var VERIFY_CACHE_TTL_MS = 3e4;
269
275
  var MastraAuthStudio = class extends MastraAuthProvider {
270
276
  isMastraCloudAuth = true;
271
277
  sharedApiUrl;
@@ -281,6 +287,15 @@ var MastraAuthStudio = class extends MastraAuthProvider {
281
287
  */
282
288
  userSessionCookies = /* @__PURE__ */ new Map();
283
289
  maxCachedSessions = 1e3;
290
+ /**
291
+ * Short-TTL cache of SUCCESSFUL credential verifications, keyed by a
292
+ * sha256 of the credential (never the raw cookie/token). Every protected
293
+ * request re-verifies against the shared API otherwise — one network
294
+ * round trip per request. Failures are never cached, so a rejected
295
+ * credential is always re-checked. Bounded + insert-order evicted.
296
+ */
297
+ verifiedCredentials = /* @__PURE__ */ new Map();
298
+ maxCachedVerifications = 1e3;
284
299
  /**
285
300
  * In-flight `ensureOrganization` promises keyed by userId. Concurrent calls
286
301
  * for the same brand-new user (multiple tabs, parallel requests) would
@@ -635,6 +650,27 @@ var MastraAuthStudio = class extends MastraAuthProvider {
635
650
  if (oldest !== void 0) this.userSessionCookies.delete(oldest);
636
651
  }
637
652
  }
653
+ /** Cache key for a verified credential — hash, never the raw secret. */
654
+ verificationKey(kind, credential) {
655
+ return crypto$1.createHash("sha256").update(`${kind}:${credential}`).digest("hex");
656
+ }
657
+ getCachedVerification(key) {
658
+ const entry = this.verifiedCredentials.get(key);
659
+ if (!entry) return null;
660
+ if (entry.expiresAt <= Date.now()) {
661
+ this.verifiedCredentials.delete(key);
662
+ return null;
663
+ }
664
+ return entry.user;
665
+ }
666
+ cacheVerification(key, user) {
667
+ this.verifiedCredentials.delete(key);
668
+ this.verifiedCredentials.set(key, { user, expiresAt: Date.now() + VERIFY_CACHE_TTL_MS });
669
+ if (this.verifiedCredentials.size > this.maxCachedVerifications) {
670
+ const oldest = this.verifiedCredentials.keys().next().value;
671
+ if (oldest !== void 0) this.verifiedCredentials.delete(oldest);
672
+ }
673
+ }
638
674
  /**
639
675
  * Fetch the shared API's `/auth/me` and return the raw response body, or
640
676
  * `null` on any non-OK / network error. Split out so `ensureOrganization`
@@ -643,7 +679,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
643
679
  async fetchMe(sessionCookie) {
644
680
  try {
645
681
  const res = await fetch(`${this.sharedApiUrl}/auth/me`, {
646
- headers: { Cookie: `${COOKIE_NAME}=${sessionCookie}` }
682
+ headers: { Cookie: `${COOKIE_NAME}=${sessionCookie}` },
683
+ signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
647
684
  });
648
685
  if (!res.ok) return null;
649
686
  return await res.json();
@@ -656,11 +693,18 @@ var MastraAuthStudio = class extends MastraAuthProvider {
656
693
  * to validate it and get user info.
657
694
  */
658
695
  async verifySessionCookie(sessionCookie) {
696
+ const cacheKey = this.verificationKey("cookie", sessionCookie);
697
+ const cached = this.getCachedVerification(cacheKey);
698
+ if (cached) {
699
+ this.rememberUserSession(cached.id, sessionCookie);
700
+ return cached;
701
+ }
659
702
  try {
660
703
  const res = await fetch(`${this.sharedApiUrl}/auth/me`, {
661
704
  headers: {
662
705
  Cookie: `${COOKIE_NAME}=${sessionCookie}`
663
- }
706
+ },
707
+ signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
664
708
  });
665
709
  if (!res.ok) {
666
710
  this.logger.warn("verifySessionCookie: shared API returned non-OK status", {
@@ -672,7 +716,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
672
716
  }
673
717
  const data = await res.json();
674
718
  this.rememberUserSession(data.user.id, sessionCookie);
675
- return {
719
+ const user = {
676
720
  id: data.user.id,
677
721
  email: data.user.email,
678
722
  name: [data.user.firstName, data.user.lastName].filter(Boolean).join(" ") || void 0,
@@ -682,6 +726,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
682
726
  permissions: data.permissions,
683
727
  memberOrgIds: data.memberOrgIds
684
728
  };
729
+ if (user.organizationId) this.cacheVerification(cacheKey, user);
730
+ return user;
685
731
  } catch (error) {
686
732
  this.logger.error("verifySessionCookie: fetch to shared API failed", {
687
733
  url: `${this.sharedApiUrl}/auth/me`,
@@ -695,11 +741,15 @@ var MastraAuthStudio = class extends MastraAuthProvider {
695
741
  * to validate it and get user info (used for CLI tokens).
696
742
  */
697
743
  async verifyBearerToken(token) {
744
+ const cacheKey = this.verificationKey("bearer", token);
745
+ const cached = this.getCachedVerification(cacheKey);
746
+ if (cached) return cached;
698
747
  try {
699
748
  const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {
700
749
  headers: {
701
750
  Authorization: `Bearer ${token}`
702
- }
751
+ },
752
+ signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
703
753
  });
704
754
  if (!res.ok) {
705
755
  this.logger.warn("verifyBearerToken: shared API returned non-OK status", {
@@ -709,7 +759,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
709
759
  return null;
710
760
  }
711
761
  const data = await res.json();
712
- return {
762
+ const user = {
713
763
  id: data.user.id,
714
764
  email: data.user.email,
715
765
  name: [data.user.firstName, data.user.lastName].filter(Boolean).join(" ") || void 0,
@@ -717,6 +767,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
717
767
  role: data.role,
718
768
  memberOrgIds: data.memberOrgIds
719
769
  };
770
+ if (user.organizationId) this.cacheVerification(cacheKey, user);
771
+ return user;
720
772
  } catch (error) {
721
773
  this.logger.error("verifyBearerToken: fetch to shared API failed", {
722
774
  url: `${this.sharedApiUrl}/auth/verify`,