@mastra/react 1.13.0-alpha.2 → 1.13.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accumulator-BmD8-x9I.cjs → accumulator-Bjfckb5t.cjs} +5 -9
- package/dist/{accumulator-BmD8-x9I.cjs.map → accumulator-Bjfckb5t.cjs.map} +1 -1
- package/dist/{accumulator-D9jAph99.js → accumulator-DysrPe6U.js} +5 -9
- package/dist/{accumulator-D9jAph99.js.map → accumulator-DysrPe6U.js.map} +1 -1
- package/dist/chat/index.cjs +1 -1
- package/dist/chat/index.js +1 -1
- package/dist/{combine-by-ids-CcaZKGT9.js → combine-by-ids-C-0oe4eH.js} +2 -3
- package/dist/{combine-by-ids-CcaZKGT9.js.map → combine-by-ids-C-0oe4eH.js.map} +1 -1
- package/dist/{combine-by-ids-D_lp6Dvq.cjs → combine-by-ids-ERVPXXBi.cjs} +2 -3
- package/dist/{combine-by-ids-D_lp6Dvq.cjs.map → combine-by-ids-ERVPXXBi.cjs.map} +1 -1
- package/dist/{experiments-CJw1N3FB.cjs → experiments-Duv0RgkM.cjs} +12 -19
- package/dist/{experiments-CJw1N3FB.cjs.map → experiments-Duv0RgkM.cjs.map} +1 -1
- package/dist/{experiments-B7vRMK5T.js → experiments-DyecjEut.js} +12 -19
- package/dist/{experiments-B7vRMK5T.js.map → experiments-DyecjEut.js.map} +1 -1
- package/dist/{feedback-refetch-interval-XD5FVc2k.cjs → feedback-refetch-interval-BBcT9r8s.cjs} +3 -4
- package/dist/{feedback-refetch-interval-XD5FVc2k.cjs.map → feedback-refetch-interval-BBcT9r8s.cjs.map} +1 -1
- package/dist/{feedback-refetch-interval-DLHzQoVV.js → feedback-refetch-interval-C12Nzb2r.js} +3 -4
- package/dist/{feedback-refetch-interval-DLHzQoVV.js.map → feedback-refetch-interval-C12Nzb2r.js.map} +1 -1
- package/dist/hooks/agents/index.cjs +19 -37
- package/dist/hooks/agents/index.cjs.map +1 -1
- package/dist/hooks/agents/index.js +19 -37
- package/dist/hooks/agents/index.js.map +1 -1
- package/dist/hooks/auth/index.cjs +11 -21
- package/dist/hooks/auth/index.cjs.map +1 -1
- package/dist/hooks/auth/index.js +11 -21
- package/dist/hooks/auth/index.js.map +1 -1
- package/dist/hooks/capabilities/index.cjs +11 -21
- package/dist/hooks/capabilities/index.cjs.map +1 -1
- package/dist/hooks/capabilities/index.js +11 -21
- package/dist/hooks/capabilities/index.js.map +1 -1
- package/dist/hooks/configuration/index.cjs +2 -3
- package/dist/hooks/configuration/index.js +2 -3
- package/dist/hooks/datasets/index.cjs +12 -21
- package/dist/hooks/datasets/index.cjs.map +1 -1
- package/dist/hooks/datasets/index.js +12 -21
- package/dist/hooks/datasets/index.js.map +1 -1
- package/dist/hooks/embedders/index.cjs +2 -3
- package/dist/hooks/embedders/index.js +2 -3
- package/dist/hooks/experiments/index.cjs +1 -1
- package/dist/hooks/experiments/index.js +1 -1
- package/dist/hooks/feedback/index.cjs +3 -4
- package/dist/hooks/feedback/index.js +3 -4
- package/dist/hooks/llm/index.cjs +2 -3
- package/dist/hooks/llm/index.js +2 -3
- package/dist/hooks/logs/index.cjs +4 -5
- package/dist/hooks/logs/index.js +4 -5
- package/dist/hooks/mcps/index.cjs +8 -15
- package/dist/hooks/mcps/index.cjs.map +1 -1
- package/dist/hooks/mcps/index.js +8 -15
- package/dist/hooks/mcps/index.js.map +1 -1
- package/dist/hooks/memory/index.cjs +5 -9
- package/dist/hooks/memory/index.cjs.map +1 -1
- package/dist/hooks/memory/index.js +5 -9
- package/dist/hooks/memory/index.js.map +1 -1
- package/dist/hooks/metrics/index.cjs +19 -36
- package/dist/hooks/metrics/index.cjs.map +1 -1
- package/dist/hooks/metrics/index.js +19 -36
- package/dist/hooks/metrics/index.js.map +1 -1
- package/dist/hooks/processors/index.cjs +2 -3
- package/dist/hooks/processors/index.js +2 -3
- package/dist/hooks/prompt-blocks/index.cjs +3 -5
- package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
- package/dist/hooks/prompt-blocks/index.js +3 -5
- package/dist/hooks/prompt-blocks/index.js.map +1 -1
- package/dist/hooks/query/index.cjs +2 -3
- package/dist/hooks/query/index.js +2 -3
- package/dist/hooks/review/index.cjs +4 -6
- package/dist/hooks/review/index.cjs.map +1 -1
- package/dist/hooks/review/index.js +4 -6
- package/dist/hooks/review/index.js.map +1 -1
- package/dist/hooks/schedules/index.cjs +6 -10
- package/dist/hooks/schedules/index.cjs.map +1 -1
- package/dist/hooks/schedules/index.js +6 -10
- package/dist/hooks/schedules/index.js.map +1 -1
- package/dist/hooks/scores/index.cjs +8 -13
- package/dist/hooks/scores/index.cjs.map +1 -1
- package/dist/hooks/scores/index.js +8 -13
- package/dist/hooks/scores/index.js.map +1 -1
- package/dist/hooks/templates/index.cjs +2 -3
- package/dist/hooks/templates/index.js +2 -3
- package/dist/hooks/tool-providers/index.cjs +10 -19
- package/dist/hooks/tool-providers/index.cjs.map +1 -1
- package/dist/hooks/tool-providers/index.js +10 -19
- package/dist/hooks/tool-providers/index.js.map +1 -1
- package/dist/hooks/tools/index.cjs +3 -5
- package/dist/hooks/tools/index.cjs.map +1 -1
- package/dist/hooks/tools/index.js +3 -5
- package/dist/hooks/tools/index.js.map +1 -1
- package/dist/hooks/traces/index.cjs +28 -51
- package/dist/hooks/traces/index.cjs.map +1 -1
- package/dist/hooks/traces/index.js +28 -51
- package/dist/hooks/traces/index.js.map +1 -1
- package/dist/hooks/vectors/index.cjs +2 -3
- package/dist/hooks/vectors/index.js +2 -3
- package/dist/hooks/voice/index.cjs +3 -4
- package/dist/hooks/voice/index.js +3 -4
- package/dist/hooks/workflows/index.cjs +7 -11
- package/dist/hooks/workflows/index.cjs.map +1 -1
- package/dist/hooks/workflows/index.js +7 -11
- package/dist/hooks/workflows/index.js.map +1 -1
- package/dist/hooks/workspace/index.cjs +12 -22
- package/dist/hooks/workspace/index.cjs.map +1 -1
- package/dist/hooks/workspace/index.js +12 -22
- package/dist/hooks/workspace/index.js.map +1 -1
- package/dist/{hooks-XYsmqFCz.cjs → hooks-Bt15IwzP.cjs} +6 -9
- package/dist/{hooks-XYsmqFCz.cjs.map → hooks-Bt15IwzP.cjs.map} +1 -1
- package/dist/{hooks-DG-Y1KFe.js → hooks-Btt7PyI-.js} +6 -9
- package/dist/{hooks-DG-Y1KFe.js.map → hooks-Btt7PyI-.js.map} +1 -1
- package/dist/{hooks-BfysjY_K.js → hooks-CEikbhrN.js} +9 -15
- package/dist/{hooks-BfysjY_K.js.map → hooks-CEikbhrN.js.map} +1 -1
- package/dist/{hooks-BbUMSab8.cjs → hooks-D6LDSEcm.cjs} +9 -15
- package/dist/{hooks-BbUMSab8.cjs.map → hooks-D6LDSEcm.cjs.map} +1 -1
- package/dist/index.cjs +7 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/{map-CDv4fbu4.js → map-5-4U5rwA.js} +2 -3
- package/dist/{map-CDv4fbu4.js.map → map-5-4U5rwA.js.map} +1 -1
- package/dist/{map-wjmL1y5O.cjs → map-BGoWBTGy.cjs} +2 -3
- package/dist/{map-wjmL1y5O.cjs.map → map-BGoWBTGy.cjs.map} +1 -1
- package/dist/{mastra-client-context-Bx_g84YB.js → mastra-client-context-DQ5z_ze9.js} +2 -3
- package/dist/{mastra-client-context-Bx_g84YB.js.map → mastra-client-context-DQ5z_ze9.js.map} +1 -1
- package/dist/{mastra-client-context-DzX3f0RF.cjs → mastra-client-context-DX8wJM9p.cjs} +2 -3
- package/dist/{mastra-client-context-DzX3f0RF.cjs.map → mastra-client-context-DX8wJM9p.cjs.map} +1 -1
- package/dist/{query-utils-CcrChYgz.cjs → query-utils-BVgE_xxj.cjs} +2 -3
- package/dist/{query-utils-CcrChYgz.cjs.map → query-utils-BVgE_xxj.cjs.map} +1 -1
- package/dist/{query-utils-D1NgFnWU.js → query-utils-DvMERIwf.js} +2 -3
- package/dist/{query-utils-D1NgFnWU.js.map → query-utils-DvMERIwf.js.map} +1 -1
- package/dist/ui/index.cjs +15 -30
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +14 -28
- package/dist/ui/index.js.map +1 -1
- package/dist/{use-in-view-B6eJO9Zi.cjs → use-in-view-BxdrrnCw.cjs} +2 -3
- package/dist/{use-in-view-B6eJO9Zi.cjs.map → use-in-view-BxdrrnCw.cjs.map} +1 -1
- package/dist/{use-in-view-C9sYPGRm.js → use-in-view-CyjKdplM.js} +2 -3
- package/dist/{use-in-view-C9sYPGRm.js.map → use-in-view-CyjKdplM.js.map} +1 -1
- package/dist/{voice-BOtUdMi8.cjs → voice-Didej2E1.cjs} +5 -8
- package/dist/{voice-BOtUdMi8.cjs.map → voice-Didej2E1.cjs.map} +1 -1
- package/dist/{voice-DgirjEyH.js → voice-ugGu7VyA.js} +5 -8
- package/dist/{voice-DgirjEyH.js.map → voice-ugGu7VyA.js.map} +1 -1
- package/package.json +17 -17
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_mastra_client_context = require("../../mastra-client-context-
|
|
2
|
+
const require_mastra_client_context = require("../../mastra-client-context-DX8wJM9p.cjs");
|
|
3
3
|
let react = require("react");
|
|
4
4
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
5
|
-
|
|
5
|
+
// src/hooks/auth/types.ts
|
|
6
6
|
/**
|
|
7
7
|
* Type guard to check if capabilities include authenticated user
|
|
8
8
|
*/
|
|
9
9
|
function isAuthenticated(capabilities) {
|
|
10
10
|
return "user" in capabilities && capabilities.user !== void 0;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
//#region src/hooks/auth/fetch-with-refresh.ts
|
|
12
|
+
// src/hooks/auth/fetch-with-refresh.ts
|
|
14
13
|
/**
|
|
15
14
|
* Fetch wrapper for the Mastra server API.
|
|
16
15
|
*
|
|
@@ -42,8 +41,7 @@ async function fetchWithRefresh(_baseUrl, input, init) {
|
|
|
42
41
|
function createFetchWithRefresh(_baseUrl, _apiPrefix) {
|
|
43
42
|
return (input, init) => fetch(input, init);
|
|
44
43
|
}
|
|
45
|
-
|
|
46
|
-
//#region src/hooks/auth/get-client-query-key.ts
|
|
44
|
+
// src/hooks/auth/get-client-query-key.ts
|
|
47
45
|
const clientQueryKeys = /* @__PURE__ */ new WeakMap();
|
|
48
46
|
let nextClientQueryKey = 0;
|
|
49
47
|
/**
|
|
@@ -57,8 +55,7 @@ function getClientQueryKey(client) {
|
|
|
57
55
|
clientQueryKeys.set(client, queryKey);
|
|
58
56
|
return queryKey;
|
|
59
57
|
}
|
|
60
|
-
|
|
61
|
-
//#region src/hooks/auth/sso-login.ts
|
|
58
|
+
// src/hooks/auth/sso-login.ts
|
|
62
59
|
async function makeSSOLoginRequest(client, { redirectUri }) {
|
|
63
60
|
const { baseUrl = "", apiPrefix, headers: clientHeaders = {} } = client.options;
|
|
64
61
|
const raw = (apiPrefix || "/api").trim();
|
|
@@ -76,8 +73,7 @@ async function makeSSOLoginRequest(client, { redirectUri }) {
|
|
|
76
73
|
if (!response.ok) throw new Error(`Failed to initiate SSO login: ${response.status}`);
|
|
77
74
|
return response.json();
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
//#region src/hooks/auth/use-auth-capabilities.ts
|
|
76
|
+
// src/hooks/auth/use-auth-capabilities.ts
|
|
81
77
|
/**
|
|
82
78
|
* Makes a request to the auth capabilities endpoint.
|
|
83
79
|
* Exported for testing purposes.
|
|
@@ -140,8 +136,7 @@ function useAuthCapabilities({ queryOptions } = {}) {
|
|
|
140
136
|
...queryOptions
|
|
141
137
|
});
|
|
142
138
|
}
|
|
143
|
-
|
|
144
|
-
//#region src/hooks/auth/use-current-user.ts
|
|
139
|
+
// src/hooks/auth/use-current-user.ts
|
|
145
140
|
const AUTH_TRANSIENT_MAX_RETRIES = 3;
|
|
146
141
|
const AUTH_TRANSIENT_MAX_BACKOFF_MS = 8e3;
|
|
147
142
|
var CurrentUserError = class extends Error {
|
|
@@ -205,8 +200,7 @@ function useCurrentUser({ queryOptions } = {}) {
|
|
|
205
200
|
...queryOptions
|
|
206
201
|
});
|
|
207
202
|
}
|
|
208
|
-
|
|
209
|
-
//#region src/hooks/auth/use-permission-patterns.ts
|
|
203
|
+
// src/hooks/auth/use-permission-patterns.ts
|
|
210
204
|
const usePermissionPatterns = ({ queryOptions } = {}) => {
|
|
211
205
|
const client = require_mastra_client_context.useMastraClient();
|
|
212
206
|
const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();
|
|
@@ -225,8 +219,7 @@ const usePermissionPatterns = ({ queryOptions } = {}) => {
|
|
|
225
219
|
error: capabilitiesError || error
|
|
226
220
|
};
|
|
227
221
|
};
|
|
228
|
-
|
|
229
|
-
//#region src/hooks/auth/use-credentials-login.ts
|
|
222
|
+
// src/hooks/auth/use-credentials-login.ts
|
|
230
223
|
/**
|
|
231
224
|
* Hook to login with email/password credentials.
|
|
232
225
|
*
|
|
@@ -305,8 +298,7 @@ function useCredentialsLogin({ queryOptions } = {}) {
|
|
|
305
298
|
...queryOptions
|
|
306
299
|
});
|
|
307
300
|
}
|
|
308
|
-
|
|
309
|
-
//#region src/hooks/auth/use-credentials-signup.ts
|
|
301
|
+
// src/hooks/auth/use-credentials-signup.ts
|
|
310
302
|
/**
|
|
311
303
|
* Hook to sign up with email/password credentials.
|
|
312
304
|
*
|
|
@@ -389,8 +381,7 @@ function useCredentialsSignUp({ queryOptions } = {}) {
|
|
|
389
381
|
...queryOptions
|
|
390
382
|
});
|
|
391
383
|
}
|
|
392
|
-
|
|
393
|
-
//#region src/hooks/auth/use-auth-actions.ts
|
|
384
|
+
// src/hooks/auth/use-auth-actions.ts
|
|
394
385
|
function useSSOLogin({ queryOptions } = {}) {
|
|
395
386
|
const client = require_mastra_client_context.useMastraClient();
|
|
396
387
|
return (0, _tanstack_react_query.useMutation)({
|
|
@@ -469,7 +460,6 @@ function useLogout({ onLoggedOut, queryOptions } = {}) {
|
|
|
469
460
|
...queryOptions
|
|
470
461
|
});
|
|
471
462
|
}
|
|
472
|
-
//#endregion
|
|
473
463
|
exports.CurrentUserError = CurrentUserError;
|
|
474
464
|
exports.createFetchWithRefresh = createFetchWithRefresh;
|
|
475
465
|
exports.fetchWithRefresh = fetchWithRefresh;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMemo","useMastraClient","useQueryClient","useMutation","useMastraClient","useQueryClient","useMutation","useMastraClient","useMutation","useQueryClient"],"sources":["../../../src/hooks/auth/types.ts","../../../src/hooks/auth/fetch-with-refresh.ts","../../../src/hooks/auth/get-client-query-key.ts","../../../src/hooks/auth/sso-login.ts","../../../src/hooks/auth/use-auth-capabilities.ts","../../../src/hooks/auth/use-current-user.ts","../../../src/hooks/auth/use-permission-patterns.ts","../../../src/hooks/auth/use-credentials-login.ts","../../../src/hooks/auth/use-credentials-signup.ts","../../../src/hooks/auth/use-auth-actions.ts"],"sourcesContent":["/**\n * Auth types for EE authentication in playground-ui.\n *\n * These types mirror the server schemas from @mastra/server.\n */\n\n/**\n * SSO configuration for login\n */\nexport type SSOConfig = {\n provider: string;\n text: string;\n icon?: string;\n description?: string;\n url: string;\n};\n\n/**\n * Login configuration\n */\nexport type LoginConfig = {\n type: 'sso' | 'credentials' | 'both';\n /** Whether sign-up is enabled (defaults to true) */\n signUpEnabled?: boolean;\n /** Optional description explaining the auth requirement and what credentials to use */\n description?: string;\n sso?: SSOConfig;\n} | null;\n\n/**\n * Public capabilities (unauthenticated)\n */\nexport type PublicAuthCapabilities = {\n enabled: boolean;\n login: LoginConfig;\n};\n\n/**\n * Authenticated user information\n */\nexport type AuthenticatedUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n};\n\n/**\n * Capability flags\n */\nexport type CapabilityFlags = {\n user: boolean;\n session: boolean;\n sso: boolean;\n rbac: boolean;\n acl: boolean;\n};\n\n/**\n * User access information\n */\nexport type UserAccess = {\n roles: string[];\n permissions: string[];\n} | null;\n\n/**\n * Authenticated capabilities (extends public)\n */\nexport type AuthenticatedCapabilities = PublicAuthCapabilities & {\n user: AuthenticatedUser;\n capabilities: CapabilityFlags;\n access: UserAccess;\n /** Available roles in the system (only present for admin users) */\n availableRoles?: { id: string; name: string }[];\n};\n\n/**\n * Auth capabilities response (union of public and authenticated)\n */\nexport type AuthCapabilities = PublicAuthCapabilities | AuthenticatedCapabilities;\n\n/**\n * Current user response (may be null if not authenticated)\n */\nexport type CurrentUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n roles?: string[];\n permissions?: string[];\n} | null;\n\n/**\n * SSO callback response\n */\nexport type SSOCallbackResponse = {\n success: boolean;\n user?: AuthenticatedUser;\n redirectTo?: string;\n};\n\n/**\n * Logout response\n */\nexport type LogoutResponse = {\n success: boolean;\n redirectTo?: string;\n};\n\n/**\n * Type guard to check if capabilities include authenticated user\n */\nexport function isAuthenticated(capabilities: AuthCapabilities): capabilities is AuthenticatedCapabilities {\n return 'user' in capabilities && capabilities.user !== undefined;\n}\n","/**\n * Fetch wrapper for the Mastra server API.\n *\n * ⚠️ MIRRORS: `platform/frontend/src/shared/lib/fetch-with-refresh.ts`\n *\n * Both files must stay behaviourally in lockstep — the platform dashboard and\n * the embedded playground both talk to WorkOS-backed auth and both would be\n * vulnerable to the same 429 lockout loop if either regressed. If you change\n * one, change the other in the same PR (or extract to a shared package —\n * currently blocked by the platform/mastra-ai monorepo boundary).\n *\n * ---\n *\n * The server middleware already refreshes the WorkOS session transparently\n * on every protected request. There is no scenario where the client can\n * succeed by calling /auth/refresh after a 401 — that endpoint hits the\n * same broken WorkOS with the same session and would only amplify transient\n * failures into forced logout (PLTFRM-1270).\n *\n * These are pass-throughs today. The names and signatures are preserved for\n * compatibility with existing call sites (`App.tsx`, `use-current-user.ts`).\n * Transient-failure retry belongs one level up — in React Query's `retry`\n * config on individual queries — not in a fetch wrapper that would compound\n * with the query-level retry.\n */\n\nexport async function fetchWithRefresh(\n _baseUrl: string,\n input: RequestInfo | URL,\n init?: RequestInit,\n): Promise<Response> {\n return fetch(input, init);\n}\n\nexport function createFetchWithRefresh(_baseUrl?: string, _apiPrefix?: string): typeof fetch {\n return (input, init) => fetch(input, init);\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nconst clientQueryKeys = new WeakMap<MastraClient, number>();\nlet nextClientQueryKey = 0;\n\n/**\n * Returns a stable, non-sensitive query key for a Mastra client instance.\n * A new client is created whenever its connection options change.\n */\nexport function getClientQueryKey(client: MastraClient) {\n const existingKey = clientQueryKeys.get(client);\n if (existingKey !== undefined) return existingKey;\n\n const queryKey = nextClientQueryKey++;\n clientQueryKeys.set(client, queryKey);\n return queryKey;\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nexport type SSOLoginResponse = {\n url: string;\n};\n\nexport async function makeSSOLoginRequest(\n client: Pick<MastraClient, 'options'>,\n { redirectUri }: { redirectUri?: string },\n): Promise<SSOLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const params = new URLSearchParams();\n if (redirectUri) {\n params.set('redirect_uri', redirectUri);\n }\n\n const url = `${baseUrl}${prefix}/auth/sso/login${params.toString() ? `?${params}` : ''}`;\n\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to initiate SSO login: ${response.status}`);\n }\n\n return response.json();\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport type { AuthCapabilities } from './types';\n\n/**\n * Makes a request to the auth capabilities endpoint.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeAuthCapabilitiesRequest(client: MastraClient): Promise<AuthCapabilities> {\n const { baseUrl = '', headers: clientHeaders = {}, apiPrefix } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/capabilities`, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch auth capabilities: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Hook to fetch authentication capabilities.\n *\n * Returns server-authoritative capability detection including:\n * - Whether auth is enabled\n * - Login configuration (SSO, credentials, or both)\n * - Current user (if authenticated)\n * - Available capabilities (user awareness, session, SSO, RBAC, ACL, audit)\n * - User access (roles and permissions)\n *\n * @example\n * ```tsx\n * import { useAuthCapabilities } from '@mastra/react/hooks/auth';\n *\n * function AuthStatus() {\n * const { data: capabilities, isLoading } = useAuthCapabilities();\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (!capabilities?.enabled) return <div>Auth not enabled</div>;\n *\n * if (isAuthenticated(capabilities)) {\n * return <div>Welcome, {capabilities.user.name}</div>;\n * }\n *\n * return <LoginButton config={capabilities.login} />;\n * }\n * ```\n */\nexport function useAuthCapabilities<TData = AuthCapabilities>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<AuthCapabilities, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery<AuthCapabilities, Error, TData>({\n queryKey: ['auth', 'capabilities', getClientQueryKey(client)],\n queryFn: () => makeAuthCapabilitiesRequest(client),\n staleTime: 60 * 1000, // Cache for 1 minute\n retry: false, // Don't retry auth requests\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { fetchWithRefresh } from './fetch-with-refresh';\nimport type { CurrentUser } from './types';\n\nconst AUTH_TRANSIENT_MAX_RETRIES = 3;\nconst AUTH_TRANSIENT_MAX_BACKOFF_MS = 8_000;\n\nexport class CurrentUserError extends Error {\n constructor(public readonly status: number) {\n super(`Failed to fetch current user: ${status}`);\n this.name = 'CurrentUserError';\n }\n}\n\nexport function isUnauthenticatedError(error: unknown): boolean {\n return error instanceof CurrentUserError && error.status === 401;\n}\n\n/**\n * Hook to fetch the current authenticated user.\n *\n * Returns the current user if authenticated, null otherwise.\n * Includes roles and permissions if RBAC is available.\n *\n * Uses fetchWithRefresh to automatically refresh the session on 401 errors,\n * preventing users from being logged out when the access token expires.\n *\n * @example\n * ```tsx\n * import { useCurrentUser } from '@mastra/react/hooks/auth';\n *\n * function UserMenu() {\n * const { data: user, isLoading } = useCurrentUser();\n *\n * if (isLoading) return <Skeleton />;\n * if (!user) return <LoginButton />;\n *\n * return (\n * <Menu>\n * <Avatar src={user.avatarUrl} />\n * <span>{user.name || user.email}</span>\n * </Menu>\n * );\n * }\n * ```\n */\nexport function useCurrentUser<TData = CurrentUser>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<CurrentUser, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const baseUrl = client.options?.baseUrl || '';\n\n return useQuery<CurrentUser, Error, TData>({\n queryKey: ['auth', 'me'],\n queryFn: async () => {\n const response = await fetchWithRefresh(baseUrl, `${baseUrl}/api/auth/me`, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new CurrentUserError(response.status);\n }\n\n return response.json();\n },\n staleTime: 60 * 1000, // Cache for 1 minute\n // Retry the /api/auth/me query on transient auth-provider failures (HTTP 503)\n // so the UI stays in `isLoading` instead of flipping to `isError` and\n // triggering login — that redirect is what fed the WorkOS 429 lockout loop\n // (PLTFRM-1270). 401 (terminal) still fails fast.\n retry: (failureCount, error) => {\n if (!(error instanceof CurrentUserError)) return false;\n if (error.status !== 503) return false;\n return failureCount < AUTH_TRANSIENT_MAX_RETRIES;\n },\n retryDelay: attemptIndex => Math.min(AUTH_TRANSIENT_MAX_BACKOFF_MS, 500 * 2 ** attemptIndex),\n ...queryOptions,\n });\n}\n","import type { MastraClient, PermissionPattern } from '@mastra/client-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport { isAuthenticated } from './types';\nimport { useAuthCapabilities } from './use-auth-capabilities';\n\n/**\n * Fetches the authoritative set of permission patterns from the server\n * (`GET /auth/permission-patterns`).\n *\n * The server owns the permission source of truth (generated from the route\n * registry), so the browser never imports the server-only `@mastra/core/auth/ee`\n * code just to validate hardcoded route-permission literals.\n *\n * The request only fires when RBAC is actually enabled — when auth is off or\n * RBAC isn't configured, route gating is a no-op so the pattern vocabulary is\n * not needed, and we avoid an unnecessary (and potentially 403/401) call.\n */\ntype PermissionPatternsResponse = Awaited<ReturnType<MastraClient['getPermissionPatterns']>>;\n\nexport const usePermissionPatterns = ({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<PermissionPatternsResponse> } = {}) => {\n const client = useMastraClient();\n const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();\n\n const rbacEnabled = !!(capabilities && isAuthenticated(capabilities) && capabilities.capabilities.rbac);\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['permission-patterns', getClientQueryKey(client)],\n queryFn: () => client.getPermissionPatterns(),\n // Only fetch the pattern vocabulary when RBAC gating is in effect.\n enabled: rbacEnabled,\n // The endpoint requires auth; on 403/401 we don't want React Query to\n // thrash with retries (which toggles isLoading and re-triggers redirect\n // guards). One attempt is enough — gating falls back to the user's\n // permissions if the pattern set is empty.\n retry: false,\n staleTime: Infinity,\n ...queryOptions,\n });\n\n const patterns = useMemo(() => new Set<PermissionPattern>(data?.patterns ?? []), [data]);\n\n // While capabilities are resolving we don't yet know whether RBAC applies, so\n // report loading. Once RBAC is ruled out, this hook is never \"loading\".\n return { patterns, isLoading: capabilitiesLoading || (rbacEnabled && isLoading), error: capabilitiesError || error };\n};\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsLoginRequest = {\n email: string;\n password: string;\n};\n\nexport type CredentialsLoginResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to login with email/password credentials.\n *\n * Uses Better Auth's email sign-in endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsLogin } from '@mastra/react/hooks/auth';\n *\n * function LoginForm() {\n * const { mutate: login, isPending, error } = useCredentialsLogin();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * login({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign in\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-in request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsLoginRequest(\n client: MastraClient,\n { email, password }: CredentialsLoginRequest,\n): Promise<CredentialsLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-in`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Invalid email or password');\n }\n\n return data;\n}\n\nexport function useCredentialsLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsLoginResponse, CredentialsLoginRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsLoginResponse, Error, CredentialsLoginRequest>({\n mutationFn: ({ email, password }) => makeCredentialsLoginRequest(client, { email, password }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsSignUpRequest = {\n email: string;\n password: string;\n name?: string;\n};\n\nexport type CredentialsSignUpResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to sign up with email/password credentials.\n *\n * Uses Better Auth's email sign-up endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsSignUp } from '@mastra/react/hooks/auth';\n *\n * function SignUpForm() {\n * const { mutate: signUp, isPending, error } = useCredentialsSignUp();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * signUp({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * name: formData.get('name') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"name\" type=\"text\" />\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign up\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-up request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsSignUpRequest(\n client: MastraClient,\n { email, password, name }: CredentialsSignUpRequest,\n): Promise<CredentialsSignUpResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-up`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password, name }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Failed to create account');\n }\n\n return data;\n}\n\nexport function useCredentialsSignUp({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsSignUpResponse, CredentialsSignUpRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsSignUpResponse, Error, CredentialsSignUpRequest>({\n mutationFn: ({ email, password, name }) => makeCredentialsSignUpRequest(client, { email, password, name }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nimport { makeSSOLoginRequest } from './sso-login';\nimport type { LogoutResponse } from './types';\n\n/**\n * Hook to initiate SSO login.\n *\n * Returns mutation to get the SSO login URL and redirect.\n *\n * @example\n * ```tsx\n * import { useSSOLogin } from '@mastra/react/hooks/auth';\n *\n * function SSOLoginButton() {\n * const { mutate: login, isPending } = useSSOLogin();\n *\n * const handleClick = () => {\n * login({ redirectUri: window.location.href }, {\n * onSuccess: (data) => {\n * window.location.href = data.url;\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleClick} disabled={isPending}>\n * Sign in with SSO\n * </button>\n * );\n * }\n * ```\n */\ntype SSOLoginResponse = Awaited<ReturnType<typeof makeSSOLoginRequest>>;\n\nexport function useSSOLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<SSOLoginResponse, { redirectUri?: string }> } = {}) {\n const client = useMastraClient();\n\n return useMutation({\n mutationFn: ({ redirectUri }: { redirectUri?: string }) => makeSSOLoginRequest(client, { redirectUri }),\n ...queryOptions,\n });\n}\n\n/**\n * Hook to logout the current user.\n *\n * Destroys the current session and optionally redirects to\n * the SSO logout URL if available.\n *\n * @example\n * ```tsx\n * import { useLogout } from '@mastra/react/hooks/auth';\n *\n * function LogoutButton({ userId }: { userId: string }) {\n * const { mutate: logout, isPending } = useLogout();\n * const queryClient = useQueryClient();\n *\n * const handleLogout = () => {\n * logout({ userId }, {\n * onSuccess: (data) => {\n * queryClient.invalidateQueries({ queryKey: ['auth'] });\n * if (data.redirectTo) {\n * window.location.href = data.redirectTo;\n * } else {\n * window.location.reload();\n * }\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleLogout} disabled={isPending}>\n * Sign out\n * </button>\n * );\n * }\n * ```\n */\n/**\n * Makes a logout request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeLogoutRequest(client: Pick<MastraClient, 'options'>): Promise<LogoutResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/logout`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to logout: ${response.status}`);\n }\n\n return response.json();\n}\n\nexport interface UseLogoutOptions {\n /**\n * Runs once the server has ended the session, before the mutation resolves.\n * Failures are ignored so cleanup never turns a completed sign-out into an error.\n */\n onLoggedOut?: (variables: { userId: string }) => Promise<void>;\n queryOptions?: MastraMutationOptions<LogoutResponse, { userId: string }>;\n}\n\nexport function useLogout({ onLoggedOut, queryOptions }: UseLogoutOptions = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<LogoutResponse, Error, { userId: string }>({\n mutationFn: async variables => {\n const response = await makeLogoutRequest(client);\n await onLoggedOut?.(variables).catch(() => {});\n return response;\n },\n onSuccess: () => {\n // Invalidate all auth-related queries\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMemo","useMastraClient","useQueryClient","useMutation","useMastraClient","useQueryClient","useMutation","useMastraClient","useMutation","useQueryClient"],"sources":["../../../src/hooks/auth/types.ts","../../../src/hooks/auth/fetch-with-refresh.ts","../../../src/hooks/auth/get-client-query-key.ts","../../../src/hooks/auth/sso-login.ts","../../../src/hooks/auth/use-auth-capabilities.ts","../../../src/hooks/auth/use-current-user.ts","../../../src/hooks/auth/use-permission-patterns.ts","../../../src/hooks/auth/use-credentials-login.ts","../../../src/hooks/auth/use-credentials-signup.ts","../../../src/hooks/auth/use-auth-actions.ts"],"sourcesContent":["/**\n * Auth types for EE authentication in playground-ui.\n *\n * These types mirror the server schemas from @mastra/server.\n */\n\n/**\n * SSO configuration for login\n */\nexport type SSOConfig = {\n provider: string;\n text: string;\n icon?: string;\n description?: string;\n url: string;\n};\n\n/**\n * Login configuration\n */\nexport type LoginConfig = {\n type: 'sso' | 'credentials' | 'both';\n /** Whether sign-up is enabled (defaults to true) */\n signUpEnabled?: boolean;\n /** Optional description explaining the auth requirement and what credentials to use */\n description?: string;\n sso?: SSOConfig;\n} | null;\n\n/**\n * Public capabilities (unauthenticated)\n */\nexport type PublicAuthCapabilities = {\n enabled: boolean;\n login: LoginConfig;\n};\n\n/**\n * Authenticated user information\n */\nexport type AuthenticatedUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n};\n\n/**\n * Capability flags\n */\nexport type CapabilityFlags = {\n user: boolean;\n session: boolean;\n sso: boolean;\n rbac: boolean;\n acl: boolean;\n};\n\n/**\n * User access information\n */\nexport type UserAccess = {\n roles: string[];\n permissions: string[];\n} | null;\n\n/**\n * Authenticated capabilities (extends public)\n */\nexport type AuthenticatedCapabilities = PublicAuthCapabilities & {\n user: AuthenticatedUser;\n capabilities: CapabilityFlags;\n access: UserAccess;\n /** Available roles in the system (only present for admin users) */\n availableRoles?: { id: string; name: string }[];\n};\n\n/**\n * Auth capabilities response (union of public and authenticated)\n */\nexport type AuthCapabilities = PublicAuthCapabilities | AuthenticatedCapabilities;\n\n/**\n * Current user response (may be null if not authenticated)\n */\nexport type CurrentUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n roles?: string[];\n permissions?: string[];\n} | null;\n\n/**\n * SSO callback response\n */\nexport type SSOCallbackResponse = {\n success: boolean;\n user?: AuthenticatedUser;\n redirectTo?: string;\n};\n\n/**\n * Logout response\n */\nexport type LogoutResponse = {\n success: boolean;\n redirectTo?: string;\n};\n\n/**\n * Type guard to check if capabilities include authenticated user\n */\nexport function isAuthenticated(capabilities: AuthCapabilities): capabilities is AuthenticatedCapabilities {\n return 'user' in capabilities && capabilities.user !== undefined;\n}\n","/**\n * Fetch wrapper for the Mastra server API.\n *\n * ⚠️ MIRRORS: `platform/frontend/src/shared/lib/fetch-with-refresh.ts`\n *\n * Both files must stay behaviourally in lockstep — the platform dashboard and\n * the embedded playground both talk to WorkOS-backed auth and both would be\n * vulnerable to the same 429 lockout loop if either regressed. If you change\n * one, change the other in the same PR (or extract to a shared package —\n * currently blocked by the platform/mastra-ai monorepo boundary).\n *\n * ---\n *\n * The server middleware already refreshes the WorkOS session transparently\n * on every protected request. There is no scenario where the client can\n * succeed by calling /auth/refresh after a 401 — that endpoint hits the\n * same broken WorkOS with the same session and would only amplify transient\n * failures into forced logout (PLTFRM-1270).\n *\n * These are pass-throughs today. The names and signatures are preserved for\n * compatibility with existing call sites (`App.tsx`, `use-current-user.ts`).\n * Transient-failure retry belongs one level up — in React Query's `retry`\n * config on individual queries — not in a fetch wrapper that would compound\n * with the query-level retry.\n */\n\nexport async function fetchWithRefresh(\n _baseUrl: string,\n input: RequestInfo | URL,\n init?: RequestInit,\n): Promise<Response> {\n return fetch(input, init);\n}\n\nexport function createFetchWithRefresh(_baseUrl?: string, _apiPrefix?: string): typeof fetch {\n return (input, init) => fetch(input, init);\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nconst clientQueryKeys = new WeakMap<MastraClient, number>();\nlet nextClientQueryKey = 0;\n\n/**\n * Returns a stable, non-sensitive query key for a Mastra client instance.\n * A new client is created whenever its connection options change.\n */\nexport function getClientQueryKey(client: MastraClient) {\n const existingKey = clientQueryKeys.get(client);\n if (existingKey !== undefined) return existingKey;\n\n const queryKey = nextClientQueryKey++;\n clientQueryKeys.set(client, queryKey);\n return queryKey;\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nexport type SSOLoginResponse = {\n url: string;\n};\n\nexport async function makeSSOLoginRequest(\n client: Pick<MastraClient, 'options'>,\n { redirectUri }: { redirectUri?: string },\n): Promise<SSOLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const params = new URLSearchParams();\n if (redirectUri) {\n params.set('redirect_uri', redirectUri);\n }\n\n const url = `${baseUrl}${prefix}/auth/sso/login${params.toString() ? `?${params}` : ''}`;\n\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to initiate SSO login: ${response.status}`);\n }\n\n return response.json();\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport type { AuthCapabilities } from './types';\n\n/**\n * Makes a request to the auth capabilities endpoint.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeAuthCapabilitiesRequest(client: MastraClient): Promise<AuthCapabilities> {\n const { baseUrl = '', headers: clientHeaders = {}, apiPrefix } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/capabilities`, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch auth capabilities: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Hook to fetch authentication capabilities.\n *\n * Returns server-authoritative capability detection including:\n * - Whether auth is enabled\n * - Login configuration (SSO, credentials, or both)\n * - Current user (if authenticated)\n * - Available capabilities (user awareness, session, SSO, RBAC, ACL, audit)\n * - User access (roles and permissions)\n *\n * @example\n * ```tsx\n * import { useAuthCapabilities } from '@mastra/react/hooks/auth';\n *\n * function AuthStatus() {\n * const { data: capabilities, isLoading } = useAuthCapabilities();\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (!capabilities?.enabled) return <div>Auth not enabled</div>;\n *\n * if (isAuthenticated(capabilities)) {\n * return <div>Welcome, {capabilities.user.name}</div>;\n * }\n *\n * return <LoginButton config={capabilities.login} />;\n * }\n * ```\n */\nexport function useAuthCapabilities<TData = AuthCapabilities>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<AuthCapabilities, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery<AuthCapabilities, Error, TData>({\n queryKey: ['auth', 'capabilities', getClientQueryKey(client)],\n queryFn: () => makeAuthCapabilitiesRequest(client),\n staleTime: 60 * 1000, // Cache for 1 minute\n retry: false, // Don't retry auth requests\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { fetchWithRefresh } from './fetch-with-refresh';\nimport type { CurrentUser } from './types';\n\nconst AUTH_TRANSIENT_MAX_RETRIES = 3;\nconst AUTH_TRANSIENT_MAX_BACKOFF_MS = 8_000;\n\nexport class CurrentUserError extends Error {\n constructor(public readonly status: number) {\n super(`Failed to fetch current user: ${status}`);\n this.name = 'CurrentUserError';\n }\n}\n\nexport function isUnauthenticatedError(error: unknown): boolean {\n return error instanceof CurrentUserError && error.status === 401;\n}\n\n/**\n * Hook to fetch the current authenticated user.\n *\n * Returns the current user if authenticated, null otherwise.\n * Includes roles and permissions if RBAC is available.\n *\n * Uses fetchWithRefresh to automatically refresh the session on 401 errors,\n * preventing users from being logged out when the access token expires.\n *\n * @example\n * ```tsx\n * import { useCurrentUser } from '@mastra/react/hooks/auth';\n *\n * function UserMenu() {\n * const { data: user, isLoading } = useCurrentUser();\n *\n * if (isLoading) return <Skeleton />;\n * if (!user) return <LoginButton />;\n *\n * return (\n * <Menu>\n * <Avatar src={user.avatarUrl} />\n * <span>{user.name || user.email}</span>\n * </Menu>\n * );\n * }\n * ```\n */\nexport function useCurrentUser<TData = CurrentUser>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<CurrentUser, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const baseUrl = client.options?.baseUrl || '';\n\n return useQuery<CurrentUser, Error, TData>({\n queryKey: ['auth', 'me'],\n queryFn: async () => {\n const response = await fetchWithRefresh(baseUrl, `${baseUrl}/api/auth/me`, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new CurrentUserError(response.status);\n }\n\n return response.json();\n },\n staleTime: 60 * 1000, // Cache for 1 minute\n // Retry the /api/auth/me query on transient auth-provider failures (HTTP 503)\n // so the UI stays in `isLoading` instead of flipping to `isError` and\n // triggering login — that redirect is what fed the WorkOS 429 lockout loop\n // (PLTFRM-1270). 401 (terminal) still fails fast.\n retry: (failureCount, error) => {\n if (!(error instanceof CurrentUserError)) return false;\n if (error.status !== 503) return false;\n return failureCount < AUTH_TRANSIENT_MAX_RETRIES;\n },\n retryDelay: attemptIndex => Math.min(AUTH_TRANSIENT_MAX_BACKOFF_MS, 500 * 2 ** attemptIndex),\n ...queryOptions,\n });\n}\n","import type { MastraClient, PermissionPattern } from '@mastra/client-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport { isAuthenticated } from './types';\nimport { useAuthCapabilities } from './use-auth-capabilities';\n\n/**\n * Fetches the authoritative set of permission patterns from the server\n * (`GET /auth/permission-patterns`).\n *\n * The server owns the permission source of truth (generated from the route\n * registry), so the browser never imports the server-only `@mastra/core/auth/ee`\n * code just to validate hardcoded route-permission literals.\n *\n * The request only fires when RBAC is actually enabled — when auth is off or\n * RBAC isn't configured, route gating is a no-op so the pattern vocabulary is\n * not needed, and we avoid an unnecessary (and potentially 403/401) call.\n */\ntype PermissionPatternsResponse = Awaited<ReturnType<MastraClient['getPermissionPatterns']>>;\n\nexport const usePermissionPatterns = ({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<PermissionPatternsResponse> } = {}) => {\n const client = useMastraClient();\n const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();\n\n const rbacEnabled = !!(capabilities && isAuthenticated(capabilities) && capabilities.capabilities.rbac);\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['permission-patterns', getClientQueryKey(client)],\n queryFn: () => client.getPermissionPatterns(),\n // Only fetch the pattern vocabulary when RBAC gating is in effect.\n enabled: rbacEnabled,\n // The endpoint requires auth; on 403/401 we don't want React Query to\n // thrash with retries (which toggles isLoading and re-triggers redirect\n // guards). One attempt is enough — gating falls back to the user's\n // permissions if the pattern set is empty.\n retry: false,\n staleTime: Infinity,\n ...queryOptions,\n });\n\n const patterns = useMemo(() => new Set<PermissionPattern>(data?.patterns ?? []), [data]);\n\n // While capabilities are resolving we don't yet know whether RBAC applies, so\n // report loading. Once RBAC is ruled out, this hook is never \"loading\".\n return { patterns, isLoading: capabilitiesLoading || (rbacEnabled && isLoading), error: capabilitiesError || error };\n};\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsLoginRequest = {\n email: string;\n password: string;\n};\n\nexport type CredentialsLoginResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to login with email/password credentials.\n *\n * Uses Better Auth's email sign-in endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsLogin } from '@mastra/react/hooks/auth';\n *\n * function LoginForm() {\n * const { mutate: login, isPending, error } = useCredentialsLogin();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * login({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign in\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-in request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsLoginRequest(\n client: MastraClient,\n { email, password }: CredentialsLoginRequest,\n): Promise<CredentialsLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-in`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Invalid email or password');\n }\n\n return data;\n}\n\nexport function useCredentialsLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsLoginResponse, CredentialsLoginRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsLoginResponse, Error, CredentialsLoginRequest>({\n mutationFn: ({ email, password }) => makeCredentialsLoginRequest(client, { email, password }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsSignUpRequest = {\n email: string;\n password: string;\n name?: string;\n};\n\nexport type CredentialsSignUpResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to sign up with email/password credentials.\n *\n * Uses Better Auth's email sign-up endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsSignUp } from '@mastra/react/hooks/auth';\n *\n * function SignUpForm() {\n * const { mutate: signUp, isPending, error } = useCredentialsSignUp();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * signUp({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * name: formData.get('name') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"name\" type=\"text\" />\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign up\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-up request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsSignUpRequest(\n client: MastraClient,\n { email, password, name }: CredentialsSignUpRequest,\n): Promise<CredentialsSignUpResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-up`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password, name }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Failed to create account');\n }\n\n return data;\n}\n\nexport function useCredentialsSignUp({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsSignUpResponse, CredentialsSignUpRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsSignUpResponse, Error, CredentialsSignUpRequest>({\n mutationFn: ({ email, password, name }) => makeCredentialsSignUpRequest(client, { email, password, name }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nimport { makeSSOLoginRequest } from './sso-login';\nimport type { LogoutResponse } from './types';\n\n/**\n * Hook to initiate SSO login.\n *\n * Returns mutation to get the SSO login URL and redirect.\n *\n * @example\n * ```tsx\n * import { useSSOLogin } from '@mastra/react/hooks/auth';\n *\n * function SSOLoginButton() {\n * const { mutate: login, isPending } = useSSOLogin();\n *\n * const handleClick = () => {\n * login({ redirectUri: window.location.href }, {\n * onSuccess: (data) => {\n * window.location.href = data.url;\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleClick} disabled={isPending}>\n * Sign in with SSO\n * </button>\n * );\n * }\n * ```\n */\ntype SSOLoginResponse = Awaited<ReturnType<typeof makeSSOLoginRequest>>;\n\nexport function useSSOLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<SSOLoginResponse, { redirectUri?: string }> } = {}) {\n const client = useMastraClient();\n\n return useMutation({\n mutationFn: ({ redirectUri }: { redirectUri?: string }) => makeSSOLoginRequest(client, { redirectUri }),\n ...queryOptions,\n });\n}\n\n/**\n * Hook to logout the current user.\n *\n * Destroys the current session and optionally redirects to\n * the SSO logout URL if available.\n *\n * @example\n * ```tsx\n * import { useLogout } from '@mastra/react/hooks/auth';\n *\n * function LogoutButton({ userId }: { userId: string }) {\n * const { mutate: logout, isPending } = useLogout();\n * const queryClient = useQueryClient();\n *\n * const handleLogout = () => {\n * logout({ userId }, {\n * onSuccess: (data) => {\n * queryClient.invalidateQueries({ queryKey: ['auth'] });\n * if (data.redirectTo) {\n * window.location.href = data.redirectTo;\n * } else {\n * window.location.reload();\n * }\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleLogout} disabled={isPending}>\n * Sign out\n * </button>\n * );\n * }\n * ```\n */\n/**\n * Makes a logout request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeLogoutRequest(client: Pick<MastraClient, 'options'>): Promise<LogoutResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/logout`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to logout: ${response.status}`);\n }\n\n return response.json();\n}\n\nexport interface UseLogoutOptions {\n /**\n * Runs once the server has ended the session, before the mutation resolves.\n * Failures are ignored so cleanup never turns a completed sign-out into an error.\n */\n onLoggedOut?: (variables: { userId: string }) => Promise<void>;\n queryOptions?: MastraMutationOptions<LogoutResponse, { userId: string }>;\n}\n\nexport function useLogout({ onLoggedOut, queryOptions }: UseLogoutOptions = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<LogoutResponse, Error, { userId: string }>({\n mutationFn: async variables => {\n const response = await makeLogoutRequest(client);\n await onLoggedOut?.(variables).catch(() => {});\n return response;\n },\n onSuccess: () => {\n // Invalidate all auth-related queries\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
|
package/dist/hooks/auth/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { n as useMastraClient } from "../../mastra-client-context-
|
|
1
|
+
import { n as useMastraClient } from "../../mastra-client-context-DQ5z_ze9.js";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
|
-
|
|
4
|
+
// src/hooks/auth/types.ts
|
|
5
5
|
/**
|
|
6
6
|
* Type guard to check if capabilities include authenticated user
|
|
7
7
|
*/
|
|
8
8
|
function isAuthenticated(capabilities) {
|
|
9
9
|
return "user" in capabilities && capabilities.user !== void 0;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
//#region src/hooks/auth/fetch-with-refresh.ts
|
|
11
|
+
// src/hooks/auth/fetch-with-refresh.ts
|
|
13
12
|
/**
|
|
14
13
|
* Fetch wrapper for the Mastra server API.
|
|
15
14
|
*
|
|
@@ -41,8 +40,7 @@ async function fetchWithRefresh(_baseUrl, input, init) {
|
|
|
41
40
|
function createFetchWithRefresh(_baseUrl, _apiPrefix) {
|
|
42
41
|
return (input, init) => fetch(input, init);
|
|
43
42
|
}
|
|
44
|
-
|
|
45
|
-
//#region src/hooks/auth/get-client-query-key.ts
|
|
43
|
+
// src/hooks/auth/get-client-query-key.ts
|
|
46
44
|
const clientQueryKeys = /* @__PURE__ */ new WeakMap();
|
|
47
45
|
let nextClientQueryKey = 0;
|
|
48
46
|
/**
|
|
@@ -56,8 +54,7 @@ function getClientQueryKey(client) {
|
|
|
56
54
|
clientQueryKeys.set(client, queryKey);
|
|
57
55
|
return queryKey;
|
|
58
56
|
}
|
|
59
|
-
|
|
60
|
-
//#region src/hooks/auth/sso-login.ts
|
|
57
|
+
// src/hooks/auth/sso-login.ts
|
|
61
58
|
async function makeSSOLoginRequest(client, { redirectUri }) {
|
|
62
59
|
const { baseUrl = "", apiPrefix, headers: clientHeaders = {} } = client.options;
|
|
63
60
|
const raw = (apiPrefix || "/api").trim();
|
|
@@ -75,8 +72,7 @@ async function makeSSOLoginRequest(client, { redirectUri }) {
|
|
|
75
72
|
if (!response.ok) throw new Error(`Failed to initiate SSO login: ${response.status}`);
|
|
76
73
|
return response.json();
|
|
77
74
|
}
|
|
78
|
-
|
|
79
|
-
//#region src/hooks/auth/use-auth-capabilities.ts
|
|
75
|
+
// src/hooks/auth/use-auth-capabilities.ts
|
|
80
76
|
/**
|
|
81
77
|
* Makes a request to the auth capabilities endpoint.
|
|
82
78
|
* Exported for testing purposes.
|
|
@@ -139,8 +135,7 @@ function useAuthCapabilities({ queryOptions } = {}) {
|
|
|
139
135
|
...queryOptions
|
|
140
136
|
});
|
|
141
137
|
}
|
|
142
|
-
|
|
143
|
-
//#region src/hooks/auth/use-current-user.ts
|
|
138
|
+
// src/hooks/auth/use-current-user.ts
|
|
144
139
|
const AUTH_TRANSIENT_MAX_RETRIES = 3;
|
|
145
140
|
const AUTH_TRANSIENT_MAX_BACKOFF_MS = 8e3;
|
|
146
141
|
var CurrentUserError = class extends Error {
|
|
@@ -204,8 +199,7 @@ function useCurrentUser({ queryOptions } = {}) {
|
|
|
204
199
|
...queryOptions
|
|
205
200
|
});
|
|
206
201
|
}
|
|
207
|
-
|
|
208
|
-
//#region src/hooks/auth/use-permission-patterns.ts
|
|
202
|
+
// src/hooks/auth/use-permission-patterns.ts
|
|
209
203
|
const usePermissionPatterns = ({ queryOptions } = {}) => {
|
|
210
204
|
const client = useMastraClient();
|
|
211
205
|
const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();
|
|
@@ -224,8 +218,7 @@ const usePermissionPatterns = ({ queryOptions } = {}) => {
|
|
|
224
218
|
error: capabilitiesError || error
|
|
225
219
|
};
|
|
226
220
|
};
|
|
227
|
-
|
|
228
|
-
//#region src/hooks/auth/use-credentials-login.ts
|
|
221
|
+
// src/hooks/auth/use-credentials-login.ts
|
|
229
222
|
/**
|
|
230
223
|
* Hook to login with email/password credentials.
|
|
231
224
|
*
|
|
@@ -304,8 +297,7 @@ function useCredentialsLogin({ queryOptions } = {}) {
|
|
|
304
297
|
...queryOptions
|
|
305
298
|
});
|
|
306
299
|
}
|
|
307
|
-
|
|
308
|
-
//#region src/hooks/auth/use-credentials-signup.ts
|
|
300
|
+
// src/hooks/auth/use-credentials-signup.ts
|
|
309
301
|
/**
|
|
310
302
|
* Hook to sign up with email/password credentials.
|
|
311
303
|
*
|
|
@@ -388,8 +380,7 @@ function useCredentialsSignUp({ queryOptions } = {}) {
|
|
|
388
380
|
...queryOptions
|
|
389
381
|
});
|
|
390
382
|
}
|
|
391
|
-
|
|
392
|
-
//#region src/hooks/auth/use-auth-actions.ts
|
|
383
|
+
// src/hooks/auth/use-auth-actions.ts
|
|
393
384
|
function useSSOLogin({ queryOptions } = {}) {
|
|
394
385
|
const client = useMastraClient();
|
|
395
386
|
return useMutation({
|
|
@@ -468,7 +459,6 @@ function useLogout({ onLoggedOut, queryOptions } = {}) {
|
|
|
468
459
|
...queryOptions
|
|
469
460
|
});
|
|
470
461
|
}
|
|
471
|
-
//#endregion
|
|
472
462
|
export { CurrentUserError, createFetchWithRefresh, fetchWithRefresh, getClientQueryKey, isAuthenticated, isUnauthenticatedError, makeAuthCapabilitiesRequest, makeCredentialsLoginRequest, makeCredentialsSignUpRequest, makeLogoutRequest, makeSSOLoginRequest, useAuthCapabilities, useCredentialsLogin, useCredentialsSignUp, useCurrentUser, useLogout, usePermissionPatterns, useSSOLogin };
|
|
473
463
|
|
|
474
464
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/hooks/auth/types.ts","../../../src/hooks/auth/fetch-with-refresh.ts","../../../src/hooks/auth/get-client-query-key.ts","../../../src/hooks/auth/sso-login.ts","../../../src/hooks/auth/use-auth-capabilities.ts","../../../src/hooks/auth/use-current-user.ts","../../../src/hooks/auth/use-permission-patterns.ts","../../../src/hooks/auth/use-credentials-login.ts","../../../src/hooks/auth/use-credentials-signup.ts","../../../src/hooks/auth/use-auth-actions.ts"],"sourcesContent":["/**\n * Auth types for EE authentication in playground-ui.\n *\n * These types mirror the server schemas from @mastra/server.\n */\n\n/**\n * SSO configuration for login\n */\nexport type SSOConfig = {\n provider: string;\n text: string;\n icon?: string;\n description?: string;\n url: string;\n};\n\n/**\n * Login configuration\n */\nexport type LoginConfig = {\n type: 'sso' | 'credentials' | 'both';\n /** Whether sign-up is enabled (defaults to true) */\n signUpEnabled?: boolean;\n /** Optional description explaining the auth requirement and what credentials to use */\n description?: string;\n sso?: SSOConfig;\n} | null;\n\n/**\n * Public capabilities (unauthenticated)\n */\nexport type PublicAuthCapabilities = {\n enabled: boolean;\n login: LoginConfig;\n};\n\n/**\n * Authenticated user information\n */\nexport type AuthenticatedUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n};\n\n/**\n * Capability flags\n */\nexport type CapabilityFlags = {\n user: boolean;\n session: boolean;\n sso: boolean;\n rbac: boolean;\n acl: boolean;\n};\n\n/**\n * User access information\n */\nexport type UserAccess = {\n roles: string[];\n permissions: string[];\n} | null;\n\n/**\n * Authenticated capabilities (extends public)\n */\nexport type AuthenticatedCapabilities = PublicAuthCapabilities & {\n user: AuthenticatedUser;\n capabilities: CapabilityFlags;\n access: UserAccess;\n /** Available roles in the system (only present for admin users) */\n availableRoles?: { id: string; name: string }[];\n};\n\n/**\n * Auth capabilities response (union of public and authenticated)\n */\nexport type AuthCapabilities = PublicAuthCapabilities | AuthenticatedCapabilities;\n\n/**\n * Current user response (may be null if not authenticated)\n */\nexport type CurrentUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n roles?: string[];\n permissions?: string[];\n} | null;\n\n/**\n * SSO callback response\n */\nexport type SSOCallbackResponse = {\n success: boolean;\n user?: AuthenticatedUser;\n redirectTo?: string;\n};\n\n/**\n * Logout response\n */\nexport type LogoutResponse = {\n success: boolean;\n redirectTo?: string;\n};\n\n/**\n * Type guard to check if capabilities include authenticated user\n */\nexport function isAuthenticated(capabilities: AuthCapabilities): capabilities is AuthenticatedCapabilities {\n return 'user' in capabilities && capabilities.user !== undefined;\n}\n","/**\n * Fetch wrapper for the Mastra server API.\n *\n * ⚠️ MIRRORS: `platform/frontend/src/shared/lib/fetch-with-refresh.ts`\n *\n * Both files must stay behaviourally in lockstep — the platform dashboard and\n * the embedded playground both talk to WorkOS-backed auth and both would be\n * vulnerable to the same 429 lockout loop if either regressed. If you change\n * one, change the other in the same PR (or extract to a shared package —\n * currently blocked by the platform/mastra-ai monorepo boundary).\n *\n * ---\n *\n * The server middleware already refreshes the WorkOS session transparently\n * on every protected request. There is no scenario where the client can\n * succeed by calling /auth/refresh after a 401 — that endpoint hits the\n * same broken WorkOS with the same session and would only amplify transient\n * failures into forced logout (PLTFRM-1270).\n *\n * These are pass-throughs today. The names and signatures are preserved for\n * compatibility with existing call sites (`App.tsx`, `use-current-user.ts`).\n * Transient-failure retry belongs one level up — in React Query's `retry`\n * config on individual queries — not in a fetch wrapper that would compound\n * with the query-level retry.\n */\n\nexport async function fetchWithRefresh(\n _baseUrl: string,\n input: RequestInfo | URL,\n init?: RequestInit,\n): Promise<Response> {\n return fetch(input, init);\n}\n\nexport function createFetchWithRefresh(_baseUrl?: string, _apiPrefix?: string): typeof fetch {\n return (input, init) => fetch(input, init);\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nconst clientQueryKeys = new WeakMap<MastraClient, number>();\nlet nextClientQueryKey = 0;\n\n/**\n * Returns a stable, non-sensitive query key for a Mastra client instance.\n * A new client is created whenever its connection options change.\n */\nexport function getClientQueryKey(client: MastraClient) {\n const existingKey = clientQueryKeys.get(client);\n if (existingKey !== undefined) return existingKey;\n\n const queryKey = nextClientQueryKey++;\n clientQueryKeys.set(client, queryKey);\n return queryKey;\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nexport type SSOLoginResponse = {\n url: string;\n};\n\nexport async function makeSSOLoginRequest(\n client: Pick<MastraClient, 'options'>,\n { redirectUri }: { redirectUri?: string },\n): Promise<SSOLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const params = new URLSearchParams();\n if (redirectUri) {\n params.set('redirect_uri', redirectUri);\n }\n\n const url = `${baseUrl}${prefix}/auth/sso/login${params.toString() ? `?${params}` : ''}`;\n\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to initiate SSO login: ${response.status}`);\n }\n\n return response.json();\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport type { AuthCapabilities } from './types';\n\n/**\n * Makes a request to the auth capabilities endpoint.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeAuthCapabilitiesRequest(client: MastraClient): Promise<AuthCapabilities> {\n const { baseUrl = '', headers: clientHeaders = {}, apiPrefix } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/capabilities`, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch auth capabilities: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Hook to fetch authentication capabilities.\n *\n * Returns server-authoritative capability detection including:\n * - Whether auth is enabled\n * - Login configuration (SSO, credentials, or both)\n * - Current user (if authenticated)\n * - Available capabilities (user awareness, session, SSO, RBAC, ACL, audit)\n * - User access (roles and permissions)\n *\n * @example\n * ```tsx\n * import { useAuthCapabilities } from '@mastra/react/hooks/auth';\n *\n * function AuthStatus() {\n * const { data: capabilities, isLoading } = useAuthCapabilities();\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (!capabilities?.enabled) return <div>Auth not enabled</div>;\n *\n * if (isAuthenticated(capabilities)) {\n * return <div>Welcome, {capabilities.user.name}</div>;\n * }\n *\n * return <LoginButton config={capabilities.login} />;\n * }\n * ```\n */\nexport function useAuthCapabilities<TData = AuthCapabilities>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<AuthCapabilities, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery<AuthCapabilities, Error, TData>({\n queryKey: ['auth', 'capabilities', getClientQueryKey(client)],\n queryFn: () => makeAuthCapabilitiesRequest(client),\n staleTime: 60 * 1000, // Cache for 1 minute\n retry: false, // Don't retry auth requests\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { fetchWithRefresh } from './fetch-with-refresh';\nimport type { CurrentUser } from './types';\n\nconst AUTH_TRANSIENT_MAX_RETRIES = 3;\nconst AUTH_TRANSIENT_MAX_BACKOFF_MS = 8_000;\n\nexport class CurrentUserError extends Error {\n constructor(public readonly status: number) {\n super(`Failed to fetch current user: ${status}`);\n this.name = 'CurrentUserError';\n }\n}\n\nexport function isUnauthenticatedError(error: unknown): boolean {\n return error instanceof CurrentUserError && error.status === 401;\n}\n\n/**\n * Hook to fetch the current authenticated user.\n *\n * Returns the current user if authenticated, null otherwise.\n * Includes roles and permissions if RBAC is available.\n *\n * Uses fetchWithRefresh to automatically refresh the session on 401 errors,\n * preventing users from being logged out when the access token expires.\n *\n * @example\n * ```tsx\n * import { useCurrentUser } from '@mastra/react/hooks/auth';\n *\n * function UserMenu() {\n * const { data: user, isLoading } = useCurrentUser();\n *\n * if (isLoading) return <Skeleton />;\n * if (!user) return <LoginButton />;\n *\n * return (\n * <Menu>\n * <Avatar src={user.avatarUrl} />\n * <span>{user.name || user.email}</span>\n * </Menu>\n * );\n * }\n * ```\n */\nexport function useCurrentUser<TData = CurrentUser>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<CurrentUser, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const baseUrl = client.options?.baseUrl || '';\n\n return useQuery<CurrentUser, Error, TData>({\n queryKey: ['auth', 'me'],\n queryFn: async () => {\n const response = await fetchWithRefresh(baseUrl, `${baseUrl}/api/auth/me`, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new CurrentUserError(response.status);\n }\n\n return response.json();\n },\n staleTime: 60 * 1000, // Cache for 1 minute\n // Retry the /api/auth/me query on transient auth-provider failures (HTTP 503)\n // so the UI stays in `isLoading` instead of flipping to `isError` and\n // triggering login — that redirect is what fed the WorkOS 429 lockout loop\n // (PLTFRM-1270). 401 (terminal) still fails fast.\n retry: (failureCount, error) => {\n if (!(error instanceof CurrentUserError)) return false;\n if (error.status !== 503) return false;\n return failureCount < AUTH_TRANSIENT_MAX_RETRIES;\n },\n retryDelay: attemptIndex => Math.min(AUTH_TRANSIENT_MAX_BACKOFF_MS, 500 * 2 ** attemptIndex),\n ...queryOptions,\n });\n}\n","import type { MastraClient, PermissionPattern } from '@mastra/client-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport { isAuthenticated } from './types';\nimport { useAuthCapabilities } from './use-auth-capabilities';\n\n/**\n * Fetches the authoritative set of permission patterns from the server\n * (`GET /auth/permission-patterns`).\n *\n * The server owns the permission source of truth (generated from the route\n * registry), so the browser never imports the server-only `@mastra/core/auth/ee`\n * code just to validate hardcoded route-permission literals.\n *\n * The request only fires when RBAC is actually enabled — when auth is off or\n * RBAC isn't configured, route gating is a no-op so the pattern vocabulary is\n * not needed, and we avoid an unnecessary (and potentially 403/401) call.\n */\ntype PermissionPatternsResponse = Awaited<ReturnType<MastraClient['getPermissionPatterns']>>;\n\nexport const usePermissionPatterns = ({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<PermissionPatternsResponse> } = {}) => {\n const client = useMastraClient();\n const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();\n\n const rbacEnabled = !!(capabilities && isAuthenticated(capabilities) && capabilities.capabilities.rbac);\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['permission-patterns', getClientQueryKey(client)],\n queryFn: () => client.getPermissionPatterns(),\n // Only fetch the pattern vocabulary when RBAC gating is in effect.\n enabled: rbacEnabled,\n // The endpoint requires auth; on 403/401 we don't want React Query to\n // thrash with retries (which toggles isLoading and re-triggers redirect\n // guards). One attempt is enough — gating falls back to the user's\n // permissions if the pattern set is empty.\n retry: false,\n staleTime: Infinity,\n ...queryOptions,\n });\n\n const patterns = useMemo(() => new Set<PermissionPattern>(data?.patterns ?? []), [data]);\n\n // While capabilities are resolving we don't yet know whether RBAC applies, so\n // report loading. Once RBAC is ruled out, this hook is never \"loading\".\n return { patterns, isLoading: capabilitiesLoading || (rbacEnabled && isLoading), error: capabilitiesError || error };\n};\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsLoginRequest = {\n email: string;\n password: string;\n};\n\nexport type CredentialsLoginResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to login with email/password credentials.\n *\n * Uses Better Auth's email sign-in endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsLogin } from '@mastra/react/hooks/auth';\n *\n * function LoginForm() {\n * const { mutate: login, isPending, error } = useCredentialsLogin();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * login({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign in\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-in request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsLoginRequest(\n client: MastraClient,\n { email, password }: CredentialsLoginRequest,\n): Promise<CredentialsLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-in`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Invalid email or password');\n }\n\n return data;\n}\n\nexport function useCredentialsLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsLoginResponse, CredentialsLoginRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsLoginResponse, Error, CredentialsLoginRequest>({\n mutationFn: ({ email, password }) => makeCredentialsLoginRequest(client, { email, password }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsSignUpRequest = {\n email: string;\n password: string;\n name?: string;\n};\n\nexport type CredentialsSignUpResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to sign up with email/password credentials.\n *\n * Uses Better Auth's email sign-up endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsSignUp } from '@mastra/react/hooks/auth';\n *\n * function SignUpForm() {\n * const { mutate: signUp, isPending, error } = useCredentialsSignUp();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * signUp({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * name: formData.get('name') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"name\" type=\"text\" />\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign up\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-up request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsSignUpRequest(\n client: MastraClient,\n { email, password, name }: CredentialsSignUpRequest,\n): Promise<CredentialsSignUpResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-up`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password, name }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Failed to create account');\n }\n\n return data;\n}\n\nexport function useCredentialsSignUp({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsSignUpResponse, CredentialsSignUpRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsSignUpResponse, Error, CredentialsSignUpRequest>({\n mutationFn: ({ email, password, name }) => makeCredentialsSignUpRequest(client, { email, password, name }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nimport { makeSSOLoginRequest } from './sso-login';\nimport type { LogoutResponse } from './types';\n\n/**\n * Hook to initiate SSO login.\n *\n * Returns mutation to get the SSO login URL and redirect.\n *\n * @example\n * ```tsx\n * import { useSSOLogin } from '@mastra/react/hooks/auth';\n *\n * function SSOLoginButton() {\n * const { mutate: login, isPending } = useSSOLogin();\n *\n * const handleClick = () => {\n * login({ redirectUri: window.location.href }, {\n * onSuccess: (data) => {\n * window.location.href = data.url;\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleClick} disabled={isPending}>\n * Sign in with SSO\n * </button>\n * );\n * }\n * ```\n */\ntype SSOLoginResponse = Awaited<ReturnType<typeof makeSSOLoginRequest>>;\n\nexport function useSSOLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<SSOLoginResponse, { redirectUri?: string }> } = {}) {\n const client = useMastraClient();\n\n return useMutation({\n mutationFn: ({ redirectUri }: { redirectUri?: string }) => makeSSOLoginRequest(client, { redirectUri }),\n ...queryOptions,\n });\n}\n\n/**\n * Hook to logout the current user.\n *\n * Destroys the current session and optionally redirects to\n * the SSO logout URL if available.\n *\n * @example\n * ```tsx\n * import { useLogout } from '@mastra/react/hooks/auth';\n *\n * function LogoutButton({ userId }: { userId: string }) {\n * const { mutate: logout, isPending } = useLogout();\n * const queryClient = useQueryClient();\n *\n * const handleLogout = () => {\n * logout({ userId }, {\n * onSuccess: (data) => {\n * queryClient.invalidateQueries({ queryKey: ['auth'] });\n * if (data.redirectTo) {\n * window.location.href = data.redirectTo;\n * } else {\n * window.location.reload();\n * }\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleLogout} disabled={isPending}>\n * Sign out\n * </button>\n * );\n * }\n * ```\n */\n/**\n * Makes a logout request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeLogoutRequest(client: Pick<MastraClient, 'options'>): Promise<LogoutResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/logout`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to logout: ${response.status}`);\n }\n\n return response.json();\n}\n\nexport interface UseLogoutOptions {\n /**\n * Runs once the server has ended the session, before the mutation resolves.\n * Failures are ignored so cleanup never turns a completed sign-out into an error.\n */\n onLoggedOut?: (variables: { userId: string }) => Promise<void>;\n queryOptions?: MastraMutationOptions<LogoutResponse, { userId: string }>;\n}\n\nexport function useLogout({ onLoggedOut, queryOptions }: UseLogoutOptions = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<LogoutResponse, Error, { userId: string }>({\n mutationFn: async variables => {\n const response = await makeLogoutRequest(client);\n await onLoggedOut?.(variables).catch(() => {});\n return response;\n },\n onSuccess: () => {\n // Invalidate all auth-related queries\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/hooks/auth/types.ts","../../../src/hooks/auth/fetch-with-refresh.ts","../../../src/hooks/auth/get-client-query-key.ts","../../../src/hooks/auth/sso-login.ts","../../../src/hooks/auth/use-auth-capabilities.ts","../../../src/hooks/auth/use-current-user.ts","../../../src/hooks/auth/use-permission-patterns.ts","../../../src/hooks/auth/use-credentials-login.ts","../../../src/hooks/auth/use-credentials-signup.ts","../../../src/hooks/auth/use-auth-actions.ts"],"sourcesContent":["/**\n * Auth types for EE authentication in playground-ui.\n *\n * These types mirror the server schemas from @mastra/server.\n */\n\n/**\n * SSO configuration for login\n */\nexport type SSOConfig = {\n provider: string;\n text: string;\n icon?: string;\n description?: string;\n url: string;\n};\n\n/**\n * Login configuration\n */\nexport type LoginConfig = {\n type: 'sso' | 'credentials' | 'both';\n /** Whether sign-up is enabled (defaults to true) */\n signUpEnabled?: boolean;\n /** Optional description explaining the auth requirement and what credentials to use */\n description?: string;\n sso?: SSOConfig;\n} | null;\n\n/**\n * Public capabilities (unauthenticated)\n */\nexport type PublicAuthCapabilities = {\n enabled: boolean;\n login: LoginConfig;\n};\n\n/**\n * Authenticated user information\n */\nexport type AuthenticatedUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n};\n\n/**\n * Capability flags\n */\nexport type CapabilityFlags = {\n user: boolean;\n session: boolean;\n sso: boolean;\n rbac: boolean;\n acl: boolean;\n};\n\n/**\n * User access information\n */\nexport type UserAccess = {\n roles: string[];\n permissions: string[];\n} | null;\n\n/**\n * Authenticated capabilities (extends public)\n */\nexport type AuthenticatedCapabilities = PublicAuthCapabilities & {\n user: AuthenticatedUser;\n capabilities: CapabilityFlags;\n access: UserAccess;\n /** Available roles in the system (only present for admin users) */\n availableRoles?: { id: string; name: string }[];\n};\n\n/**\n * Auth capabilities response (union of public and authenticated)\n */\nexport type AuthCapabilities = PublicAuthCapabilities | AuthenticatedCapabilities;\n\n/**\n * Current user response (may be null if not authenticated)\n */\nexport type CurrentUser = {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n roles?: string[];\n permissions?: string[];\n} | null;\n\n/**\n * SSO callback response\n */\nexport type SSOCallbackResponse = {\n success: boolean;\n user?: AuthenticatedUser;\n redirectTo?: string;\n};\n\n/**\n * Logout response\n */\nexport type LogoutResponse = {\n success: boolean;\n redirectTo?: string;\n};\n\n/**\n * Type guard to check if capabilities include authenticated user\n */\nexport function isAuthenticated(capabilities: AuthCapabilities): capabilities is AuthenticatedCapabilities {\n return 'user' in capabilities && capabilities.user !== undefined;\n}\n","/**\n * Fetch wrapper for the Mastra server API.\n *\n * ⚠️ MIRRORS: `platform/frontend/src/shared/lib/fetch-with-refresh.ts`\n *\n * Both files must stay behaviourally in lockstep — the platform dashboard and\n * the embedded playground both talk to WorkOS-backed auth and both would be\n * vulnerable to the same 429 lockout loop if either regressed. If you change\n * one, change the other in the same PR (or extract to a shared package —\n * currently blocked by the platform/mastra-ai monorepo boundary).\n *\n * ---\n *\n * The server middleware already refreshes the WorkOS session transparently\n * on every protected request. There is no scenario where the client can\n * succeed by calling /auth/refresh after a 401 — that endpoint hits the\n * same broken WorkOS with the same session and would only amplify transient\n * failures into forced logout (PLTFRM-1270).\n *\n * These are pass-throughs today. The names and signatures are preserved for\n * compatibility with existing call sites (`App.tsx`, `use-current-user.ts`).\n * Transient-failure retry belongs one level up — in React Query's `retry`\n * config on individual queries — not in a fetch wrapper that would compound\n * with the query-level retry.\n */\n\nexport async function fetchWithRefresh(\n _baseUrl: string,\n input: RequestInfo | URL,\n init?: RequestInit,\n): Promise<Response> {\n return fetch(input, init);\n}\n\nexport function createFetchWithRefresh(_baseUrl?: string, _apiPrefix?: string): typeof fetch {\n return (input, init) => fetch(input, init);\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nconst clientQueryKeys = new WeakMap<MastraClient, number>();\nlet nextClientQueryKey = 0;\n\n/**\n * Returns a stable, non-sensitive query key for a Mastra client instance.\n * A new client is created whenever its connection options change.\n */\nexport function getClientQueryKey(client: MastraClient) {\n const existingKey = clientQueryKeys.get(client);\n if (existingKey !== undefined) return existingKey;\n\n const queryKey = nextClientQueryKey++;\n clientQueryKeys.set(client, queryKey);\n return queryKey;\n}\n","import type { MastraClient } from '@mastra/client-js';\n\nexport type SSOLoginResponse = {\n url: string;\n};\n\nexport async function makeSSOLoginRequest(\n client: Pick<MastraClient, 'options'>,\n { redirectUri }: { redirectUri?: string },\n): Promise<SSOLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const params = new URLSearchParams();\n if (redirectUri) {\n params.set('redirect_uri', redirectUri);\n }\n\n const url = `${baseUrl}${prefix}/auth/sso/login${params.toString() ? `?${params}` : ''}`;\n\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to initiate SSO login: ${response.status}`);\n }\n\n return response.json();\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport type { AuthCapabilities } from './types';\n\n/**\n * Makes a request to the auth capabilities endpoint.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeAuthCapabilitiesRequest(client: MastraClient): Promise<AuthCapabilities> {\n const { baseUrl = '', headers: clientHeaders = {}, apiPrefix } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/capabilities`, {\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch auth capabilities: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Hook to fetch authentication capabilities.\n *\n * Returns server-authoritative capability detection including:\n * - Whether auth is enabled\n * - Login configuration (SSO, credentials, or both)\n * - Current user (if authenticated)\n * - Available capabilities (user awareness, session, SSO, RBAC, ACL, audit)\n * - User access (roles and permissions)\n *\n * @example\n * ```tsx\n * import { useAuthCapabilities } from '@mastra/react/hooks/auth';\n *\n * function AuthStatus() {\n * const { data: capabilities, isLoading } = useAuthCapabilities();\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (!capabilities?.enabled) return <div>Auth not enabled</div>;\n *\n * if (isAuthenticated(capabilities)) {\n * return <div>Welcome, {capabilities.user.name}</div>;\n * }\n *\n * return <LoginButton config={capabilities.login} />;\n * }\n * ```\n */\nexport function useAuthCapabilities<TData = AuthCapabilities>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<AuthCapabilities, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery<AuthCapabilities, Error, TData>({\n queryKey: ['auth', 'capabilities', getClientQueryKey(client)],\n queryFn: () => makeAuthCapabilitiesRequest(client),\n staleTime: 60 * 1000, // Cache for 1 minute\n retry: false, // Don't retry auth requests\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { fetchWithRefresh } from './fetch-with-refresh';\nimport type { CurrentUser } from './types';\n\nconst AUTH_TRANSIENT_MAX_RETRIES = 3;\nconst AUTH_TRANSIENT_MAX_BACKOFF_MS = 8_000;\n\nexport class CurrentUserError extends Error {\n constructor(public readonly status: number) {\n super(`Failed to fetch current user: ${status}`);\n this.name = 'CurrentUserError';\n }\n}\n\nexport function isUnauthenticatedError(error: unknown): boolean {\n return error instanceof CurrentUserError && error.status === 401;\n}\n\n/**\n * Hook to fetch the current authenticated user.\n *\n * Returns the current user if authenticated, null otherwise.\n * Includes roles and permissions if RBAC is available.\n *\n * Uses fetchWithRefresh to automatically refresh the session on 401 errors,\n * preventing users from being logged out when the access token expires.\n *\n * @example\n * ```tsx\n * import { useCurrentUser } from '@mastra/react/hooks/auth';\n *\n * function UserMenu() {\n * const { data: user, isLoading } = useCurrentUser();\n *\n * if (isLoading) return <Skeleton />;\n * if (!user) return <LoginButton />;\n *\n * return (\n * <Menu>\n * <Avatar src={user.avatarUrl} />\n * <span>{user.name || user.email}</span>\n * </Menu>\n * );\n * }\n * ```\n */\nexport function useCurrentUser<TData = CurrentUser>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<CurrentUser, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const baseUrl = client.options?.baseUrl || '';\n\n return useQuery<CurrentUser, Error, TData>({\n queryKey: ['auth', 'me'],\n queryFn: async () => {\n const response = await fetchWithRefresh(baseUrl, `${baseUrl}/api/auth/me`, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new CurrentUserError(response.status);\n }\n\n return response.json();\n },\n staleTime: 60 * 1000, // Cache for 1 minute\n // Retry the /api/auth/me query on transient auth-provider failures (HTTP 503)\n // so the UI stays in `isLoading` instead of flipping to `isError` and\n // triggering login — that redirect is what fed the WorkOS 429 lockout loop\n // (PLTFRM-1270). 401 (terminal) still fails fast.\n retry: (failureCount, error) => {\n if (!(error instanceof CurrentUserError)) return false;\n if (error.status !== 503) return false;\n return failureCount < AUTH_TRANSIENT_MAX_RETRIES;\n },\n retryDelay: attemptIndex => Math.min(AUTH_TRANSIENT_MAX_BACKOFF_MS, 500 * 2 ** attemptIndex),\n ...queryOptions,\n });\n}\n","import type { MastraClient, PermissionPattern } from '@mastra/client-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nimport { getClientQueryKey } from './get-client-query-key';\nimport { isAuthenticated } from './types';\nimport { useAuthCapabilities } from './use-auth-capabilities';\n\n/**\n * Fetches the authoritative set of permission patterns from the server\n * (`GET /auth/permission-patterns`).\n *\n * The server owns the permission source of truth (generated from the route\n * registry), so the browser never imports the server-only `@mastra/core/auth/ee`\n * code just to validate hardcoded route-permission literals.\n *\n * The request only fires when RBAC is actually enabled — when auth is off or\n * RBAC isn't configured, route gating is a no-op so the pattern vocabulary is\n * not needed, and we avoid an unnecessary (and potentially 403/401) call.\n */\ntype PermissionPatternsResponse = Awaited<ReturnType<MastraClient['getPermissionPatterns']>>;\n\nexport const usePermissionPatterns = ({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<PermissionPatternsResponse> } = {}) => {\n const client = useMastraClient();\n const { data: capabilities, isLoading: capabilitiesLoading, error: capabilitiesError } = useAuthCapabilities();\n\n const rbacEnabled = !!(capabilities && isAuthenticated(capabilities) && capabilities.capabilities.rbac);\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['permission-patterns', getClientQueryKey(client)],\n queryFn: () => client.getPermissionPatterns(),\n // Only fetch the pattern vocabulary when RBAC gating is in effect.\n enabled: rbacEnabled,\n // The endpoint requires auth; on 403/401 we don't want React Query to\n // thrash with retries (which toggles isLoading and re-triggers redirect\n // guards). One attempt is enough — gating falls back to the user's\n // permissions if the pattern set is empty.\n retry: false,\n staleTime: Infinity,\n ...queryOptions,\n });\n\n const patterns = useMemo(() => new Set<PermissionPattern>(data?.patterns ?? []), [data]);\n\n // While capabilities are resolving we don't yet know whether RBAC applies, so\n // report loading. Once RBAC is ruled out, this hook is never \"loading\".\n return { patterns, isLoading: capabilitiesLoading || (rbacEnabled && isLoading), error: capabilitiesError || error };\n};\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsLoginRequest = {\n email: string;\n password: string;\n};\n\nexport type CredentialsLoginResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to login with email/password credentials.\n *\n * Uses Better Auth's email sign-in endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsLogin } from '@mastra/react/hooks/auth';\n *\n * function LoginForm() {\n * const { mutate: login, isPending, error } = useCredentialsLogin();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * login({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign in\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-in request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsLoginRequest(\n client: MastraClient,\n { email, password }: CredentialsLoginRequest,\n): Promise<CredentialsLoginResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-in`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Invalid email or password');\n }\n\n return data;\n}\n\nexport function useCredentialsLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsLoginResponse, CredentialsLoginRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsLoginResponse, Error, CredentialsLoginRequest>({\n mutationFn: ({ email, password }) => makeCredentialsLoginRequest(client, { email, password }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type CredentialsSignUpRequest = {\n email: string;\n password: string;\n name?: string;\n};\n\nexport type CredentialsSignUpResponse = {\n user?: {\n id: string;\n email: string;\n name?: string;\n };\n error?: string;\n};\n\n/**\n * Hook to sign up with email/password credentials.\n *\n * Uses Better Auth's email sign-up endpoint.\n *\n * @example\n * ```tsx\n * import { useCredentialsSignUp } from '@mastra/react/hooks/auth';\n *\n * function SignUpForm() {\n * const { mutate: signUp, isPending, error } = useCredentialsSignUp();\n *\n * const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n * e.preventDefault();\n * const formData = new FormData(e.currentTarget);\n * signUp({\n * email: formData.get('email') as string,\n * password: formData.get('password') as string,\n * name: formData.get('name') as string,\n * }, {\n * onSuccess: () => {\n * window.location.href = '/';\n * },\n * });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"name\" type=\"text\" />\n * <input name=\"email\" type=\"email\" required />\n * <input name=\"password\" type=\"password\" required />\n * <button type=\"submit\" disabled={isPending}>\n * Sign up\n * </button>\n * {error && <p>{error.message}</p>}\n * </form>\n * );\n * }\n * ```\n */\n/**\n * Makes a credentials sign-up request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeCredentialsSignUpRequest(\n client: MastraClient,\n { email, password, name }: CredentialsSignUpRequest,\n): Promise<CredentialsSignUpResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options || {};\n const raw = (apiPrefix ?? '/api').trim();\n const normalized = raw === '' ? '' : raw.startsWith('/') ? raw : `/${raw}`;\n const prefix = normalized.replace(/\\/+$/, '');\n\n // Generic Mastra auth endpoint - works with any credentials provider\n const response = await fetch(`${baseUrl}${prefix}/auth/credentials/sign-up`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ email, password, name }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(data.message || data.error || 'Failed to create account');\n }\n\n return data;\n}\n\nexport function useCredentialsSignUp({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<CredentialsSignUpResponse, CredentialsSignUpRequest> } = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<CredentialsSignUpResponse, Error, CredentialsSignUpRequest>({\n mutationFn: ({ email, password, name }) => makeCredentialsSignUpRequest(client, { email, password, name }),\n onSuccess: () => {\n // Invalidate auth queries to refetch user state\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nimport { makeSSOLoginRequest } from './sso-login';\nimport type { LogoutResponse } from './types';\n\n/**\n * Hook to initiate SSO login.\n *\n * Returns mutation to get the SSO login URL and redirect.\n *\n * @example\n * ```tsx\n * import { useSSOLogin } from '@mastra/react/hooks/auth';\n *\n * function SSOLoginButton() {\n * const { mutate: login, isPending } = useSSOLogin();\n *\n * const handleClick = () => {\n * login({ redirectUri: window.location.href }, {\n * onSuccess: (data) => {\n * window.location.href = data.url;\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleClick} disabled={isPending}>\n * Sign in with SSO\n * </button>\n * );\n * }\n * ```\n */\ntype SSOLoginResponse = Awaited<ReturnType<typeof makeSSOLoginRequest>>;\n\nexport function useSSOLogin({\n queryOptions,\n}: { queryOptions?: MastraMutationOptions<SSOLoginResponse, { redirectUri?: string }> } = {}) {\n const client = useMastraClient();\n\n return useMutation({\n mutationFn: ({ redirectUri }: { redirectUri?: string }) => makeSSOLoginRequest(client, { redirectUri }),\n ...queryOptions,\n });\n}\n\n/**\n * Hook to logout the current user.\n *\n * Destroys the current session and optionally redirects to\n * the SSO logout URL if available.\n *\n * @example\n * ```tsx\n * import { useLogout } from '@mastra/react/hooks/auth';\n *\n * function LogoutButton({ userId }: { userId: string }) {\n * const { mutate: logout, isPending } = useLogout();\n * const queryClient = useQueryClient();\n *\n * const handleLogout = () => {\n * logout({ userId }, {\n * onSuccess: (data) => {\n * queryClient.invalidateQueries({ queryKey: ['auth'] });\n * if (data.redirectTo) {\n * window.location.href = data.redirectTo;\n * } else {\n * window.location.reload();\n * }\n * },\n * });\n * };\n *\n * return (\n * <button onClick={handleLogout} disabled={isPending}>\n * Sign out\n * </button>\n * );\n * }\n * ```\n */\n/**\n * Makes a logout request.\n * Exported for testing purposes.\n *\n * @internal\n */\nexport async function makeLogoutRequest(client: Pick<MastraClient, 'options'>): Promise<LogoutResponse> {\n const { baseUrl = '', apiPrefix, headers: clientHeaders = {} } = client.options;\n const raw = (apiPrefix || '/api').trim();\n const prefix = (raw.startsWith('/') ? raw : `/${raw}`).replace(/\\/$/, '');\n\n const response = await fetch(`${baseUrl}${prefix}/auth/logout`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...clientHeaders,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to logout: ${response.status}`);\n }\n\n return response.json();\n}\n\nexport interface UseLogoutOptions {\n /**\n * Runs once the server has ended the session, before the mutation resolves.\n * Failures are ignored so cleanup never turns a completed sign-out into an error.\n */\n onLoggedOut?: (variables: { userId: string }) => Promise<void>;\n queryOptions?: MastraMutationOptions<LogoutResponse, { userId: string }>;\n}\n\nexport function useLogout({ onLoggedOut, queryOptions }: UseLogoutOptions = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation<LogoutResponse, Error, { userId: string }>({\n mutationFn: async variables => {\n const response = await makeLogoutRequest(client);\n await onLoggedOut?.(variables).catch(() => {});\n return response;\n },\n onSuccess: () => {\n // Invalidate all auth-related queries\n void queryClient.invalidateQueries({ queryKey: ['auth'] });\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
|