56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import type { FastifyInstance } from 'fastify'
|
|
import {
|
|
allPermissionKeys,
|
|
normalizePermissionKeys,
|
|
tenantsClaimForUser,
|
|
type LoginResponse,
|
|
} from '@authportal/shared'
|
|
import {
|
|
getAppSwitcherConfig,
|
|
getUserApps,
|
|
getUserPermissions,
|
|
type UserRow,
|
|
} from '@authportal/db'
|
|
import { toMe } from '../plugins/auth-guards.js'
|
|
import { getUserProfile } from './user-profile.js'
|
|
|
|
/** Mint access JWT + Me from current DB state (login / reissue). */
|
|
export function issueAccessToken(
|
|
app: FastifyInstance,
|
|
user: UserRow,
|
|
): LoginResponse {
|
|
// Профиль из кэша (инвалидируется записями в users/доступ); user — свежая строка вызывающего.
|
|
const profile = getUserProfile(app.db, user.id)
|
|
const apps = profile?.apps ?? getUserApps(app.db, user.id)
|
|
const permissions = user.isAdmin
|
|
? allPermissionKeys()
|
|
: (profile?.permissions ??
|
|
normalizePermissionKeys(getUserPermissions(app.db, user.id)))
|
|
const switcher = getAppSwitcherConfig(app.db)
|
|
const tenants = tenantsClaimForUser(switcher, apps)
|
|
const me = toMe(user, apps, permissions)
|
|
const expiresAt = new Date(
|
|
Date.now() + app.config.jwtTtlHours * 60 * 60 * 1000,
|
|
)
|
|
const accessToken = app.jwt.sign(
|
|
{
|
|
sub: user.id,
|
|
email: user.email,
|
|
name: user.name,
|
|
apps,
|
|
permissions,
|
|
tenants,
|
|
bgp_tenant_id: tenants.bgp,
|
|
is_admin: user.isAdmin,
|
|
iss: app.config.issuer,
|
|
},
|
|
{ expiresIn: `${app.config.jwtTtlHours}h` },
|
|
)
|
|
return {
|
|
access_token: accessToken,
|
|
expires_at: expiresAt.toISOString(),
|
|
token_type: 'Bearer',
|
|
user: me,
|
|
}
|
|
}
|