- Add user management with roles and permissions (RBAC) - Implement OAuth2 service provider supporting 4 grant types: authorization_code, password, client_credentials, refresh_token - Add JWT authentication with 7-day expiry - Add admin API for users, roles and OAuth clients management - Add CLI tool for user management (scripts/user-cli.js) - Add collapsible sidebar layout with login dialog - Add user management page and OAuth client management page - Add server middleware for auth token verification - Add seed script for initial data (admin/admin123)
46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import jwt from 'jsonwebtoken'
|
|
import type { JWTPayload } from '../modules/auth/types'
|
|
|
|
const JWT_SECRET = process.env.JWT_SECRET || 'sport-meeting-admin-secret-key-2026'
|
|
const ACCESS_TOKEN_EXPIRY = '7d'
|
|
const REFRESH_TOKEN_EXPIRY = '30d'
|
|
|
|
export function generateAccessToken(payload: Omit<JWTPayload, 'iat' | 'exp' | 'type'>): string {
|
|
return jwt.sign({ ...payload, type: 'access' }, JWT_SECRET, { expiresIn: ACCESS_TOKEN_EXPIRY })
|
|
}
|
|
|
|
export function generateRefreshToken(payload: Omit<JWTPayload, 'iat' | 'exp' | 'type'>): string {
|
|
return jwt.sign({ ...payload, type: 'refresh' }, JWT_SECRET, { expiresIn: REFRESH_TOKEN_EXPIRY })
|
|
}
|
|
|
|
export function verifyToken(token: string): JWTPayload | null {
|
|
try {
|
|
const decoded = jwt.verify(token, JWT_SECRET) as JWTPayload
|
|
return decoded
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export function decodeToken(token: string): JWTPayload | null {
|
|
try {
|
|
return jwt.decode(token) as JWTPayload
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export function isAccessToken(token: JWTPayload): boolean {
|
|
return token.type === 'access'
|
|
}
|
|
|
|
export function isRefreshToken(token: JWTPayload): boolean {
|
|
return token.type === 'refresh'
|
|
}
|
|
|
|
export function getTokenExpiry(token: string): Date | null {
|
|
const decoded = decodeToken(token)
|
|
if (!decoded?.exp) return null
|
|
return new Date(decoded.exp * 1000)
|
|
}
|