@mastra/auth-studio 1.3.2-alpha.1 → 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 +21 -0
- package/dist/index.cjs +57 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -5
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
|
|
1
5
|
// ../../packages/_internals/auth/dist/chunk-LZCWL5CT.js
|
|
2
6
|
var RESOURCE_EXPANSIONS = {
|
|
3
7
|
stored: [
|
|
@@ -264,6 +268,8 @@ function getRequestHeader2(request, name) {
|
|
|
264
268
|
return request.raw?.headers.get(name) ?? request.headers?.get(name) ?? request.header(name) ?? null;
|
|
265
269
|
}
|
|
266
270
|
var COOKIE_NAME = "wos-session";
|
|
271
|
+
var VERIFY_FETCH_TIMEOUT_MS = 15e3;
|
|
272
|
+
var VERIFY_CACHE_TTL_MS = 3e4;
|
|
267
273
|
var MastraAuthStudio = class extends MastraAuthProvider {
|
|
268
274
|
isMastraCloudAuth = true;
|
|
269
275
|
sharedApiUrl;
|
|
@@ -279,6 +285,15 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
279
285
|
*/
|
|
280
286
|
userSessionCookies = /* @__PURE__ */ new Map();
|
|
281
287
|
maxCachedSessions = 1e3;
|
|
288
|
+
/**
|
|
289
|
+
* Short-TTL cache of SUCCESSFUL credential verifications, keyed by a
|
|
290
|
+
* sha256 of the credential (never the raw cookie/token). Every protected
|
|
291
|
+
* request re-verifies against the shared API otherwise — one network
|
|
292
|
+
* round trip per request. Failures are never cached, so a rejected
|
|
293
|
+
* credential is always re-checked. Bounded + insert-order evicted.
|
|
294
|
+
*/
|
|
295
|
+
verifiedCredentials = /* @__PURE__ */ new Map();
|
|
296
|
+
maxCachedVerifications = 1e3;
|
|
282
297
|
/**
|
|
283
298
|
* In-flight `ensureOrganization` promises keyed by userId. Concurrent calls
|
|
284
299
|
* for the same brand-new user (multiple tabs, parallel requests) would
|
|
@@ -633,6 +648,27 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
633
648
|
if (oldest !== void 0) this.userSessionCookies.delete(oldest);
|
|
634
649
|
}
|
|
635
650
|
}
|
|
651
|
+
/** Cache key for a verified credential — hash, never the raw secret. */
|
|
652
|
+
verificationKey(kind, credential) {
|
|
653
|
+
return createHash("sha256").update(`${kind}:${credential}`).digest("hex");
|
|
654
|
+
}
|
|
655
|
+
getCachedVerification(key) {
|
|
656
|
+
const entry = this.verifiedCredentials.get(key);
|
|
657
|
+
if (!entry) return null;
|
|
658
|
+
if (entry.expiresAt <= Date.now()) {
|
|
659
|
+
this.verifiedCredentials.delete(key);
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
return entry.user;
|
|
663
|
+
}
|
|
664
|
+
cacheVerification(key, user) {
|
|
665
|
+
this.verifiedCredentials.delete(key);
|
|
666
|
+
this.verifiedCredentials.set(key, { user, expiresAt: Date.now() + VERIFY_CACHE_TTL_MS });
|
|
667
|
+
if (this.verifiedCredentials.size > this.maxCachedVerifications) {
|
|
668
|
+
const oldest = this.verifiedCredentials.keys().next().value;
|
|
669
|
+
if (oldest !== void 0) this.verifiedCredentials.delete(oldest);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
636
672
|
/**
|
|
637
673
|
* Fetch the shared API's `/auth/me` and return the raw response body, or
|
|
638
674
|
* `null` on any non-OK / network error. Split out so `ensureOrganization`
|
|
@@ -641,7 +677,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
641
677
|
async fetchMe(sessionCookie) {
|
|
642
678
|
try {
|
|
643
679
|
const res = await fetch(`${this.sharedApiUrl}/auth/me`, {
|
|
644
|
-
headers: { Cookie: `${COOKIE_NAME}=${sessionCookie}` }
|
|
680
|
+
headers: { Cookie: `${COOKIE_NAME}=${sessionCookie}` },
|
|
681
|
+
signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
|
|
645
682
|
});
|
|
646
683
|
if (!res.ok) return null;
|
|
647
684
|
return await res.json();
|
|
@@ -654,11 +691,18 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
654
691
|
* to validate it and get user info.
|
|
655
692
|
*/
|
|
656
693
|
async verifySessionCookie(sessionCookie) {
|
|
694
|
+
const cacheKey = this.verificationKey("cookie", sessionCookie);
|
|
695
|
+
const cached = this.getCachedVerification(cacheKey);
|
|
696
|
+
if (cached) {
|
|
697
|
+
this.rememberUserSession(cached.id, sessionCookie);
|
|
698
|
+
return cached;
|
|
699
|
+
}
|
|
657
700
|
try {
|
|
658
701
|
const res = await fetch(`${this.sharedApiUrl}/auth/me`, {
|
|
659
702
|
headers: {
|
|
660
703
|
Cookie: `${COOKIE_NAME}=${sessionCookie}`
|
|
661
|
-
}
|
|
704
|
+
},
|
|
705
|
+
signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
|
|
662
706
|
});
|
|
663
707
|
if (!res.ok) {
|
|
664
708
|
this.logger.warn("verifySessionCookie: shared API returned non-OK status", {
|
|
@@ -670,7 +714,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
670
714
|
}
|
|
671
715
|
const data = await res.json();
|
|
672
716
|
this.rememberUserSession(data.user.id, sessionCookie);
|
|
673
|
-
|
|
717
|
+
const user = {
|
|
674
718
|
id: data.user.id,
|
|
675
719
|
email: data.user.email,
|
|
676
720
|
name: [data.user.firstName, data.user.lastName].filter(Boolean).join(" ") || void 0,
|
|
@@ -680,6 +724,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
680
724
|
permissions: data.permissions,
|
|
681
725
|
memberOrgIds: data.memberOrgIds
|
|
682
726
|
};
|
|
727
|
+
if (user.organizationId) this.cacheVerification(cacheKey, user);
|
|
728
|
+
return user;
|
|
683
729
|
} catch (error) {
|
|
684
730
|
this.logger.error("verifySessionCookie: fetch to shared API failed", {
|
|
685
731
|
url: `${this.sharedApiUrl}/auth/me`,
|
|
@@ -693,11 +739,15 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
693
739
|
* to validate it and get user info (used for CLI tokens).
|
|
694
740
|
*/
|
|
695
741
|
async verifyBearerToken(token) {
|
|
742
|
+
const cacheKey = this.verificationKey("bearer", token);
|
|
743
|
+
const cached = this.getCachedVerification(cacheKey);
|
|
744
|
+
if (cached) return cached;
|
|
696
745
|
try {
|
|
697
746
|
const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {
|
|
698
747
|
headers: {
|
|
699
748
|
Authorization: `Bearer ${token}`
|
|
700
|
-
}
|
|
749
|
+
},
|
|
750
|
+
signal: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS)
|
|
701
751
|
});
|
|
702
752
|
if (!res.ok) {
|
|
703
753
|
this.logger.warn("verifyBearerToken: shared API returned non-OK status", {
|
|
@@ -707,7 +757,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
707
757
|
return null;
|
|
708
758
|
}
|
|
709
759
|
const data = await res.json();
|
|
710
|
-
|
|
760
|
+
const user = {
|
|
711
761
|
id: data.user.id,
|
|
712
762
|
email: data.user.email,
|
|
713
763
|
name: [data.user.firstName, data.user.lastName].filter(Boolean).join(" ") || void 0,
|
|
@@ -715,6 +765,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
715
765
|
role: data.role,
|
|
716
766
|
memberOrgIds: data.memberOrgIds
|
|
717
767
|
};
|
|
768
|
+
if (user.organizationId) this.cacheVerification(cacheKey, user);
|
|
769
|
+
return user;
|
|
718
770
|
} catch (error) {
|
|
719
771
|
this.logger.error("verifyBearerToken: fetch to shared API failed", {
|
|
720
772
|
url: `${this.sharedApiUrl}/auth/verify`,
|