19e1a4fca3
- Add _verify-token.get.ts to both operator and portal — decodes the access token stored in the nuxt-oidc-auth session and echoes iss/aud/ sub/groups. Used to confirm operator tokens carry aud=dezky-operator and portal tokens carry aud=dezky-portal. Listed in NEXT-STEPS.md as throwaway, to be removed when proper verification surfaces exist. - OPERATOR-PLAN.md O.9 marked done with the actual claims captured + the Mongo-side verification of attach + suspend flows. - NEXT-STEPS.md: replaced the "Operator portal — out-of-band track" section with a "shipped + follow-ups" version. The 9-item follow-up list (impersonation, audit, flags, incidents, support, partner portal, env switcher, on-call, workspace impersonation) is now the authoritative roadmap, not buried inside OPERATOR-PLAN.md.
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
// Throwaway verification endpoint for O.9: decodes the access token currently
|
|
// stored in the operator's nuxt-oidc-auth session and returns the claims we
|
|
// care about (iss, aud, sub, exp, groups). NEVER returns the raw token. Safe
|
|
// to leave deployed since it requires a valid operator session and only
|
|
// echoes claims the user can already see in their JWT.
|
|
|
|
import { getUserSession } from 'nuxt-oidc-auth/runtime/server/utils/session.js'
|
|
|
|
function decodeJwtClaims(token: string): Record<string, unknown> {
|
|
const parts = token.split('.')
|
|
if (parts.length < 2) throw new Error('Not a JWT')
|
|
const payload = parts[1].replace(/-/g, '+').replace(/_/g, '/')
|
|
const padded = payload + '='.repeat((4 - (payload.length % 4)) % 4)
|
|
return JSON.parse(Buffer.from(padded, 'base64').toString('utf8'))
|
|
}
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const session = await getUserSession(event).catch(() => null)
|
|
const accessToken = (session as { accessToken?: string } | null)?.accessToken
|
|
if (!accessToken) throw createError({ statusCode: 401, statusMessage: 'No session' })
|
|
|
|
const claims = decodeJwtClaims(accessToken)
|
|
return {
|
|
iss: claims.iss,
|
|
aud: claims.aud,
|
|
sub: claims.sub,
|
|
email: claims.email,
|
|
groups: claims.groups,
|
|
exp: claims.exp,
|
|
iat: claims.iat,
|
|
}
|
|
})
|