diff --git a/services/platform-service/src/modules/auth/jwt.ts b/services/platform-service/src/modules/auth/jwt.ts index 2428224a..ceeca2a8 100644 --- a/services/platform-service/src/modules/auth/jwt.ts +++ b/services/platform-service/src/modules/auth/jwt.ts @@ -16,6 +16,7 @@ export async function createAccessToken(payload: { email: string; role: string; productId: string; + plan?: 'free' | 'pro' | 'enterprise'; }): Promise { return new SignJWT({ ...payload, type: 'access' }) .setProtectedHeader({ alg: 'HS256' }) @@ -42,6 +43,7 @@ export async function verifyToken(token: string): Promise<{ email?: string; role?: string; productId?: string; + plan?: 'free' | 'pro' | 'enterprise'; type?: string; }> { const { payload } = await jwtVerify(token, getSecret(), { @@ -52,6 +54,7 @@ export async function verifyToken(token: string): Promise<{ email?: string; role?: string; productId?: string; + plan?: 'free' | 'pro' | 'enterprise'; type?: string; }; } diff --git a/services/platform-service/src/modules/auth/routes.ts b/services/platform-service/src/modules/auth/routes.ts index e9779c52..cbea261e 100644 --- a/services/platform-service/src/modules/auth/routes.ts +++ b/services/platform-service/src/modules/auth/routes.ts @@ -9,6 +9,7 @@ */ import type { FastifyInstance } from 'fastify'; +import { getRequestProductConfig } from '../../lib/request-context.js'; import { BadRequestError, UnauthorizedError } from '../../lib/errors.js'; import * as repo from './repository.js'; import * as jwt from './jwt.js'; @@ -36,13 +37,20 @@ export async function authRoutes(app: FastifyInstance) { email: user.email, role: user.role, productId, + plan: user.plan, }); const refreshToken = await jwt.createRefreshToken({ sub: user.id, productId }); return { accessToken, refreshToken, - user: { id: user.id, email: user.email, role: user.role, displayName: user.displayName }, + user: { + id: user.id, + email: user.email, + role: user.role, + plan: user.plan, + displayName: user.displayName, + }, }; }); @@ -53,6 +61,7 @@ export async function authRoutes(app: FastifyInstance) { throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; ')); } const { email, password, displayName, role, productId } = parsed.data; + const product = getRequestProductConfig(req); const existing = await repo.getByEmail(email, productId); if (existing) throw new BadRequestError('Email already registered'); @@ -63,6 +72,7 @@ export async function authRoutes(app: FastifyInstance) { productId, email: email.toLowerCase(), passwordHash: await repo.hashPassword(password), + plan: product.defaultPlan, role, displayName, status: 'active', @@ -77,6 +87,7 @@ export async function authRoutes(app: FastifyInstance) { email: user.email, role: user.role, productId, + plan: user.plan, }); const refreshToken = await jwt.createRefreshToken({ sub: user.id, productId }); @@ -84,7 +95,13 @@ export async function authRoutes(app: FastifyInstance) { return { accessToken, refreshToken, - user: { id: user.id, email: user.email, role: user.role, displayName: user.displayName }, + user: { + id: user.id, + email: user.email, + role: user.role, + plan: user.plan, + displayName: user.displayName, + }, }; }); @@ -106,6 +123,7 @@ export async function authRoutes(app: FastifyInstance) { email: user.email, role: user.role, productId: user.productId, + plan: user.plan, }); return { accessToken }; } catch { @@ -123,7 +141,13 @@ export async function authRoutes(app: FastifyInstance) { const payload = await jwt.verifyToken(token); const user = await repo.getById(payload.sub); if (!user) throw new UnauthorizedError('User not found'); - return { id: user.id, email: user.email, role: user.role, displayName: user.displayName }; + return { + id: user.id, + email: user.email, + role: user.role, + plan: user.plan, + displayName: user.displayName, + }; } catch { throw new UnauthorizedError('Invalid or expired token'); } diff --git a/services/platform-service/src/modules/auth/types.ts b/services/platform-service/src/modules/auth/types.ts index 213f3420..376409ea 100644 --- a/services/platform-service/src/modules/auth/types.ts +++ b/services/platform-service/src/modules/auth/types.ts @@ -9,6 +9,7 @@ export interface UserDoc { productId: string; email: string; passwordHash: string; + plan: 'free' | 'pro' | 'enterprise'; role: 'super_admin' | 'admin' | 'viewer' | 'user'; displayName: string; status: 'active' | 'disabled'; @@ -22,6 +23,7 @@ export interface TokenPayload { email: string; role: string; productId: string; + plan?: 'free' | 'pro' | 'enterprise'; iat: number; exp: number; }