mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:01:08 +02:00
fix(mana-auth): add session-to-token endpoint and return JWT from login
The client (shared-auth) calls /api/v1/auth/session-to-token for SSO and
2FA flows, but this endpoint was never implemented. Also, the login endpoint
returned raw Better Auth session data instead of the expected
{ accessToken, refreshToken } format.
- Add POST /api/v1/auth/session-to-token endpoint
- Fix login to generate JWT via Better Auth's /api/auth/token
- Fix refresh to return JWT instead of raw session data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0d6005dbcc
commit
8ffd2ce774
1 changed files with 85 additions and 3 deletions
|
|
@ -108,6 +108,27 @@ export function createAuthRoutes(
|
|||
lockout.clearAttempts(body.email);
|
||||
}
|
||||
|
||||
// signInEmail returns { token (session token), user, redirect }
|
||||
// Use the session token to call Better Auth's JWT /token endpoint
|
||||
const sessionToken = response?.token;
|
||||
if (sessionToken) {
|
||||
const tokenResponse = await auth.handler(
|
||||
new Request(new URL('/api/auth/token', config.baseUrl), {
|
||||
method: 'GET',
|
||||
headers: new Headers({ cookie: `mana.session_token=${sessionToken}` }),
|
||||
})
|
||||
);
|
||||
|
||||
if (tokenResponse.ok) {
|
||||
const tokenData = await tokenResponse.json();
|
||||
return c.json({
|
||||
...response,
|
||||
accessToken: tokenData.token,
|
||||
refreshToken: sessionToken,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return c.json(response);
|
||||
} catch (error) {
|
||||
security.logEvent({
|
||||
|
|
@ -120,6 +141,47 @@ export function createAuthRoutes(
|
|||
}
|
||||
});
|
||||
|
||||
// ─── Session → JWT Token Exchange ───────────────────────
|
||||
// Used by SSO (trySSO) and after 2FA verification to get JWT from session cookie
|
||||
|
||||
app.post('/session-to-token', async (c) => {
|
||||
// First verify the session is valid
|
||||
const sessionResponse = await auth.handler(
|
||||
new Request(new URL('/api/auth/get-session', config.baseUrl), {
|
||||
method: 'GET',
|
||||
headers: c.req.raw.headers,
|
||||
})
|
||||
);
|
||||
|
||||
if (!sessionResponse.ok) {
|
||||
return c.json({ error: 'No valid session' }, 401);
|
||||
}
|
||||
|
||||
const sessionData = await sessionResponse.json();
|
||||
if (!sessionData?.session?.token) {
|
||||
return c.json({ error: 'No valid session' }, 401);
|
||||
}
|
||||
|
||||
// Generate JWT from the session
|
||||
const tokenResponse = await auth.handler(
|
||||
new Request(new URL('/api/auth/token', config.baseUrl), {
|
||||
method: 'GET',
|
||||
headers: c.req.raw.headers,
|
||||
})
|
||||
);
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
return c.json({ error: 'Token generation failed' }, 500);
|
||||
}
|
||||
|
||||
const tokenData = await tokenResponse.json();
|
||||
return c.json({
|
||||
accessToken: tokenData.token,
|
||||
// Session token serves as refresh mechanism via session cookie
|
||||
refreshToken: sessionData.session.token,
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Token Validation ────────────────────────────────────
|
||||
|
||||
app.post('/validate', async (c) => {
|
||||
|
|
@ -160,14 +222,34 @@ export function createAuthRoutes(
|
|||
});
|
||||
|
||||
app.post('/refresh', async (c) => {
|
||||
const body = await c.req.json();
|
||||
// Better Auth handles refresh via session cookies
|
||||
return auth.handler(
|
||||
// Generate a fresh JWT from the session cookie
|
||||
const tokenResponse = await auth.handler(
|
||||
new Request(new URL('/api/auth/token', config.baseUrl), {
|
||||
method: 'GET',
|
||||
headers: c.req.raw.headers,
|
||||
})
|
||||
);
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
return c.json({ error: 'Session expired' }, 401);
|
||||
}
|
||||
|
||||
const tokenData = await tokenResponse.json();
|
||||
|
||||
// Also get session data for the refresh token
|
||||
const sessionResponse = await auth.handler(
|
||||
new Request(new URL('/api/auth/get-session', config.baseUrl), {
|
||||
method: 'GET',
|
||||
headers: c.req.raw.headers,
|
||||
})
|
||||
);
|
||||
|
||||
const sessionData = sessionResponse.ok ? await sessionResponse.json() : null;
|
||||
|
||||
return c.json({
|
||||
accessToken: tokenData.token,
|
||||
refreshToken: sessionData?.session?.token,
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Password Management ─────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue