'use strict'; var chunkRR5IB5A2_cjs = require('./chunk-RR5IB5A2.cjs'); var chunk4PQR3D5Y_cjs = require('./chunk-4PQR3D5Y.cjs'); var chunkZ7LCIYK7_cjs = require('./chunk-Z7LCIYK7.cjs'); var chunkG54X6VE6_cjs = require('./chunk-G54X6VE6.cjs'); var chunk64ITUOXI_cjs = require('./chunk-64ITUOXI.cjs'); var chunkSXKQ7CSX_cjs = require('./chunk-SXKQ7CSX.cjs'); var v4 = require('zod/v4'); var _buildCapabilitiesPromise; function loadBuildCapabilities() { if (!_buildCapabilitiesPromise) { _buildCapabilitiesPromise = import('@mastra/core/auth/ee').then((m) => m.buildCapabilities).catch(() => { console.error( "[@mastra/server] EE auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest" ); return void 0; }); } return _buildCapabilitiesPromise; } var _permissionPatternsPromise; function loadPermissionPatterns() { if (!_permissionPatternsPromise) { _permissionPatternsPromise = import('@mastra/core/auth/ee').then((m) => m.PERMISSION_PATTERNS).catch(() => { console.error( "[@mastra/server] EE auth features require @mastra/core >= 1.6.0. Please upgrade: npm install @mastra/core@latest" ); return void 0; }); } return _permissionPatternsPromise; } function getAuthProvider(mastra, isStudio) { const studioConfig = mastra.getStudio?.(); const hasStudioAuth = studioConfig?.auth && typeof studioConfig.auth.authenticateToken === "function"; if (isStudio && hasStudioAuth) { return studioConfig.auth; } const serverConfig = mastra.getServer?.(); if (!serverConfig?.auth) return null; if (typeof serverConfig.auth.authenticateToken === "function") { return serverConfig.auth; } return null; } function isStudioRequest(request) { return chunkSXKQ7CSX_cjs.isStudioClientTypeHeader(request.headers.get(chunkSXKQ7CSX_cjs.MASTRA_CLIENT_TYPE_HEADER) ?? void 0); } function getPublicOrigin(request) { const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim(); if (forwardedHost) { return `https://${forwardedHost}`; } const host = request.headers.get("host"); if (host) { const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(); const proto = forwardedProto || new URL(request.url).protocol.replace(":", ""); return `${proto}://${host}`; } return new URL(request.url).origin; } function getRBACProvider(mastra, isStudio) { if (isStudio) { const studioConfig = mastra.getStudio?.(); if (studioConfig?.rbac) { return studioConfig.rbac; } } const serverConfig = mastra.getServer?.(); return serverConfig?.rbac; } function getFGAProvider(mastra, isStudio) { if (isStudio) { const studioConfig = mastra.getStudio?.(); if (studioConfig?.fga) { return studioConfig.fga; } } const serverConfig = mastra.getServer?.(); return serverConfig?.fga; } function implementsInterface(auth, method) { return auth !== null && typeof auth === "object" && typeof auth[method] === "function"; } var GET_AUTH_CAPABILITIES_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "GET", path: "/auth/capabilities", responseType: "json", responseSchema: chunkRR5IB5A2_cjs.capabilitiesResponseSchema, summary: "Get auth capabilities", description: "Returns authentication capabilities and current user info. Used by Studio to determine available features and user state.", tags: ["Auth"], handler: async (ctx) => { try { const { mastra, request, routePrefix } = ctx; const isStudio = isStudioRequest(request); const auth = getAuthProvider(mastra, isStudio); if (!auth) { return { enabled: false, login: null }; } const rbac = getRBACProvider(mastra, isStudio); const fga = getFGAProvider(mastra, isStudio); const buildCapabilities = await loadBuildCapabilities(); if (!buildCapabilities) { return { enabled: false, login: null }; } const capabilities = await buildCapabilities(auth, request, { rbac, fga, apiPrefix: routePrefix }); if (!("user" in capabilities) && chunk4PQR3D5Y_cjs.supportsSessionRefresh(auth)) { try { const sessionId = await auth.getSessionIdFromRequest(request); if (sessionId) { const refreshedSession = await auth.refreshSession(sessionId); if (refreshedSession) { const sessionHeaders = await auth.getSessionHeaders(refreshedSession); const cookieValue = extractCookieFromHeaders(sessionHeaders); if (cookieValue) { const refreshedRequest = new Request(request.url, { method: request.method, headers: new Headers(request.headers) }); refreshedRequest.headers.set("Cookie", cookieValue); const refreshedCapabilities = await buildCapabilities(auth, refreshedRequest, { rbac, apiPrefix: routePrefix }); if ("user" in refreshedCapabilities) { refreshedCapabilities.__refreshHeaders = sessionHeaders; } return refreshedCapabilities; } } } } catch { } } return capabilities; } catch (error) { return chunkZ7LCIYK7_cjs.handleError(error, "Error getting auth capabilities"); } } }); function extractCookieFromHeaders(headers) { const setCookie = headers["Set-Cookie"] || headers["set-cookie"]; if (!setCookie) return null; const match = setCookie.match(/^([^;]+)/); return match ? match[1] ?? null : null; } var GET_CURRENT_USER_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "GET", path: "/auth/me", responseType: "json", responseSchema: chunkRR5IB5A2_cjs.currentUserResponseSchema, summary: "Get current user", description: "Returns the currently authenticated user, or null if not authenticated.", tags: ["Auth"], handler: async (ctx) => { try { const { mastra, request } = ctx; const isStudio = isStudioRequest(request); const auth = getAuthProvider(mastra, isStudio); const rbac = getRBACProvider(mastra, isStudio); if (!auth || !implementsInterface(auth, "getCurrentUser")) { return null; } const user = await auth.getCurrentUser(request); if (!user) return null; let roles; let permissions; if (rbac) { try { roles = await rbac.getRoles(user); permissions = await rbac.getPermissions(user); } catch { } } return { id: user.id, email: user.email, name: user.name, avatarUrl: user.avatarUrl, roles, permissions }; } catch (error) { return chunkZ7LCIYK7_cjs.handleError(error, "Error getting current user"); } } }); var GET_SSO_LOGIN_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "GET", path: "/auth/sso/login", responseType: "datastream-response", queryParamSchema: chunkRR5IB5A2_cjs.ssoLoginQuerySchema, summary: "Initiate SSO login", description: "Returns the SSO login URL and sets PKCE cookies if needed.", tags: ["Auth"], handler: async (ctx) => { try { const { mastra, redirect_uri, request, routePrefix } = ctx; const isStudio = isStudioRequest(request); const auth = getAuthProvider(mastra, isStudio); if (!auth || !implementsInterface(auth, "getLoginUrl")) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "SSO not configured" }); } const origin = getPublicOrigin(request); const raw = (routePrefix || "/api").trim(); const withSlash = raw.startsWith("/") ? raw : `/${raw}`; const prefix = withSlash.endsWith("/") ? withSlash.slice(0, -1) : withSlash; const oauthCallbackUri = `${origin}${prefix}/auth/sso/callback`; let postLoginRedirect = "/"; if (redirect_uri) { if (!redirect_uri.startsWith("http")) { postLoginRedirect = redirect_uri; } else { try { const redirectUrl = new URL(redirect_uri); const requestOrigin = new URL(origin); const isHttps = redirectUrl.protocol === "http:" || redirectUrl.protocol === "https:"; const isSameOrigin = redirectUrl.origin === requestOrigin.origin; const isLocalhost = redirectUrl.hostname === "localhost" || redirectUrl.hostname === "127.0.0.1" || redirectUrl.hostname === "[::1]"; if (isHttps && (isSameOrigin || isLocalhost)) { postLoginRedirect = redirect_uri; } } catch { } } } const stateId = crypto.randomUUID(); const state = `${stateId}|${encodeURIComponent(postLoginRedirect)}`; const loginUrl = await Promise.resolve(auth.getLoginUrl(oauthCallbackUri, state)); const headers = new Headers({ "Content-Type": "application/json" }); if (implementsInterface(auth, "getLoginCookies") && auth.getLoginCookies) { const cookies = auth.getLoginCookies(oauthCallbackUri, state); if (cookies?.length) { for (const cookie of cookies) { headers.append("Set-Cookie", cookie); } } } return new Response(JSON.stringify({ url: loginUrl }), { status: 200, headers }); } catch (error) { return chunkZ7LCIYK7_cjs.handleError(error, "Error initiating SSO login"); } } }); var GET_SSO_CALLBACK_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "GET", path: "/auth/sso/callback", responseType: "datastream-response", queryParamSchema: chunkRR5IB5A2_cjs.ssoCallbackQuerySchema, summary: "Handle SSO callback", description: "Handles the OAuth callback, exchanges code for session, and redirects to the app.", tags: ["Auth"], handler: async (ctx) => { const { mastra, code, state, request } = ctx; isStudioRequest(request); const baseUrl = getPublicOrigin(request); let redirectTo = "/"; let stateId = state || ""; if (state && state.includes("|")) { const [id, encodedRedirect] = state.split("|", 2); stateId = id; try { redirectTo = decodeURIComponent(encodedRedirect); } catch { redirectTo = "/"; } } let absoluteRedirect; if (redirectTo.startsWith("http")) { try { const parsed = new URL(redirectTo); const baseOrigin = new URL(baseUrl); const isHttps = parsed.protocol === "http:" || parsed.protocol === "https:"; const isSameOrigin = parsed.origin === baseOrigin.origin; const isLocalhost = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]"; absoluteRedirect = isHttps && (isSameOrigin || isLocalhost) ? redirectTo : `${baseUrl}/`; } catch { absoluteRedirect = `${baseUrl}/`; } } else { absoluteRedirect = `${baseUrl}${redirectTo}`; } try { let auth = getAuthProvider(mastra, true); if (!auth || !implementsInterface(auth, "handleCallback")) { auth = getAuthProvider(mastra, false); } if (!auth || !implementsInterface(auth, "handleCallback")) { return Response.redirect(`${absoluteRedirect}?error=sso_not_configured`, 302); } const reqCookieHeader = request.headers.get("cookie"); if (typeof auth.setCallbackCookieHeader === "function") { auth.setCallbackCookieHeader(reqCookieHeader); } const result = await auth.handleCallback(code, stateId); const user = result.user; const headers = new Headers(); headers.set("Location", absoluteRedirect); if (result.cookies?.length) { for (const cookie of result.cookies) { headers.append("Set-Cookie", cookie); } } else if (implementsInterface(auth, "createSession") && result.tokens) { const session = await auth.createSession(user.id, { accessToken: result.tokens.accessToken, refreshToken: result.tokens.refreshToken, expiresAt: result.tokens.expiresAt, organizationId: user.organizationId }); const sessionHeaders = auth.getSessionHeaders(session); for (const [key, value] of Object.entries(sessionHeaders)) { headers.append(key, value); } } return new Response(null, { status: 302, headers }); } catch (error) { const errorMessage = encodeURIComponent(error instanceof Error ? error.message : "Unknown error"); return Response.redirect(`${absoluteRedirect}?error=${errorMessage}`, 302); } } }); var POST_LOGOUT_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "POST", path: "/auth/logout", responseType: "datastream-response", summary: "Logout", description: "Destroys the current session and returns logout redirect URL if available.", tags: ["Auth"], handler: async (ctx) => { const { mastra, request } = ctx; const isStudio = isStudioRequest(request); try { const auth = getAuthProvider(mastra, isStudio); if (!auth) { return new Response(JSON.stringify({ success: true }), { status: 200, headers: { "Content-Type": "application/json" } }); } if (implementsInterface(auth, "getSessionIdFromRequest")) { const sessionId = auth.getSessionIdFromRequest(request); if (sessionId && implementsInterface(auth, "destroySession")) { await auth.destroySession(sessionId); } } let redirectTo; if (implementsInterface(auth, "getLogoutUrl") && auth.getLogoutUrl) { const origin = getPublicOrigin(request); const logoutUrl = await auth.getLogoutUrl(origin, request); redirectTo = logoutUrl ?? void 0; } const headers = new Headers({ "Content-Type": "application/json" }); if (implementsInterface(auth, "getClearSessionHeaders")) { const clearHeaders = auth.getClearSessionHeaders(); for (const [key, value] of Object.entries(clearHeaders)) { headers.append(key, value); } } return new Response(JSON.stringify({ success: true, redirectTo }), { status: 200, headers }); } catch (error) { return chunkZ7LCIYK7_cjs.handleError(error, "Error logging out"); } } }); var POST_REFRESH_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "POST", path: "/auth/refresh", responseType: "datastream-response", responseSchema: chunkRR5IB5A2_cjs.refreshResponseSchema, summary: "Refresh session", description: "Refreshes the current session, extending its expiry. Sets a new session cookie on success.", tags: ["Auth"], handler: async (ctx) => { const { mastra, request } = ctx; const isStudio = isStudioRequest(request); try { const auth = getAuthProvider(mastra, isStudio); if (!auth || !implementsInterface(auth, "refreshSession") || !implementsInterface(auth, "getSessionIdFromRequest")) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "Session refresh not configured" }); } const sessionId = auth.getSessionIdFromRequest(request); if (!sessionId) { throw new chunk64ITUOXI_cjs.HTTPException(401, { message: "No session" }); } const newSession = await auth.refreshSession(sessionId); if (!newSession) { throw new chunk64ITUOXI_cjs.HTTPException(401, { message: "Session expired" }); } const headers = new Headers({ "Content-Type": "application/json" }); if (implementsInterface(auth, "getSessionHeaders")) { const sessionHeaders = auth.getSessionHeaders(newSession); for (const [key, value] of Object.entries(sessionHeaders)) { headers.append(key, value); } } return new Response(JSON.stringify({ success: true }), { status: 200, headers }); } catch (error) { if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error; return chunkZ7LCIYK7_cjs.handleError(error, "Error refreshing session"); } } }); var POST_CREDENTIALS_SIGN_IN_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "POST", path: "/auth/credentials/sign-in", responseType: "datastream-response", bodySchema: chunkRR5IB5A2_cjs.credentialsSignInBodySchema, summary: "Sign in with credentials", description: "Authenticates a user with email and password.", tags: ["Auth"], handler: async (ctx) => { const { mastra, request, email, password } = ctx; const isStudio = isStudioRequest(request); try { const auth = getAuthProvider(mastra, isStudio); if (!auth || !implementsInterface(auth, "signIn")) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "Credentials authentication not configured" }); } const result = await auth.signIn(email, password, request); const user = result.user; const responseBody = JSON.stringify({ user: { id: user.id, email: user.email, name: user.name, avatarUrl: user.avatarUrl }, token: result.token }); const headers = new Headers({ "Content-Type": "application/json" }); if (result.cookies?.length) { for (const cookie of result.cookies) { headers.append("Set-Cookie", cookie); } } return new Response(responseBody, { status: 200, headers }); } catch (error) { if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error; throw new chunk64ITUOXI_cjs.HTTPException(401, { message: "Invalid email or password" }); } } }); var POST_CREDENTIALS_SIGN_UP_ROUTE = chunkG54X6VE6_cjs.createPublicRoute({ method: "POST", path: "/auth/credentials/sign-up", responseType: "datastream-response", bodySchema: chunkRR5IB5A2_cjs.credentialsSignUpBodySchema, summary: "Sign up with credentials", description: "Creates a new user account with email and password.", tags: ["Auth"], handler: async (ctx) => { const { mastra, request, email, password, name } = ctx; const isStudio = isStudioRequest(request); try { const auth = getAuthProvider(mastra, isStudio); if (!auth || !implementsInterface(auth, "signUp")) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "Credentials authentication not configured" }); } const result = await auth.signUp(email, password, name, request); const user = result.user; const responseBody = JSON.stringify({ user: { id: user.id, email: user.email, name: user.name, avatarUrl: user.avatarUrl }, token: result.token }); const headers = new Headers({ "Content-Type": "application/json" }); if (result.cookies?.length) { for (const cookie of result.cookies) { headers.append("Set-Cookie", cookie); } } return new Response(responseBody, { status: 200, headers }); } catch (error) { if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error; const mastra2 = ctx.mastra; mastra2?.getLogger?.()?.error("Sign-up error", { error: error instanceof Error ? { message: error.message, stack: error.stack } : error }); throw new chunk64ITUOXI_cjs.HTTPException(400, { message: "Failed to create account" }); } } }); var rolePermissionsPathSchema = v4.z.object({ roleId: v4.z.string() }); var rolePermissionsResponseSchema = v4.z.object({ roleId: v4.z.string(), permissions: v4.z.array(v4.z.string()) }); var GET_ROLE_PERMISSIONS_ROUTE = chunkG54X6VE6_cjs.createRoute({ method: "GET", path: "/auth/roles/:roleId/permissions", requiresAuth: true, responseType: "json", pathParamSchema: rolePermissionsPathSchema, responseSchema: rolePermissionsResponseSchema, summary: "Get permissions for a role", description: 'Returns the resolved permissions for a specific role. Only accessible by admin users. Used by the "View as role" feature.', tags: ["Auth"], handler: async (ctx) => { try { const { mastra, requestContext, roleId } = ctx; const callerPermissions = requestContext?.get(chunkSXKQ7CSX_cjs.MASTRA_USER_PERMISSIONS_KEY) ?? []; const isAdmin = callerPermissions.some((p) => p === "*" || p === "*:*"); if (!isAdmin) { throw new chunk64ITUOXI_cjs.HTTPException(403, { message: "Admin access required" }); } const rbac = getRBACProvider(mastra); if (!rbac?.getPermissionsForRole) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "RBAC provider does not support role permission resolution" }); } const permissions = await rbac.getPermissionsForRole(roleId); return { roleId, permissions }; } catch (error) { if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error; return chunkZ7LCIYK7_cjs.handleError(error, "Error getting role permissions"); } } }); var GET_PERMISSION_PATTERNS_ROUTE = chunkG54X6VE6_cjs.createRoute({ method: "GET", path: "/auth/permission-patterns", requiresAuth: true, responseType: "json", responseSchema: chunkRR5IB5A2_cjs.permissionPatternsResponseSchema, summary: "List valid permission patterns", description: "Returns the authoritative list of valid permission-pattern strings. Used by Studio to validate the route\u2192permission literals it ships and to gate the sidebar.", tags: ["Auth"], handler: async () => { const patterns = await loadPermissionPatterns(); return { patterns: Object.keys(patterns ?? {}) }; } }); var AUTH_ROUTES = [ GET_AUTH_CAPABILITIES_ROUTE, GET_CURRENT_USER_ROUTE, GET_SSO_LOGIN_ROUTE, GET_SSO_CALLBACK_ROUTE, POST_LOGOUT_ROUTE, POST_REFRESH_ROUTE, POST_CREDENTIALS_SIGN_IN_ROUTE, POST_CREDENTIALS_SIGN_UP_ROUTE, GET_ROLE_PERMISSIONS_ROUTE, GET_PERMISSION_PATTERNS_ROUTE ]; exports.AUTH_ROUTES = AUTH_ROUTES; exports.GET_AUTH_CAPABILITIES_ROUTE = GET_AUTH_CAPABILITIES_ROUTE; exports.GET_CURRENT_USER_ROUTE = GET_CURRENT_USER_ROUTE; exports.GET_PERMISSION_PATTERNS_ROUTE = GET_PERMISSION_PATTERNS_ROUTE; exports.GET_ROLE_PERMISSIONS_ROUTE = GET_ROLE_PERMISSIONS_ROUTE; exports.GET_SSO_CALLBACK_ROUTE = GET_SSO_CALLBACK_ROUTE; exports.GET_SSO_LOGIN_ROUTE = GET_SSO_LOGIN_ROUTE; exports.POST_CREDENTIALS_SIGN_IN_ROUTE = POST_CREDENTIALS_SIGN_IN_ROUTE; exports.POST_CREDENTIALS_SIGN_UP_ROUTE = POST_CREDENTIALS_SIGN_UP_ROUTE; exports.POST_LOGOUT_ROUTE = POST_LOGOUT_ROUTE; exports.POST_REFRESH_ROUTE = POST_REFRESH_ROUTE; exports.getPublicOrigin = getPublicOrigin; //# sourceMappingURL=chunk-4ZHHKMDQ.cjs.map //# sourceMappingURL=chunk-4ZHHKMDQ.cjs.map