feat: add auth plugin
Made-with: Cursor
This commit is contained in:
42
src/plugins/auth.ts
Normal file
42
src/plugins/auth.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
|
||||
import fp from 'fastify-plugin';
|
||||
import { verifyToken, isAccessPayload } from '../utils/jwt.js';
|
||||
import { unauthorized } from '../utils/errors.js';
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
authenticate: (req: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
||||
}
|
||||
interface FastifyRequest {
|
||||
user?: { id: string; email: string };
|
||||
}
|
||||
}
|
||||
|
||||
export async function authenticate(req: FastifyRequest, _reply: FastifyReply): Promise<void> {
|
||||
const authHeader = req.headers.authorization;
|
||||
|
||||
if (!authHeader?.startsWith('Bearer ')) {
|
||||
throw unauthorized('Missing or invalid authorization header');
|
||||
}
|
||||
|
||||
const token = authHeader.slice(7);
|
||||
|
||||
try {
|
||||
const payload = await verifyToken(token);
|
||||
|
||||
if (!isAccessPayload(payload)) {
|
||||
throw unauthorized('Invalid token type');
|
||||
}
|
||||
|
||||
req.user = { id: payload.sub, email: payload.email };
|
||||
} catch {
|
||||
throw unauthorized('Invalid or expired token');
|
||||
}
|
||||
}
|
||||
|
||||
const authPlugin = async (app: FastifyInstance) => {
|
||||
app.decorateRequest('user', undefined);
|
||||
app.decorate('authenticate', authenticate);
|
||||
};
|
||||
|
||||
export default fp(authPlugin, { name: 'auth' });
|
||||
Reference in New Issue
Block a user