@mastra/auth-studio 1.1.0-alpha.0 → 1.2.0-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 +28 -0
- package/dist/index.cjs +17 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @mastra/auth-studio
|
|
2
2
|
|
|
3
|
+
## 1.2.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add configurable cookie domain support ([#14285](https://github.com/mastra-ai/mastra/pull/14285))
|
|
8
|
+
- Add `cookieDomain` option to `MastraAuthStudioOptions` for explicit configuration
|
|
9
|
+
- Support `MASTRA_COOKIE_DOMAIN` environment variable as fallback
|
|
10
|
+
- Use hostname-based detection for auto-detecting `.mastra.ai` domain (prevents false positives from malicious URLs)
|
|
11
|
+
- Maintain backward compatibility with existing `.mastra.ai` auto-detection
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`4444280`](https://github.com/mastra-ai/mastra/commit/444428094253e916ec077e66284e685fde67021e), [`dbb879a`](https://github.com/mastra-ai/mastra/commit/dbb879af0b809c668e9b3a9d8bac97d806caa267), [`8de3555`](https://github.com/mastra-ai/mastra/commit/8de355572c6fd838f863a3e7e6fe24d0947b774f)]:
|
|
16
|
+
- @mastra/core@1.14.0-alpha.2
|
|
17
|
+
|
|
18
|
+
## 1.1.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- Added `@mastra/auth-studio` — an auth provider for deployed Mastra Studio instances that proxies authentication through the Mastra shared API. ([#13163](https://github.com/mastra-ai/mastra/pull/13163))
|
|
23
|
+
|
|
24
|
+
Deployed instances need no secrets — all WorkOS authentication is handled by the shared API. The package provides SSO login/callback flows, session management via sealed cookies, RBAC with organization-scoped permissions, and automatic forced account picker on deploy logins.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`504fc8b`](https://github.com/mastra-ai/mastra/commit/504fc8b9d0ddab717577ad3bf9c95ea4bd5377bd), [`f9c150b`](https://github.com/mastra-ai/mastra/commit/f9c150b7595ad05ad9cc9a11098e2944361e8c22), [`88de7e8`](https://github.com/mastra-ai/mastra/commit/88de7e8dfe4b7e1951a9e441bb33136e705ce24e), [`edee4b3`](https://github.com/mastra-ai/mastra/commit/edee4b37dff0af515fc7cc0e8d71ee39e6a762f0), [`3790c75`](https://github.com/mastra-ai/mastra/commit/3790c7578cc6a47d854eb12d89e6b1912867fe29), [`e7a235b`](https://github.com/mastra-ai/mastra/commit/e7a235be6472e0c870ed6c791ddb17c492dc188b), [`d51d298`](https://github.com/mastra-ai/mastra/commit/d51d298953967aab1f58ec965b644d109214f085), [`6dbeeb9`](https://github.com/mastra-ai/mastra/commit/6dbeeb94a8b1eebb727300d1a98961f882180794), [`d5f0d8d`](https://github.com/mastra-ai/mastra/commit/d5f0d8d6a03e515ddaa9b5da19b7e44b8357b07b), [`09c3b18`](https://github.com/mastra-ai/mastra/commit/09c3b1802ff14e243a8a8baea327440bc8cc2e32), [`b896379`](https://github.com/mastra-ai/mastra/commit/b8963791c6afa79484645fcec596a201f936b9a2), [`85c84eb`](https://github.com/mastra-ai/mastra/commit/85c84ebb78aebfcba9d209c8e152b16d7a00cb71), [`a89272a`](https://github.com/mastra-ai/mastra/commit/a89272a5d71939b9fcd284e6a6dc1dd091a6bdcf), [`ee9c8df`](https://github.com/mastra-ai/mastra/commit/ee9c8df644f19d055af5f496bf4942705f5a47b7), [`77b4a25`](https://github.com/mastra-ai/mastra/commit/77b4a254e51907f8ff3a3ba95596a18e93ae4b35), [`276246e`](https://github.com/mastra-ai/mastra/commit/276246e0b9066a1ea48bbc70df84dbe528daaf99), [`08ecfdb`](https://github.com/mastra-ai/mastra/commit/08ecfdbdad6fb8285deef86a034bdf4a6047cfca), [`d5f628c`](https://github.com/mastra-ai/mastra/commit/d5f628ca86c6f6f3ff1035d52f635df32dd81cab), [`524c0f3`](https://github.com/mastra-ai/mastra/commit/524c0f3c434c3d9d18f66338dcef383d6161b59c), [`c18a0e9`](https://github.com/mastra-ai/mastra/commit/c18a0e9cef1e4ca004b2963d35e4cfc031971eac), [`4bd21ea`](https://github.com/mastra-ai/mastra/commit/4bd21ea43d44d0a0427414fc047577f9f0aa3bec), [`115a7a4`](https://github.com/mastra-ai/mastra/commit/115a7a47db5e9896fec12ae6507501adb9ec89bf), [`22a48ae`](https://github.com/mastra-ai/mastra/commit/22a48ae2513eb54d8d79dad361fddbca97a155e8), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9311c17`](https://github.com/mastra-ai/mastra/commit/9311c17d7a0640d9c4da2e71b814dc67c57c6369), [`7edf78f`](https://github.com/mastra-ai/mastra/commit/7edf78f80422c43e84585f08ba11df0d4d0b73c5), [`1c4221c`](https://github.com/mastra-ai/mastra/commit/1c4221cf6032ec98d0e094d4ee11da3e48490d96), [`d25b9ea`](https://github.com/mastra-ai/mastra/commit/d25b9eabd400167255a97b690ffbc4ee4097ded5), [`fe1ce5c`](https://github.com/mastra-ai/mastra/commit/fe1ce5c9211c03d561606fda95cbfe7df1d9a9b5), [`b03c0e0`](https://github.com/mastra-ai/mastra/commit/b03c0e0389a799523929a458b0509c9e4244d562), [`0a8366b`](https://github.com/mastra-ai/mastra/commit/0a8366b0a692fcdde56c4d526e4cf03c502ae4ac), [`85664e9`](https://github.com/mastra-ai/mastra/commit/85664e9fd857320fbc245e301f764f45f66f32a3), [`bc79650`](https://github.com/mastra-ai/mastra/commit/bc796500c6e0334faa158a96077e3fb332274869), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`3a3a59e`](https://github.com/mastra-ai/mastra/commit/3a3a59e8ffaa6a985fe3d9a126a3f5ade11a6724), [`3108d4e`](https://github.com/mastra-ai/mastra/commit/3108d4e649c9fddbf03253a6feeb388a5fa9fa5a), [`0c33b2c`](https://github.com/mastra-ai/mastra/commit/0c33b2c9db537f815e1c59e2c898ffce2e395a79), [`191e5bd`](https://github.com/mastra-ai/mastra/commit/191e5bd29b82f5bda35243945790da7bc7b695c2), [`f77cd94`](https://github.com/mastra-ai/mastra/commit/f77cd94c44eabed490384e7d19232a865e13214c), [`e8135c7`](https://github.com/mastra-ai/mastra/commit/e8135c7e300dac5040670eec7eab896ac6092e30), [`daca48f`](https://github.com/mastra-ai/mastra/commit/daca48f0fb17b7ae0b62a2ac40cf0e491b2fd0b7), [`257d14f`](https://github.com/mastra-ai/mastra/commit/257d14faca5931f2e4186fc165b6f0b1f915deee), [`352f25d`](https://github.com/mastra-ai/mastra/commit/352f25da316b24cdd5b410fd8dddf6a8b763da2a), [`93477d0`](https://github.com/mastra-ai/mastra/commit/93477d0769b8a13ea5ed73d508d967fb23eaeed9), [`31c78b3`](https://github.com/mastra-ai/mastra/commit/31c78b3eb28f58a8017f1dcc795c33214d87feac), [`0bc0720`](https://github.com/mastra-ai/mastra/commit/0bc07201095791858087cc56f353fcd65e87ab54), [`36516ac`](https://github.com/mastra-ai/mastra/commit/36516aca1021cbeb42e74751b46a2614101f37c8), [`e947652`](https://github.com/mastra-ai/mastra/commit/e9476527fdecb4449e54570e80dfaf8466901254), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`ec248f6`](https://github.com/mastra-ai/mastra/commit/ec248f6b56e8a037c066c49b2178e2507471d988)]:
|
|
29
|
+
- @mastra/core@1.9.0
|
|
30
|
+
|
|
3
31
|
## 1.1.0-alpha.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,7 @@ var MastraAuthStudio = class extends server.MastraAuthProvider {
|
|
|
10
10
|
sharedApiUrl;
|
|
11
11
|
organizationId;
|
|
12
12
|
useProductionCookies;
|
|
13
|
+
cookieDomain;
|
|
13
14
|
constructor(options) {
|
|
14
15
|
super({ name: "mastra-studio", ...options });
|
|
15
16
|
this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || "http://localhost:3010/v1";
|
|
@@ -17,7 +18,18 @@ var MastraAuthStudio = class extends server.MastraAuthProvider {
|
|
|
17
18
|
if (this.sharedApiUrl.endsWith("/")) {
|
|
18
19
|
this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);
|
|
19
20
|
}
|
|
20
|
-
this.
|
|
21
|
+
this.cookieDomain = options?.cookieDomain || process.env.MASTRA_COOKIE_DOMAIN;
|
|
22
|
+
let autoDetectMastraAi = false;
|
|
23
|
+
try {
|
|
24
|
+
const hostname = new URL(this.sharedApiUrl).hostname.toLowerCase();
|
|
25
|
+
autoDetectMastraAi = hostname === "mastra.ai" || hostname.endsWith(".mastra.ai");
|
|
26
|
+
} catch {
|
|
27
|
+
autoDetectMastraAi = false;
|
|
28
|
+
}
|
|
29
|
+
this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;
|
|
30
|
+
if (!this.cookieDomain && autoDetectMastraAi) {
|
|
31
|
+
this.cookieDomain = ".mastra.ai";
|
|
32
|
+
}
|
|
21
33
|
if (options) {
|
|
22
34
|
this.registerOptions(options);
|
|
23
35
|
}
|
|
@@ -160,17 +172,17 @@ var MastraAuthStudio = class extends server.MastraAuthProvider {
|
|
|
160
172
|
}
|
|
161
173
|
getSessionHeaders(session) {
|
|
162
174
|
const parts = [`${COOKIE_NAME}=${session.id}`, "HttpOnly", "SameSite=Lax", "Path=/", "Max-Age=86400"];
|
|
163
|
-
if (this.useProductionCookies) {
|
|
175
|
+
if (this.useProductionCookies && this.cookieDomain) {
|
|
164
176
|
parts.push("Secure");
|
|
165
|
-
parts.push(
|
|
177
|
+
parts.push(`Domain=${this.cookieDomain}`);
|
|
166
178
|
}
|
|
167
179
|
return { "Set-Cookie": parts.join("; ") };
|
|
168
180
|
}
|
|
169
181
|
getClearSessionHeaders() {
|
|
170
182
|
const parts = [`${COOKIE_NAME}=`, "HttpOnly", "SameSite=Lax", "Path=/", "Max-Age=0"];
|
|
171
|
-
if (this.useProductionCookies) {
|
|
183
|
+
if (this.useProductionCookies && this.cookieDomain) {
|
|
172
184
|
parts.push("Secure");
|
|
173
|
-
parts.push(
|
|
185
|
+
parts.push(`Domain=${this.cookieDomain}`);
|
|
174
186
|
}
|
|
175
187
|
return { "Set-Cookie": parts.join("; ") };
|
|
176
188
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["MastraAuthProvider","resolvePermissionsFromMapping","matchesPermission"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ISSOProvider,\n ISessionProvider,\n IUserProvider,\n Session,\n SSOCallbackResult,\n SSOLoginConfig,\n} from '@mastra/core/auth';\nimport type { EEUser, IRBACProvider, RoleMapping } from '@mastra/core/auth/ee';\nimport { resolvePermissionsFromMapping, matchesPermission } from '@mastra/core/auth/ee';\nimport { MastraAuthProvider } from '@mastra/core/server';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\n\nexport interface StudioUser extends EEUser {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n organizationId?: string;\n role?: string;\n permissions?: string[];\n}\n\nexport interface MastraAuthStudioOptions extends MastraAuthProviderOptions<StudioUser> {\n /** Base URL of the Mastra shared API (e.g., https://api.mastra.ai/v1) */\n sharedApiUrl?: string;\n /** Organization ID that owns this deployed instance. Users not in this org are rejected. */\n organizationId?: string;\n}\n\nconst COOKIE_NAME = 'wos-session';\n\n/**\n * Auth provider for Mastra Studio deployed instances.\n *\n * Proxies all authentication through the shared API, keeping the\n * WorkOS API key safely in the shared API. Deployed instances only\n * need the shared API URL — no secrets required.\n *\n * The shared API's sealed session cookie (`wos-session`) is set with\n * `Domain=.mastra.ai` in production, so it's included in requests\n * to deployed instances and can be forwarded for validation.\n */\nexport class MastraAuthStudio\n extends MastraAuthProvider<StudioUser>\n implements ISSOProvider<StudioUser>, ISessionProvider<Session>, IUserProvider<StudioUser>\n{\n readonly isMastraCloudAuth = true;\n\n private sharedApiUrl: string;\n private organizationId: string | undefined;\n private useProductionCookies: boolean;\n\n constructor(options?: MastraAuthStudioOptions) {\n super({ name: 'mastra-studio', ...options });\n this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || 'http://localhost:3010/v1';\n this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID;\n\n // Strip trailing slash\n if (this.sharedApiUrl.endsWith('/')) {\n this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);\n }\n\n // Use production cookie settings (Secure + Domain=.mastra.ai) only when\n // the shared API is actually on .mastra.ai — NOT based on NODE_ENV which\n // may be 'production' even in local dev (e.g. mastra dev sets it).\n this.useProductionCookies = this.sharedApiUrl.includes('.mastra.ai');\n\n if (options) {\n this.registerOptions(options);\n }\n }\n\n // ---------------------------------------------------------------------------\n // MastraAuthProvider abstract methods\n // ---------------------------------------------------------------------------\n\n /**\n * Authenticate an incoming request by forwarding the sealed session cookie\n * to the shared API's /auth/me endpoint, or a Bearer token to /auth/verify.\n */\n async authenticateToken(token: string, request: any): Promise<StudioUser | null> {\n let user: StudioUser | null = null;\n\n // Try sealed session cookie first (browser flow)\n const cookieHeader = request?.headers?.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n user = await this.verifySessionCookie(sessionCookie);\n }\n\n // Fall back to Bearer token (CLI / API token flow)\n if (!user && token) {\n user = await this.verifyBearerToken(token);\n }\n\n if (!user) return null;\n\n // Org-scoping: if this instance belongs to a specific org, reject users not in that org\n if (this.organizationId && user.organizationId !== this.organizationId) {\n return null;\n }\n\n return user;\n }\n\n authorizeUser(user: StudioUser): boolean {\n return !!user?.id;\n }\n\n // ---------------------------------------------------------------------------\n // ISSOProvider\n // ---------------------------------------------------------------------------\n\n getLoginUrl(redirectUri: string, state: string): string {\n // Extract the post-login redirect from state (format: uuid|encodedPostLoginRedirect)\n let postLoginRedirect = '/';\n if (state) {\n const pipeIndex = state.indexOf('|');\n if (pipeIndex !== -1) {\n try {\n postLoginRedirect = decodeURIComponent(state.slice(pipeIndex + 1));\n } catch {\n // ignore decode errors\n }\n }\n }\n\n const params = new URLSearchParams({\n product: 'deploy',\n redirect_uri: redirectUri,\n post_login_redirect: postLoginRedirect,\n // Force re-authentication so AuthKit always shows the account picker\n prompt: 'login',\n ...(this.organizationId ? { organization_id: this.organizationId } : {}),\n });\n\n return `${this.sharedApiUrl}/auth/login?${params.toString()}`;\n }\n\n async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {\n // The shared API already consumed the OAuth code and passes the sealed\n // session directly as the `code` parameter in the redirect to this callback.\n // Validate it to get user info.\n const user = await this.verifySessionCookie(code);\n if (!user) {\n throw new Error('Session validation failed');\n }\n\n // Omit `cookies` so the Mastra server fallback path calls\n // createSession() + getSessionHeaders() to build a cookie scoped to\n // the deployed instance's domain.\n return {\n user,\n tokens: {\n accessToken: code,\n },\n };\n }\n\n setCallbackCookieHeader(_cookieHeader: string | null): void {\n // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow\n }\n\n getLoginCookies(): string[] | undefined {\n // No PKCE cookies needed — shared API manages the OAuth state\n return undefined;\n }\n\n getLoginButtonConfig(): SSOLoginConfig {\n return {\n provider: 'mastra-studio',\n text: 'Sign in with Mastra',\n };\n }\n\n async getLogoutUrl(_redirectUri: string, request?: Request): Promise<string | null> {\n const cookieHeader = request?.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (!sessionCookie) return null;\n\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (res.ok) {\n const data = (await res.json()) as { ok: boolean; logoutUrl?: string };\n return data.logoutUrl ?? null;\n }\n } catch {\n // Failed to get logout URL — return null\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // ISessionProvider\n // ---------------------------------------------------------------------------\n\n async createSession(userId: string, metadata?: Record<string, unknown>): Promise<Session> {\n const now = new Date();\n return {\n id: (metadata?.accessToken as string) || crypto.randomUUID(),\n userId,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000), // 24 hours\n createdAt: now,\n metadata,\n };\n }\n\n async validateSession(sessionId: string): Promise<Session | null> {\n const user = await this.verifySessionCookie(sessionId);\n if (!user) return null;\n\n const now = new Date();\n return {\n id: sessionId,\n userId: user.id,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000),\n createdAt: now,\n };\n }\n\n async destroySession(sessionId: string): Promise<void> {\n try {\n await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionId}`,\n },\n });\n } catch {\n // Best effort\n }\n }\n\n async refreshSession(sessionId: string): Promise<Session | null> {\n return this.validateSession(sessionId);\n }\n\n getSessionIdFromRequest(request: Request): string | null {\n const cookieHeader = request.headers.get('Cookie');\n return parseCookie(cookieHeader, COOKIE_NAME);\n }\n\n getSessionHeaders(session: Session): Record<string, string> {\n const parts = [`${COOKIE_NAME}=${session.id}`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=86400'];\n if (this.useProductionCookies) {\n parts.push('Secure');\n parts.push('Domain=.mastra.ai');\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n getClearSessionHeaders(): Record<string, string> {\n const parts = [`${COOKIE_NAME}=`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=0'];\n if (this.useProductionCookies) {\n parts.push('Secure');\n parts.push('Domain=.mastra.ai');\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n // ---------------------------------------------------------------------------\n // IUserProvider\n // ---------------------------------------------------------------------------\n\n async getCurrentUser(request: Request): Promise<StudioUser | null> {\n const cookieHeader = request.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n return this.verifySessionCookie(sessionCookie);\n }\n\n // Try bearer token\n const authHeader = request.headers.get('Authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return this.verifyBearerToken(authHeader.slice(7));\n }\n\n return null;\n }\n\n async getUser(_userId: string): Promise<StudioUser | null> {\n // Cannot look up users by ID — only validate sessions\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Forward a sealed session cookie to the shared API's /auth/me endpoint\n * to validate it and get user info.\n */\n private async verifySessionCookie(sessionCookie: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/me`, {\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n profilePictureUrl?: string;\n };\n organizationId: string;\n role?: string;\n permissions?: string[];\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n avatarUrl: data.user.profilePictureUrl,\n organizationId: data.organizationId,\n role: data.role,\n permissions: data.permissions,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Forward a Bearer token to the shared API's /auth/verify endpoint\n * to validate it and get user info (used for CLI tokens).\n */\n private async verifyBearerToken(token: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n };\n organizationId: string;\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n organizationId: data.organizationId,\n };\n } catch {\n return null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cookie helpers\n// ---------------------------------------------------------------------------\n\nfunction parseCookie(cookieHeader: string | null | undefined, name: string): string | null {\n if (!cookieHeader) return null;\n const match = cookieHeader.match(new RegExp(`${name}=([^;]+)`));\n return match?.[1] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// MastraRBACStudio — role-based permission provider for Studio auth\n// ---------------------------------------------------------------------------\n\nexport interface MastraRBACStudioOptions {\n /**\n * Mapping from role names to permission arrays.\n *\n * @example\n * ```typescript\n * {\n * admin: ['*'],\n * member: ['agents:read', 'workflows:*'],\n * viewer: ['agents:read', 'workflows:read'],\n * _default: [],\n * }\n * ```\n */\n roleMapping: RoleMapping;\n}\n\n/**\n * RBAC provider for Mastra Studio authentication.\n *\n * Maps user roles (from the shared API's /auth/me endpoint) to Mastra permissions\n * using a configurable role mapping.\n */\nexport class MastraRBACStudio implements IRBACProvider<StudioUser> {\n private options: MastraRBACStudioOptions;\n\n get roleMapping(): RoleMapping {\n return this.options.roleMapping;\n }\n\n constructor(options: MastraRBACStudioOptions) {\n this.options = options;\n }\n\n async getRoles(user: StudioUser): Promise<string[]> {\n return user.role ? [user.role] : [];\n }\n\n async hasRole(user: StudioUser, role: string): Promise<boolean> {\n const roles = await this.getRoles(user);\n return roles.includes(role);\n }\n\n async getPermissions(user: StudioUser): Promise<string[]> {\n const roles = await this.getRoles(user);\n if (roles.length === 0) {\n return this.options.roleMapping['_default'] ?? [];\n }\n return resolvePermissionsFromMapping(roles, this.options.roleMapping);\n }\n\n async hasPermission(user: StudioUser, permission: string): Promise<boolean> {\n const permissions = await this.getPermissions(user);\n return permissions.some(p => matchesPermission(p, permission));\n }\n\n async hasAllPermissions(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.every(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n\n async hasAnyPermission(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.some(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["MastraAuthProvider","resolvePermissionsFromMapping","matchesPermission"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ISSOProvider,\n ISessionProvider,\n IUserProvider,\n Session,\n SSOCallbackResult,\n SSOLoginConfig,\n} from '@mastra/core/auth';\nimport type { EEUser, IRBACProvider, RoleMapping } from '@mastra/core/auth/ee';\nimport { resolvePermissionsFromMapping, matchesPermission } from '@mastra/core/auth/ee';\nimport { MastraAuthProvider } from '@mastra/core/server';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\n\nexport interface StudioUser extends EEUser {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n organizationId?: string;\n role?: string;\n permissions?: string[];\n}\n\nexport interface MastraAuthStudioOptions extends MastraAuthProviderOptions<StudioUser> {\n /** Base URL of the Mastra shared API (e.g., https://api.mastra.ai/v1) */\n sharedApiUrl?: string;\n /** Organization ID that owns this deployed instance. Users not in this org are rejected. */\n organizationId?: string;\n /**\n * Cookie domain for session cookies (e.g., '.example.com').\n * When set, cookies will include Secure and Domain attributes.\n * Defaults to auto-detecting from sharedApiUrl (uses '.mastra.ai' when sharedApiUrl contains '.mastra.ai').\n * Can also be set via MASTRA_COOKIE_DOMAIN environment variable.\n */\n cookieDomain?: string;\n}\n\nconst COOKIE_NAME = 'wos-session';\n\n/**\n * Auth provider for Mastra Studio deployed instances.\n *\n * Proxies all authentication through the shared API, keeping the\n * WorkOS API key safely in the shared API. Deployed instances only\n * need the shared API URL — no secrets required.\n *\n * The shared API's sealed session cookie (`wos-session`) is set with\n * `Domain=.mastra.ai` in production, so it's included in requests\n * to deployed instances and can be forwarded for validation.\n */\nexport class MastraAuthStudio\n extends MastraAuthProvider<StudioUser>\n implements ISSOProvider<StudioUser>, ISessionProvider<Session>, IUserProvider<StudioUser>\n{\n readonly isMastraCloudAuth = true;\n\n private sharedApiUrl: string;\n private organizationId: string | undefined;\n private useProductionCookies: boolean;\n private cookieDomain: string | undefined;\n\n constructor(options?: MastraAuthStudioOptions) {\n super({ name: 'mastra-studio', ...options });\n this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || 'http://localhost:3010/v1';\n this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID;\n\n // Strip trailing slash\n if (this.sharedApiUrl.endsWith('/')) {\n this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);\n }\n\n // Cookie domain can be explicitly configured, read from env, or auto-detected from sharedApiUrl\n this.cookieDomain = options?.cookieDomain || process.env.MASTRA_COOKIE_DOMAIN;\n\n // Use production cookie settings (Secure + Domain) when:\n // 1. An explicit cookieDomain is configured, OR\n // 2. The shared API is on .mastra.ai (auto-detect default domain)\n // Use hostname-based detection to avoid false positives (e.g., api.mastra.ai.evil.com)\n let autoDetectMastraAi = false;\n try {\n const hostname = new URL(this.sharedApiUrl).hostname.toLowerCase();\n autoDetectMastraAi = hostname === 'mastra.ai' || hostname.endsWith('.mastra.ai');\n } catch {\n autoDetectMastraAi = false;\n }\n this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;\n\n // If no explicit domain but we're on .mastra.ai, use the default domain\n if (!this.cookieDomain && autoDetectMastraAi) {\n this.cookieDomain = '.mastra.ai';\n }\n\n if (options) {\n this.registerOptions(options);\n }\n }\n\n // ---------------------------------------------------------------------------\n // MastraAuthProvider abstract methods\n // ---------------------------------------------------------------------------\n\n /**\n * Authenticate an incoming request by forwarding the sealed session cookie\n * to the shared API's /auth/me endpoint, or a Bearer token to /auth/verify.\n */\n async authenticateToken(token: string, request: any): Promise<StudioUser | null> {\n let user: StudioUser | null = null;\n\n // Try sealed session cookie first (browser flow)\n const cookieHeader = request?.headers?.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n user = await this.verifySessionCookie(sessionCookie);\n }\n\n // Fall back to Bearer token (CLI / API token flow)\n if (!user && token) {\n user = await this.verifyBearerToken(token);\n }\n\n if (!user) return null;\n\n // Org-scoping: if this instance belongs to a specific org, reject users not in that org\n if (this.organizationId && user.organizationId !== this.organizationId) {\n return null;\n }\n\n return user;\n }\n\n authorizeUser(user: StudioUser): boolean {\n return !!user?.id;\n }\n\n // ---------------------------------------------------------------------------\n // ISSOProvider\n // ---------------------------------------------------------------------------\n\n getLoginUrl(redirectUri: string, state: string): string {\n // Extract the post-login redirect from state (format: uuid|encodedPostLoginRedirect)\n let postLoginRedirect = '/';\n if (state) {\n const pipeIndex = state.indexOf('|');\n if (pipeIndex !== -1) {\n try {\n postLoginRedirect = decodeURIComponent(state.slice(pipeIndex + 1));\n } catch {\n // ignore decode errors\n }\n }\n }\n\n const params = new URLSearchParams({\n product: 'deploy',\n redirect_uri: redirectUri,\n post_login_redirect: postLoginRedirect,\n // Force re-authentication so AuthKit always shows the account picker\n prompt: 'login',\n ...(this.organizationId ? { organization_id: this.organizationId } : {}),\n });\n\n return `${this.sharedApiUrl}/auth/login?${params.toString()}`;\n }\n\n async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {\n // The shared API already consumed the OAuth code and passes the sealed\n // session directly as the `code` parameter in the redirect to this callback.\n // Validate it to get user info.\n const user = await this.verifySessionCookie(code);\n if (!user) {\n throw new Error('Session validation failed');\n }\n\n // Omit `cookies` so the Mastra server fallback path calls\n // createSession() + getSessionHeaders() to build a cookie scoped to\n // the deployed instance's domain.\n return {\n user,\n tokens: {\n accessToken: code,\n },\n };\n }\n\n setCallbackCookieHeader(_cookieHeader: string | null): void {\n // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow\n }\n\n getLoginCookies(): string[] | undefined {\n // No PKCE cookies needed — shared API manages the OAuth state\n return undefined;\n }\n\n getLoginButtonConfig(): SSOLoginConfig {\n return {\n provider: 'mastra-studio',\n text: 'Sign in with Mastra',\n };\n }\n\n async getLogoutUrl(_redirectUri: string, request?: Request): Promise<string | null> {\n const cookieHeader = request?.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (!sessionCookie) return null;\n\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (res.ok) {\n const data = (await res.json()) as { ok: boolean; logoutUrl?: string };\n return data.logoutUrl ?? null;\n }\n } catch {\n // Failed to get logout URL — return null\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // ISessionProvider\n // ---------------------------------------------------------------------------\n\n async createSession(userId: string, metadata?: Record<string, unknown>): Promise<Session> {\n const now = new Date();\n return {\n id: (metadata?.accessToken as string) || crypto.randomUUID(),\n userId,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000), // 24 hours\n createdAt: now,\n metadata,\n };\n }\n\n async validateSession(sessionId: string): Promise<Session | null> {\n const user = await this.verifySessionCookie(sessionId);\n if (!user) return null;\n\n const now = new Date();\n return {\n id: sessionId,\n userId: user.id,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000),\n createdAt: now,\n };\n }\n\n async destroySession(sessionId: string): Promise<void> {\n try {\n await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionId}`,\n },\n });\n } catch {\n // Best effort\n }\n }\n\n async refreshSession(sessionId: string): Promise<Session | null> {\n return this.validateSession(sessionId);\n }\n\n getSessionIdFromRequest(request: Request): string | null {\n const cookieHeader = request.headers.get('Cookie');\n return parseCookie(cookieHeader, COOKIE_NAME);\n }\n\n getSessionHeaders(session: Session): Record<string, string> {\n const parts = [`${COOKIE_NAME}=${session.id}`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=86400'];\n if (this.useProductionCookies && this.cookieDomain) {\n parts.push('Secure');\n parts.push(`Domain=${this.cookieDomain}`);\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n getClearSessionHeaders(): Record<string, string> {\n const parts = [`${COOKIE_NAME}=`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=0'];\n if (this.useProductionCookies && this.cookieDomain) {\n parts.push('Secure');\n parts.push(`Domain=${this.cookieDomain}`);\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n // ---------------------------------------------------------------------------\n // IUserProvider\n // ---------------------------------------------------------------------------\n\n async getCurrentUser(request: Request): Promise<StudioUser | null> {\n const cookieHeader = request.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n return this.verifySessionCookie(sessionCookie);\n }\n\n // Try bearer token\n const authHeader = request.headers.get('Authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return this.verifyBearerToken(authHeader.slice(7));\n }\n\n return null;\n }\n\n async getUser(_userId: string): Promise<StudioUser | null> {\n // Cannot look up users by ID — only validate sessions\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Forward a sealed session cookie to the shared API's /auth/me endpoint\n * to validate it and get user info.\n */\n private async verifySessionCookie(sessionCookie: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/me`, {\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n profilePictureUrl?: string;\n };\n organizationId: string;\n role?: string;\n permissions?: string[];\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n avatarUrl: data.user.profilePictureUrl,\n organizationId: data.organizationId,\n role: data.role,\n permissions: data.permissions,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Forward a Bearer token to the shared API's /auth/verify endpoint\n * to validate it and get user info (used for CLI tokens).\n */\n private async verifyBearerToken(token: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n };\n organizationId: string;\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n organizationId: data.organizationId,\n };\n } catch {\n return null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cookie helpers\n// ---------------------------------------------------------------------------\n\nfunction parseCookie(cookieHeader: string | null | undefined, name: string): string | null {\n if (!cookieHeader) return null;\n const match = cookieHeader.match(new RegExp(`${name}=([^;]+)`));\n return match?.[1] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// MastraRBACStudio — role-based permission provider for Studio auth\n// ---------------------------------------------------------------------------\n\nexport interface MastraRBACStudioOptions {\n /**\n * Mapping from role names to permission arrays.\n *\n * @example\n * ```typescript\n * {\n * admin: ['*'],\n * member: ['agents:read', 'workflows:*'],\n * viewer: ['agents:read', 'workflows:read'],\n * _default: [],\n * }\n * ```\n */\n roleMapping: RoleMapping;\n}\n\n/**\n * RBAC provider for Mastra Studio authentication.\n *\n * Maps user roles (from the shared API's /auth/me endpoint) to Mastra permissions\n * using a configurable role mapping.\n */\nexport class MastraRBACStudio implements IRBACProvider<StudioUser> {\n private options: MastraRBACStudioOptions;\n\n get roleMapping(): RoleMapping {\n return this.options.roleMapping;\n }\n\n constructor(options: MastraRBACStudioOptions) {\n this.options = options;\n }\n\n async getRoles(user: StudioUser): Promise<string[]> {\n return user.role ? [user.role] : [];\n }\n\n async hasRole(user: StudioUser, role: string): Promise<boolean> {\n const roles = await this.getRoles(user);\n return roles.includes(role);\n }\n\n async getPermissions(user: StudioUser): Promise<string[]> {\n const roles = await this.getRoles(user);\n if (roles.length === 0) {\n return this.options.roleMapping['_default'] ?? [];\n }\n return resolvePermissionsFromMapping(roles, this.options.roleMapping);\n }\n\n async hasPermission(user: StudioUser, permission: string): Promise<boolean> {\n const permissions = await this.getPermissions(user);\n return permissions.some(p => matchesPermission(p, permission));\n }\n\n async hasAllPermissions(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.every(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n\n async hasAnyPermission(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.some(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,13 @@ export interface MastraAuthStudioOptions extends MastraAuthProviderOptions<Studi
|
|
|
16
16
|
sharedApiUrl?: string;
|
|
17
17
|
/** Organization ID that owns this deployed instance. Users not in this org are rejected. */
|
|
18
18
|
organizationId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Cookie domain for session cookies (e.g., '.example.com').
|
|
21
|
+
* When set, cookies will include Secure and Domain attributes.
|
|
22
|
+
* Defaults to auto-detecting from sharedApiUrl (uses '.mastra.ai' when sharedApiUrl contains '.mastra.ai').
|
|
23
|
+
* Can also be set via MASTRA_COOKIE_DOMAIN environment variable.
|
|
24
|
+
*/
|
|
25
|
+
cookieDomain?: string;
|
|
19
26
|
}
|
|
20
27
|
/**
|
|
21
28
|
* Auth provider for Mastra Studio deployed instances.
|
|
@@ -33,6 +40,7 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
|
|
|
33
40
|
private sharedApiUrl;
|
|
34
41
|
private organizationId;
|
|
35
42
|
private useProductionCookies;
|
|
43
|
+
private cookieDomain;
|
|
36
44
|
constructor(options?: MastraAuthStudioOptions);
|
|
37
45
|
/**
|
|
38
46
|
* Authenticate an incoming request by forwarding the sealed session cookie
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAErE,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,uBAAwB,SAAQ,yBAAyB,CAAC,UAAU,CAAC;IACpF,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
8
8
|
sharedApiUrl;
|
|
9
9
|
organizationId;
|
|
10
10
|
useProductionCookies;
|
|
11
|
+
cookieDomain;
|
|
11
12
|
constructor(options) {
|
|
12
13
|
super({ name: "mastra-studio", ...options });
|
|
13
14
|
this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || "http://localhost:3010/v1";
|
|
@@ -15,7 +16,18 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
15
16
|
if (this.sharedApiUrl.endsWith("/")) {
|
|
16
17
|
this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);
|
|
17
18
|
}
|
|
18
|
-
this.
|
|
19
|
+
this.cookieDomain = options?.cookieDomain || process.env.MASTRA_COOKIE_DOMAIN;
|
|
20
|
+
let autoDetectMastraAi = false;
|
|
21
|
+
try {
|
|
22
|
+
const hostname = new URL(this.sharedApiUrl).hostname.toLowerCase();
|
|
23
|
+
autoDetectMastraAi = hostname === "mastra.ai" || hostname.endsWith(".mastra.ai");
|
|
24
|
+
} catch {
|
|
25
|
+
autoDetectMastraAi = false;
|
|
26
|
+
}
|
|
27
|
+
this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;
|
|
28
|
+
if (!this.cookieDomain && autoDetectMastraAi) {
|
|
29
|
+
this.cookieDomain = ".mastra.ai";
|
|
30
|
+
}
|
|
19
31
|
if (options) {
|
|
20
32
|
this.registerOptions(options);
|
|
21
33
|
}
|
|
@@ -158,17 +170,17 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
158
170
|
}
|
|
159
171
|
getSessionHeaders(session) {
|
|
160
172
|
const parts = [`${COOKIE_NAME}=${session.id}`, "HttpOnly", "SameSite=Lax", "Path=/", "Max-Age=86400"];
|
|
161
|
-
if (this.useProductionCookies) {
|
|
173
|
+
if (this.useProductionCookies && this.cookieDomain) {
|
|
162
174
|
parts.push("Secure");
|
|
163
|
-
parts.push(
|
|
175
|
+
parts.push(`Domain=${this.cookieDomain}`);
|
|
164
176
|
}
|
|
165
177
|
return { "Set-Cookie": parts.join("; ") };
|
|
166
178
|
}
|
|
167
179
|
getClearSessionHeaders() {
|
|
168
180
|
const parts = [`${COOKIE_NAME}=`, "HttpOnly", "SameSite=Lax", "Path=/", "Max-Age=0"];
|
|
169
|
-
if (this.useProductionCookies) {
|
|
181
|
+
if (this.useProductionCookies && this.cookieDomain) {
|
|
170
182
|
parts.push("Secure");
|
|
171
|
-
parts.push(
|
|
183
|
+
parts.push(`Domain=${this.cookieDomain}`);
|
|
172
184
|
}
|
|
173
185
|
return { "Set-Cookie": parts.join("; ") };
|
|
174
186
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;AA8BA,IAAM,WAAA,GAAc,aAAA;AAab,IAAM,gBAAA,GAAN,cACG,kBAAA,CAEV;AAAA,EACW,iBAAA,GAAoB,IAAA;AAAA,EAErB,YAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EAER,YAAY,OAAA,EAAmC;AAC7C,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,GAAG,SAAS,CAAA;AAC3C,IAAA,IAAA,CAAK,YAAA,GAAe,OAAA,EAAS,YAAA,IAAgB,OAAA,CAAQ,IAAI,qBAAA,IAAyB,0BAAA;AAClF,IAAA,IAAA,CAAK,cAAA,GAAiB,OAAA,EAAS,cAAA,IAAkB,OAAA,CAAQ,GAAA,CAAI,sBAAA;AAG7D,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,GAAG,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,YAAA,CAAa,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,IACnD;AAKA,IAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,YAAY,CAAA;AAEnE,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAA,CAAK,gBAAgB,OAAO,CAAA;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBAAA,CAAkB,KAAA,EAAe,OAAA,EAA0C;AAC/E,IAAA,IAAI,IAAA,GAA0B,IAAA;AAG9B,IAAA,MAAM,YAAA,GAAe,OAAA,EAAS,OAAA,EAAS,GAAA,CAAI,QAAQ,CAAA;AACnD,IAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,YAAA,EAAc,WAAW,CAAA;AAE3D,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,mBAAA,CAAoB,aAAa,CAAA;AAAA,IACrD;AAGA,IAAA,IAAI,CAAC,QAAQ,KAAA,EAAO;AAClB,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,iBAAA,CAAkB,KAAK,CAAA;AAAA,IAC3C;AAEA,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAGlB,IAAA,IAAI,IAAA,CAAK,cAAA,IAAkB,IAAA,CAAK,cAAA,KAAmB,KAAK,cAAA,EAAgB;AACtE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,cAAc,IAAA,EAA2B;AACvC,IAAA,OAAO,CAAC,CAAC,IAAA,EAAM,EAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,CAAY,aAAqB,KAAA,EAAuB;AAEtD,IAAA,IAAI,iBAAA,GAAoB,GAAA;AACxB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AACnC,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,IAAI;AACF,UAAA,iBAAA,GAAoB,kBAAA,CAAmB,KAAA,CAAM,KAAA,CAAM,SAAA,GAAY,CAAC,CAAC,CAAA;AAAA,QACnE,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB;AAAA,MACjC,OAAA,EAAS,QAAA;AAAA,MACT,YAAA,EAAc,WAAA;AAAA,MACd,mBAAA,EAAqB,iBAAA;AAAA;AAAA,MAErB,MAAA,EAAQ,OAAA;AAAA,MACR,GAAI,KAAK,cAAA,GAAiB,EAAE,iBAAiB,IAAA,CAAK,cAAA,KAAmB;AAAC,KACvE,CAAA;AAED,IAAA,OAAO,GAAG,IAAA,CAAK,YAAY,CAAA,YAAA,EAAe,MAAA,CAAO,UAAU,CAAA,CAAA;AAAA,EAC7D;AAAA,EAEA,MAAM,cAAA,CAAe,IAAA,EAAc,MAAA,EAAwD;AAIzF,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,mBAAA,CAAoB,IAAI,CAAA;AAChD,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AAKA,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,WAAA,EAAa;AAAA;AACf,KACF;AAAA,EACF;AAAA,EAEA,wBAAwB,aAAA,EAAoC;AAAA,EAE5D;AAAA,EAEA,eAAA,GAAwC;AAEtC,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,oBAAA,GAAuC;AACrC,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,eAAA;AAAA,MACV,IAAA,EAAM;AAAA,KACR;AAAA,EACF;AAAA,EAEA,MAAM,YAAA,CAAa,YAAA,EAAsB,OAAA,EAA2C;AAClF,IAAA,MAAM,YAAA,GAAe,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAClD,IAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,YAAA,EAAc,WAAW,CAAA;AAE3D,IAAA,IAAI,CAAC,eAAe,OAAO,IAAA;AAE3B,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,YAAY,CAAA,YAAA,CAAA,EAAgB;AAAA,QAC1D,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,MAAA,EAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,aAAa,CAAA;AAAA;AACzC,OACD,CAAA;AAED,MAAA,IAAI,IAAI,EAAA,EAAI;AACV,QAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,QAAA,OAAO,KAAK,SAAA,IAAa,IAAA;AAAA,MAC3B;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAA,CAAc,MAAA,EAAgB,QAAA,EAAsD;AACxF,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,IAAA,OAAO;AAAA,MACL,EAAA,EAAK,QAAA,EAAU,WAAA,IAA0B,MAAA,CAAO,UAAA,EAAW;AAAA,MAC3D,MAAA;AAAA,MACA,SAAA,EAAW,IAAI,IAAA,CAAK,GAAA,CAAI,SAAQ,GAAI,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAI,CAAA;AAAA;AAAA,MACvD,SAAA,EAAW,GAAA;AAAA,MACX;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,SAAA,EAA4C;AAChE,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,mBAAA,CAAoB,SAAS,CAAA;AACrD,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,SAAA,EAAW,IAAI,IAAA,CAAK,GAAA,CAAI,SAAQ,GAAI,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAI,CAAA;AAAA,MACvD,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAA,EAAkC;AACrD,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,YAAY,CAAA,YAAA,CAAA,EAAgB;AAAA,QAC9C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,MAAA,EAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,SAAS,CAAA;AAAA;AACrC,OACD,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAA,EAA4C;AAC/D,IAAA,OAAO,IAAA,CAAK,gBAAgB,SAAS,CAAA;AAAA,EACvC;AAAA,EAEA,wBAAwB,OAAA,EAAiC;AACvD,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AACjD,IAAA,OAAO,WAAA,CAAY,cAAc,WAAW,CAAA;AAAA,EAC9C;AAAA,EAEA,kBAAkB,OAAA,EAA0C;AAC1D,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,OAAA,CAAQ,EAAE,CAAA,CAAA,EAAI,UAAA,EAAY,cAAA,EAAgB,QAAA,EAAU,eAAe,CAAA;AACpG,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,KAAA,CAAM,KAAK,QAAQ,CAAA;AACnB,MAAA,KAAA,CAAM,KAAK,mBAAmB,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,EAAE,YAAA,EAAc,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAE;AAAA,EAC1C;AAAA,EAEA,sBAAA,GAAiD;AAC/C,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,WAAW,KAAK,UAAA,EAAY,cAAA,EAAgB,UAAU,WAAW,CAAA;AACnF,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,KAAA,CAAM,KAAK,QAAQ,CAAA;AACnB,MAAA,KAAA,CAAM,KAAK,mBAAmB,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,EAAE,YAAA,EAAc,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAE;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAe,OAAA,EAA8C;AACjE,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AACjD,IAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,YAAA,EAAc,WAAW,CAAA;AAE3D,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAO,IAAA,CAAK,oBAAoB,aAAa,CAAA;AAAA,IAC/C;AAGA,IAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AACtD,IAAA,IAAI,UAAA,EAAY,UAAA,CAAW,SAAS,CAAA,EAAG;AACrC,MAAA,OAAO,IAAA,CAAK,iBAAA,CAAkB,UAAA,CAAW,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACnD;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,OAAA,EAA6C;AAEzD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,oBAAoB,aAAA,EAAmD;AACnF,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,YAAY,CAAA,QAAA,CAAA,EAAY;AAAA,QACtD,OAAA,EAAS;AAAA,UACP,MAAA,EAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,aAAa,CAAA;AAAA;AACzC,OACD,CAAA;AAED,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AAEpB,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAa7B,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAK,IAAA,CAAK,EAAA;AAAA,QACd,KAAA,EAAO,KAAK,IAAA,CAAK,KAAA;AAAA,QACjB,IAAA,EAAM,CAAC,IAAA,CAAK,IAAA,CAAK,WAAW,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAAK,MAAA;AAAA,QAC7E,SAAA,EAAW,KAAK,IAAA,CAAK,iBAAA;AAAA,QACrB,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,aAAa,IAAA,CAAK;AAAA,OACpB;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,kBAAkB,KAAA,EAA2C;AACzE,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,YAAY,CAAA,YAAA,CAAA,EAAgB;AAAA,QAC1D,OAAA,EAAS;AAAA,UACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC,OACD,CAAA;AAED,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AAEpB,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAU7B,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAK,IAAA,CAAK,EAAA;AAAA,QACd,KAAA,EAAO,KAAK,IAAA,CAAK,KAAA;AAAA,QACjB,IAAA,EAAM,CAAC,IAAA,CAAK,IAAA,CAAK,WAAW,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAAK,MAAA;AAAA,QAC7E,gBAAgB,IAAA,CAAK;AAAA,OACvB;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACF;AAMA,SAAS,WAAA,CAAY,cAAyC,IAAA,EAA6B;AACzF,EAAA,IAAI,CAAC,cAAc,OAAO,IAAA;AAC1B,EAAA,MAAM,KAAA,GAAQ,aAAa,KAAA,CAAM,IAAI,OAAO,CAAA,EAAG,IAAI,UAAU,CAAC,CAAA;AAC9D,EAAA,OAAO,KAAA,GAAQ,CAAC,CAAA,IAAK,IAAA;AACvB;AA6BO,IAAM,mBAAN,MAA4D;AAAA,EACzD,OAAA;AAAA,EAER,IAAI,WAAA,GAA2B;AAC7B,IAAA,OAAO,KAAK,OAAA,CAAQ,WAAA;AAAA,EACtB;AAAA,EAEA,YAAY,OAAA,EAAkC;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,MAAM,SAAS,IAAA,EAAqC;AAClD,IAAA,OAAO,KAAK,IAAA,GAAO,CAAC,IAAA,CAAK,IAAI,IAAI,EAAC;AAAA,EACpC;AAAA,EAEA,MAAM,OAAA,CAAQ,IAAA,EAAkB,IAAA,EAAgC;AAC9D,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA;AACtC,IAAA,OAAO,KAAA,CAAM,SAAS,IAAI,CAAA;AAAA,EAC5B;AAAA,EAEA,MAAM,eAAe,IAAA,EAAqC;AACxD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA;AACtC,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,UAAU,KAAK,EAAC;AAAA,IAClD;AACA,IAAA,OAAO,6BAAA,CAA8B,KAAA,EAAO,IAAA,CAAK,OAAA,CAAQ,WAAW,CAAA;AAAA,EACtE;AAAA,EAEA,MAAM,aAAA,CAAc,IAAA,EAAkB,UAAA,EAAsC;AAC1E,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AAClD,IAAA,OAAO,YAAY,IAAA,CAAK,CAAA,CAAA,KAAK,iBAAA,CAAkB,CAAA,EAAG,UAAU,CAAC,CAAA;AAAA,EAC/D;AAAA,EAEA,MAAM,iBAAA,CAAkB,IAAA,EAAkB,WAAA,EAAyC;AACjF,IAAA,MAAM,eAAA,GAAkB,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AACtD,IAAA,OAAO,WAAA,CAAY,KAAA,CAAM,CAAA,QAAA,KAAY,eAAA,CAAgB,IAAA,CAAK,OAAK,iBAAA,CAAkB,CAAA,EAAG,QAAQ,CAAC,CAAC,CAAA;AAAA,EAChG;AAAA,EAEA,MAAM,gBAAA,CAAiB,IAAA,EAAkB,WAAA,EAAyC;AAChF,IAAA,MAAM,eAAA,GAAkB,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AACtD,IAAA,OAAO,WAAA,CAAY,IAAA,CAAK,CAAA,QAAA,KAAY,eAAA,CAAgB,IAAA,CAAK,OAAK,iBAAA,CAAkB,CAAA,EAAG,QAAQ,CAAC,CAAC,CAAA;AAAA,EAC/F;AACF","file":"index.js","sourcesContent":["import type {\n ISSOProvider,\n ISessionProvider,\n IUserProvider,\n Session,\n SSOCallbackResult,\n SSOLoginConfig,\n} from '@mastra/core/auth';\nimport type { EEUser, IRBACProvider, RoleMapping } from '@mastra/core/auth/ee';\nimport { resolvePermissionsFromMapping, matchesPermission } from '@mastra/core/auth/ee';\nimport { MastraAuthProvider } from '@mastra/core/server';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\n\nexport interface StudioUser extends EEUser {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n organizationId?: string;\n role?: string;\n permissions?: string[];\n}\n\nexport interface MastraAuthStudioOptions extends MastraAuthProviderOptions<StudioUser> {\n /** Base URL of the Mastra shared API (e.g., https://api.mastra.ai/v1) */\n sharedApiUrl?: string;\n /** Organization ID that owns this deployed instance. Users not in this org are rejected. */\n organizationId?: string;\n}\n\nconst COOKIE_NAME = 'wos-session';\n\n/**\n * Auth provider for Mastra Studio deployed instances.\n *\n * Proxies all authentication through the shared API, keeping the\n * WorkOS API key safely in the shared API. Deployed instances only\n * need the shared API URL — no secrets required.\n *\n * The shared API's sealed session cookie (`wos-session`) is set with\n * `Domain=.mastra.ai` in production, so it's included in requests\n * to deployed instances and can be forwarded for validation.\n */\nexport class MastraAuthStudio\n extends MastraAuthProvider<StudioUser>\n implements ISSOProvider<StudioUser>, ISessionProvider<Session>, IUserProvider<StudioUser>\n{\n readonly isMastraCloudAuth = true;\n\n private sharedApiUrl: string;\n private organizationId: string | undefined;\n private useProductionCookies: boolean;\n\n constructor(options?: MastraAuthStudioOptions) {\n super({ name: 'mastra-studio', ...options });\n this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || 'http://localhost:3010/v1';\n this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID;\n\n // Strip trailing slash\n if (this.sharedApiUrl.endsWith('/')) {\n this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);\n }\n\n // Use production cookie settings (Secure + Domain=.mastra.ai) only when\n // the shared API is actually on .mastra.ai — NOT based on NODE_ENV which\n // may be 'production' even in local dev (e.g. mastra dev sets it).\n this.useProductionCookies = this.sharedApiUrl.includes('.mastra.ai');\n\n if (options) {\n this.registerOptions(options);\n }\n }\n\n // ---------------------------------------------------------------------------\n // MastraAuthProvider abstract methods\n // ---------------------------------------------------------------------------\n\n /**\n * Authenticate an incoming request by forwarding the sealed session cookie\n * to the shared API's /auth/me endpoint, or a Bearer token to /auth/verify.\n */\n async authenticateToken(token: string, request: any): Promise<StudioUser | null> {\n let user: StudioUser | null = null;\n\n // Try sealed session cookie first (browser flow)\n const cookieHeader = request?.headers?.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n user = await this.verifySessionCookie(sessionCookie);\n }\n\n // Fall back to Bearer token (CLI / API token flow)\n if (!user && token) {\n user = await this.verifyBearerToken(token);\n }\n\n if (!user) return null;\n\n // Org-scoping: if this instance belongs to a specific org, reject users not in that org\n if (this.organizationId && user.organizationId !== this.organizationId) {\n return null;\n }\n\n return user;\n }\n\n authorizeUser(user: StudioUser): boolean {\n return !!user?.id;\n }\n\n // ---------------------------------------------------------------------------\n // ISSOProvider\n // ---------------------------------------------------------------------------\n\n getLoginUrl(redirectUri: string, state: string): string {\n // Extract the post-login redirect from state (format: uuid|encodedPostLoginRedirect)\n let postLoginRedirect = '/';\n if (state) {\n const pipeIndex = state.indexOf('|');\n if (pipeIndex !== -1) {\n try {\n postLoginRedirect = decodeURIComponent(state.slice(pipeIndex + 1));\n } catch {\n // ignore decode errors\n }\n }\n }\n\n const params = new URLSearchParams({\n product: 'deploy',\n redirect_uri: redirectUri,\n post_login_redirect: postLoginRedirect,\n // Force re-authentication so AuthKit always shows the account picker\n prompt: 'login',\n ...(this.organizationId ? { organization_id: this.organizationId } : {}),\n });\n\n return `${this.sharedApiUrl}/auth/login?${params.toString()}`;\n }\n\n async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {\n // The shared API already consumed the OAuth code and passes the sealed\n // session directly as the `code` parameter in the redirect to this callback.\n // Validate it to get user info.\n const user = await this.verifySessionCookie(code);\n if (!user) {\n throw new Error('Session validation failed');\n }\n\n // Omit `cookies` so the Mastra server fallback path calls\n // createSession() + getSessionHeaders() to build a cookie scoped to\n // the deployed instance's domain.\n return {\n user,\n tokens: {\n accessToken: code,\n },\n };\n }\n\n setCallbackCookieHeader(_cookieHeader: string | null): void {\n // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow\n }\n\n getLoginCookies(): string[] | undefined {\n // No PKCE cookies needed — shared API manages the OAuth state\n return undefined;\n }\n\n getLoginButtonConfig(): SSOLoginConfig {\n return {\n provider: 'mastra-studio',\n text: 'Sign in with Mastra',\n };\n }\n\n async getLogoutUrl(_redirectUri: string, request?: Request): Promise<string | null> {\n const cookieHeader = request?.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (!sessionCookie) return null;\n\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (res.ok) {\n const data = (await res.json()) as { ok: boolean; logoutUrl?: string };\n return data.logoutUrl ?? null;\n }\n } catch {\n // Failed to get logout URL — return null\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // ISessionProvider\n // ---------------------------------------------------------------------------\n\n async createSession(userId: string, metadata?: Record<string, unknown>): Promise<Session> {\n const now = new Date();\n return {\n id: (metadata?.accessToken as string) || crypto.randomUUID(),\n userId,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000), // 24 hours\n createdAt: now,\n metadata,\n };\n }\n\n async validateSession(sessionId: string): Promise<Session | null> {\n const user = await this.verifySessionCookie(sessionId);\n if (!user) return null;\n\n const now = new Date();\n return {\n id: sessionId,\n userId: user.id,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000),\n createdAt: now,\n };\n }\n\n async destroySession(sessionId: string): Promise<void> {\n try {\n await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionId}`,\n },\n });\n } catch {\n // Best effort\n }\n }\n\n async refreshSession(sessionId: string): Promise<Session | null> {\n return this.validateSession(sessionId);\n }\n\n getSessionIdFromRequest(request: Request): string | null {\n const cookieHeader = request.headers.get('Cookie');\n return parseCookie(cookieHeader, COOKIE_NAME);\n }\n\n getSessionHeaders(session: Session): Record<string, string> {\n const parts = [`${COOKIE_NAME}=${session.id}`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=86400'];\n if (this.useProductionCookies) {\n parts.push('Secure');\n parts.push('Domain=.mastra.ai');\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n getClearSessionHeaders(): Record<string, string> {\n const parts = [`${COOKIE_NAME}=`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=0'];\n if (this.useProductionCookies) {\n parts.push('Secure');\n parts.push('Domain=.mastra.ai');\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n // ---------------------------------------------------------------------------\n // IUserProvider\n // ---------------------------------------------------------------------------\n\n async getCurrentUser(request: Request): Promise<StudioUser | null> {\n const cookieHeader = request.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n return this.verifySessionCookie(sessionCookie);\n }\n\n // Try bearer token\n const authHeader = request.headers.get('Authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return this.verifyBearerToken(authHeader.slice(7));\n }\n\n return null;\n }\n\n async getUser(_userId: string): Promise<StudioUser | null> {\n // Cannot look up users by ID — only validate sessions\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Forward a sealed session cookie to the shared API's /auth/me endpoint\n * to validate it and get user info.\n */\n private async verifySessionCookie(sessionCookie: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/me`, {\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n profilePictureUrl?: string;\n };\n organizationId: string;\n role?: string;\n permissions?: string[];\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n avatarUrl: data.user.profilePictureUrl,\n organizationId: data.organizationId,\n role: data.role,\n permissions: data.permissions,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Forward a Bearer token to the shared API's /auth/verify endpoint\n * to validate it and get user info (used for CLI tokens).\n */\n private async verifyBearerToken(token: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n };\n organizationId: string;\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n organizationId: data.organizationId,\n };\n } catch {\n return null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cookie helpers\n// ---------------------------------------------------------------------------\n\nfunction parseCookie(cookieHeader: string | null | undefined, name: string): string | null {\n if (!cookieHeader) return null;\n const match = cookieHeader.match(new RegExp(`${name}=([^;]+)`));\n return match?.[1] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// MastraRBACStudio — role-based permission provider for Studio auth\n// ---------------------------------------------------------------------------\n\nexport interface MastraRBACStudioOptions {\n /**\n * Mapping from role names to permission arrays.\n *\n * @example\n * ```typescript\n * {\n * admin: ['*'],\n * member: ['agents:read', 'workflows:*'],\n * viewer: ['agents:read', 'workflows:read'],\n * _default: [],\n * }\n * ```\n */\n roleMapping: RoleMapping;\n}\n\n/**\n * RBAC provider for Mastra Studio authentication.\n *\n * Maps user roles (from the shared API's /auth/me endpoint) to Mastra permissions\n * using a configurable role mapping.\n */\nexport class MastraRBACStudio implements IRBACProvider<StudioUser> {\n private options: MastraRBACStudioOptions;\n\n get roleMapping(): RoleMapping {\n return this.options.roleMapping;\n }\n\n constructor(options: MastraRBACStudioOptions) {\n this.options = options;\n }\n\n async getRoles(user: StudioUser): Promise<string[]> {\n return user.role ? [user.role] : [];\n }\n\n async hasRole(user: StudioUser, role: string): Promise<boolean> {\n const roles = await this.getRoles(user);\n return roles.includes(role);\n }\n\n async getPermissions(user: StudioUser): Promise<string[]> {\n const roles = await this.getRoles(user);\n if (roles.length === 0) {\n return this.options.roleMapping['_default'] ?? [];\n }\n return resolvePermissionsFromMapping(roles, this.options.roleMapping);\n }\n\n async hasPermission(user: StudioUser, permission: string): Promise<boolean> {\n const permissions = await this.getPermissions(user);\n return permissions.some(p => matchesPermission(p, permission));\n }\n\n async hasAllPermissions(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.every(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n\n async hasAnyPermission(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.some(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ISSOProvider,\n ISessionProvider,\n IUserProvider,\n Session,\n SSOCallbackResult,\n SSOLoginConfig,\n} from '@mastra/core/auth';\nimport type { EEUser, IRBACProvider, RoleMapping } from '@mastra/core/auth/ee';\nimport { resolvePermissionsFromMapping, matchesPermission } from '@mastra/core/auth/ee';\nimport { MastraAuthProvider } from '@mastra/core/server';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\n\nexport interface StudioUser extends EEUser {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n organizationId?: string;\n role?: string;\n permissions?: string[];\n}\n\nexport interface MastraAuthStudioOptions extends MastraAuthProviderOptions<StudioUser> {\n /** Base URL of the Mastra shared API (e.g., https://api.mastra.ai/v1) */\n sharedApiUrl?: string;\n /** Organization ID that owns this deployed instance. Users not in this org are rejected. */\n organizationId?: string;\n /**\n * Cookie domain for session cookies (e.g., '.example.com').\n * When set, cookies will include Secure and Domain attributes.\n * Defaults to auto-detecting from sharedApiUrl (uses '.mastra.ai' when sharedApiUrl contains '.mastra.ai').\n * Can also be set via MASTRA_COOKIE_DOMAIN environment variable.\n */\n cookieDomain?: string;\n}\n\nconst COOKIE_NAME = 'wos-session';\n\n/**\n * Auth provider for Mastra Studio deployed instances.\n *\n * Proxies all authentication through the shared API, keeping the\n * WorkOS API key safely in the shared API. Deployed instances only\n * need the shared API URL — no secrets required.\n *\n * The shared API's sealed session cookie (`wos-session`) is set with\n * `Domain=.mastra.ai` in production, so it's included in requests\n * to deployed instances and can be forwarded for validation.\n */\nexport class MastraAuthStudio\n extends MastraAuthProvider<StudioUser>\n implements ISSOProvider<StudioUser>, ISessionProvider<Session>, IUserProvider<StudioUser>\n{\n readonly isMastraCloudAuth = true;\n\n private sharedApiUrl: string;\n private organizationId: string | undefined;\n private useProductionCookies: boolean;\n private cookieDomain: string | undefined;\n\n constructor(options?: MastraAuthStudioOptions) {\n super({ name: 'mastra-studio', ...options });\n this.sharedApiUrl = options?.sharedApiUrl || process.env.MASTRA_SHARED_API_URL || 'http://localhost:3010/v1';\n this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID;\n\n // Strip trailing slash\n if (this.sharedApiUrl.endsWith('/')) {\n this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);\n }\n\n // Cookie domain can be explicitly configured, read from env, or auto-detected from sharedApiUrl\n this.cookieDomain = options?.cookieDomain || process.env.MASTRA_COOKIE_DOMAIN;\n\n // Use production cookie settings (Secure + Domain) when:\n // 1. An explicit cookieDomain is configured, OR\n // 2. The shared API is on .mastra.ai (auto-detect default domain)\n // Use hostname-based detection to avoid false positives (e.g., api.mastra.ai.evil.com)\n let autoDetectMastraAi = false;\n try {\n const hostname = new URL(this.sharedApiUrl).hostname.toLowerCase();\n autoDetectMastraAi = hostname === 'mastra.ai' || hostname.endsWith('.mastra.ai');\n } catch {\n autoDetectMastraAi = false;\n }\n this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;\n\n // If no explicit domain but we're on .mastra.ai, use the default domain\n if (!this.cookieDomain && autoDetectMastraAi) {\n this.cookieDomain = '.mastra.ai';\n }\n\n if (options) {\n this.registerOptions(options);\n }\n }\n\n // ---------------------------------------------------------------------------\n // MastraAuthProvider abstract methods\n // ---------------------------------------------------------------------------\n\n /**\n * Authenticate an incoming request by forwarding the sealed session cookie\n * to the shared API's /auth/me endpoint, or a Bearer token to /auth/verify.\n */\n async authenticateToken(token: string, request: any): Promise<StudioUser | null> {\n let user: StudioUser | null = null;\n\n // Try sealed session cookie first (browser flow)\n const cookieHeader = request?.headers?.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n user = await this.verifySessionCookie(sessionCookie);\n }\n\n // Fall back to Bearer token (CLI / API token flow)\n if (!user && token) {\n user = await this.verifyBearerToken(token);\n }\n\n if (!user) return null;\n\n // Org-scoping: if this instance belongs to a specific org, reject users not in that org\n if (this.organizationId && user.organizationId !== this.organizationId) {\n return null;\n }\n\n return user;\n }\n\n authorizeUser(user: StudioUser): boolean {\n return !!user?.id;\n }\n\n // ---------------------------------------------------------------------------\n // ISSOProvider\n // ---------------------------------------------------------------------------\n\n getLoginUrl(redirectUri: string, state: string): string {\n // Extract the post-login redirect from state (format: uuid|encodedPostLoginRedirect)\n let postLoginRedirect = '/';\n if (state) {\n const pipeIndex = state.indexOf('|');\n if (pipeIndex !== -1) {\n try {\n postLoginRedirect = decodeURIComponent(state.slice(pipeIndex + 1));\n } catch {\n // ignore decode errors\n }\n }\n }\n\n const params = new URLSearchParams({\n product: 'deploy',\n redirect_uri: redirectUri,\n post_login_redirect: postLoginRedirect,\n // Force re-authentication so AuthKit always shows the account picker\n prompt: 'login',\n ...(this.organizationId ? { organization_id: this.organizationId } : {}),\n });\n\n return `${this.sharedApiUrl}/auth/login?${params.toString()}`;\n }\n\n async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {\n // The shared API already consumed the OAuth code and passes the sealed\n // session directly as the `code` parameter in the redirect to this callback.\n // Validate it to get user info.\n const user = await this.verifySessionCookie(code);\n if (!user) {\n throw new Error('Session validation failed');\n }\n\n // Omit `cookies` so the Mastra server fallback path calls\n // createSession() + getSessionHeaders() to build a cookie scoped to\n // the deployed instance's domain.\n return {\n user,\n tokens: {\n accessToken: code,\n },\n };\n }\n\n setCallbackCookieHeader(_cookieHeader: string | null): void {\n // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow\n }\n\n getLoginCookies(): string[] | undefined {\n // No PKCE cookies needed — shared API manages the OAuth state\n return undefined;\n }\n\n getLoginButtonConfig(): SSOLoginConfig {\n return {\n provider: 'mastra-studio',\n text: 'Sign in with Mastra',\n };\n }\n\n async getLogoutUrl(_redirectUri: string, request?: Request): Promise<string | null> {\n const cookieHeader = request?.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (!sessionCookie) return null;\n\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (res.ok) {\n const data = (await res.json()) as { ok: boolean; logoutUrl?: string };\n return data.logoutUrl ?? null;\n }\n } catch {\n // Failed to get logout URL — return null\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // ISessionProvider\n // ---------------------------------------------------------------------------\n\n async createSession(userId: string, metadata?: Record<string, unknown>): Promise<Session> {\n const now = new Date();\n return {\n id: (metadata?.accessToken as string) || crypto.randomUUID(),\n userId,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000), // 24 hours\n createdAt: now,\n metadata,\n };\n }\n\n async validateSession(sessionId: string): Promise<Session | null> {\n const user = await this.verifySessionCookie(sessionId);\n if (!user) return null;\n\n const now = new Date();\n return {\n id: sessionId,\n userId: user.id,\n expiresAt: new Date(now.getTime() + 24 * 60 * 60 * 1000),\n createdAt: now,\n };\n }\n\n async destroySession(sessionId: string): Promise<void> {\n try {\n await fetch(`${this.sharedApiUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionId}`,\n },\n });\n } catch {\n // Best effort\n }\n }\n\n async refreshSession(sessionId: string): Promise<Session | null> {\n return this.validateSession(sessionId);\n }\n\n getSessionIdFromRequest(request: Request): string | null {\n const cookieHeader = request.headers.get('Cookie');\n return parseCookie(cookieHeader, COOKIE_NAME);\n }\n\n getSessionHeaders(session: Session): Record<string, string> {\n const parts = [`${COOKIE_NAME}=${session.id}`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=86400'];\n if (this.useProductionCookies && this.cookieDomain) {\n parts.push('Secure');\n parts.push(`Domain=${this.cookieDomain}`);\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n getClearSessionHeaders(): Record<string, string> {\n const parts = [`${COOKIE_NAME}=`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=0'];\n if (this.useProductionCookies && this.cookieDomain) {\n parts.push('Secure');\n parts.push(`Domain=${this.cookieDomain}`);\n }\n return { 'Set-Cookie': parts.join('; ') };\n }\n\n // ---------------------------------------------------------------------------\n // IUserProvider\n // ---------------------------------------------------------------------------\n\n async getCurrentUser(request: Request): Promise<StudioUser | null> {\n const cookieHeader = request.headers.get('Cookie');\n const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);\n\n if (sessionCookie) {\n return this.verifySessionCookie(sessionCookie);\n }\n\n // Try bearer token\n const authHeader = request.headers.get('Authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return this.verifyBearerToken(authHeader.slice(7));\n }\n\n return null;\n }\n\n async getUser(_userId: string): Promise<StudioUser | null> {\n // Cannot look up users by ID — only validate sessions\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Forward a sealed session cookie to the shared API's /auth/me endpoint\n * to validate it and get user info.\n */\n private async verifySessionCookie(sessionCookie: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/me`, {\n headers: {\n Cookie: `${COOKIE_NAME}=${sessionCookie}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n profilePictureUrl?: string;\n };\n organizationId: string;\n role?: string;\n permissions?: string[];\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n avatarUrl: data.user.profilePictureUrl,\n organizationId: data.organizationId,\n role: data.role,\n permissions: data.permissions,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Forward a Bearer token to the shared API's /auth/verify endpoint\n * to validate it and get user info (used for CLI tokens).\n */\n private async verifyBearerToken(token: string): Promise<StudioUser | null> {\n try {\n const res = await fetch(`${this.sharedApiUrl}/auth/verify`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n user: {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n };\n organizationId: string;\n };\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: [data.user.firstName, data.user.lastName].filter(Boolean).join(' ') || undefined,\n organizationId: data.organizationId,\n };\n } catch {\n return null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cookie helpers\n// ---------------------------------------------------------------------------\n\nfunction parseCookie(cookieHeader: string | null | undefined, name: string): string | null {\n if (!cookieHeader) return null;\n const match = cookieHeader.match(new RegExp(`${name}=([^;]+)`));\n return match?.[1] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// MastraRBACStudio — role-based permission provider for Studio auth\n// ---------------------------------------------------------------------------\n\nexport interface MastraRBACStudioOptions {\n /**\n * Mapping from role names to permission arrays.\n *\n * @example\n * ```typescript\n * {\n * admin: ['*'],\n * member: ['agents:read', 'workflows:*'],\n * viewer: ['agents:read', 'workflows:read'],\n * _default: [],\n * }\n * ```\n */\n roleMapping: RoleMapping;\n}\n\n/**\n * RBAC provider for Mastra Studio authentication.\n *\n * Maps user roles (from the shared API's /auth/me endpoint) to Mastra permissions\n * using a configurable role mapping.\n */\nexport class MastraRBACStudio implements IRBACProvider<StudioUser> {\n private options: MastraRBACStudioOptions;\n\n get roleMapping(): RoleMapping {\n return this.options.roleMapping;\n }\n\n constructor(options: MastraRBACStudioOptions) {\n this.options = options;\n }\n\n async getRoles(user: StudioUser): Promise<string[]> {\n return user.role ? [user.role] : [];\n }\n\n async hasRole(user: StudioUser, role: string): Promise<boolean> {\n const roles = await this.getRoles(user);\n return roles.includes(role);\n }\n\n async getPermissions(user: StudioUser): Promise<string[]> {\n const roles = await this.getRoles(user);\n if (roles.length === 0) {\n return this.options.roleMapping['_default'] ?? [];\n }\n return resolvePermissionsFromMapping(roles, this.options.roleMapping);\n }\n\n async hasPermission(user: StudioUser, permission: string): Promise<boolean> {\n const permissions = await this.getPermissions(user);\n return permissions.some(p => matchesPermission(p, permission));\n }\n\n async hasAllPermissions(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.every(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n\n async hasAnyPermission(user: StudioUser, permissions: string[]): Promise<boolean> {\n const userPermissions = await this.getPermissions(user);\n return permissions.some(required => userPermissions.some(p => matchesPermission(p, required)));\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/auth-studio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-alpha.0",
|
|
4
4
|
"description": "Mastra Studio Auth integration — proxies authentication through Mastra shared API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,18 +19,17 @@
|
|
|
19
19
|
"./package.json": "./package.json"
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
|
-
"dependencies": {},
|
|
23
22
|
"devDependencies": {
|
|
24
|
-
"@types/node": "22.19.
|
|
23
|
+
"@types/node": "22.19.15",
|
|
25
24
|
"@vitest/coverage-v8": "4.0.18",
|
|
26
25
|
"@vitest/ui": "4.0.18",
|
|
27
|
-
"eslint": "^9.
|
|
26
|
+
"eslint": "^9.39.4",
|
|
28
27
|
"tsup": "^8.5.1",
|
|
29
28
|
"typescript": "^5.9.3",
|
|
30
29
|
"vitest": "4.0.18",
|
|
31
|
-
"@internal/lint": "0.0.
|
|
32
|
-
"@internal/types-builder": "0.0.
|
|
33
|
-
"@mastra/core": "1.
|
|
30
|
+
"@internal/lint": "0.0.71",
|
|
31
|
+
"@internal/types-builder": "0.0.46",
|
|
32
|
+
"@mastra/core": "1.14.0-alpha.2"
|
|
34
33
|
},
|
|
35
34
|
"peerDependencies": {
|
|
36
35
|
"@mastra/core": ">=1.0.0-0 <2.0.0-0"
|