plplpl183's picture
Upload apps/api/src/modules/auth/routes.ts
4a2c34e verified
import { Router } from 'express';
import jwt from 'jsonwebtoken';
import { config } from '../../config';
import { redisClient } from '../../server';
const router = Router();
function signTokens(user: { id: string; email: string; orgId: string; role: string }) {
const accessToken = jwt.sign(user, config.JWT_SECRET, { expiresIn: config.JWT_ACCESS_EXPIRY });
const refreshToken = jwt.sign({ id: user.id }, config.JWT_REFRESH_SECRET, { expiresIn: config.JWT_REFRESH_EXPIRY });
return { accessToken, refreshToken };
}
router.post('/register', async (req, res) => {
const { email, name, password, orgName } = req.body;
// TODO: hash password, create org + user in DB
const user = { id: 'uuid-' + Date.now(), email, orgId: 'org-' + Date.now(), role: 'admin' };
const tokens = signTokens(user);
await redisClient.set(`refresh:${user.id}`, tokens.refreshToken, { EX: 7 * 24 * 60 * 60 });
res.json({ data: { user, accessToken: tokens.accessToken }, meta: { refreshToken: tokens.refreshToken } });
});
router.post('/login', async (req, res) => {
const { email, password } = req.body;
// TODO: verify password against DB
const user = { id: 'uuid-mock', email, orgId: 'org-mock', role: 'admin' };
const tokens = signTokens(user);
await redisClient.set(`refresh:${user.id}`, tokens.refreshToken, { EX: 7 * 24 * 60 * 60 });
res.json({ data: { user, accessToken: tokens.accessToken }, meta: { refreshToken: tokens.refreshToken } });
});
router.post('/refresh', async (req, res) => {
const { refreshToken } = req.body;
try {
const payload = jwt.verify(refreshToken, config.JWT_REFRESH_SECRET) as any;
const stored = await redisClient.get(`refresh:${payload.id}`);
if (!stored || stored !== refreshToken) throw new Error('Invalid refresh token');
// TODO: fetch user from DB
const user = { id: payload.id, email: 'mock@example.com', orgId: 'org-mock', role: 'admin' };
const tokens = signTokens(user);
await redisClient.set(`refresh:${user.id}`, tokens.refreshToken, { EX: 7 * 24 * 60 * 60 });
res.json({ data: { accessToken: tokens.accessToken }, meta: { refreshToken: tokens.refreshToken } });
} catch {
res.status(401).json({ error: { message: 'Invalid refresh token', code: 'UNAUTHORIZED' } });
}
});
router.post('/logout', async (req, res) => {
const authHeader = req.headers.authorization;
if (authHeader?.startsWith('Bearer ')) {
try {
const token = authHeader.slice(7);
const payload = jwt.verify(token, config.JWT_SECRET) as any;
await redisClient.del(`refresh:${payload.id}`);
} catch { /* ignore */ }
}
res.json({ data: { success: true } });
});
export { router as authRouter };