relv-dev's picture
Deploy latest verified Turnitin worker
521a9b6 verified
Raw
History Blame Contribute Delete
1.56 kB
import { Request, Response, NextFunction } from 'express';
import { supabase } from '../../db/client';
import { logger } from '../../utils/logger';
/** Augmented Express Request with authenticated user fields */
export interface AuthenticatedRequest extends Request {
userId: string;
userEmail: string;
}
/**
* Express middleware that verifies a Supabase JWT from the Authorization header.
* On success, sets req.userId and req.userEmail for downstream handlers.
* Returns 401 if the token is missing or invalid.
*/
export async function authenticateUser(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
res.status(401).json({ error: 'Missing or malformed Authorization header' });
return;
}
const token = authHeader.slice(7); // Strip "Bearer "
try {
const { data, error } = await supabase.auth.getUser(token);
if (error || !data.user) {
logger.warn('Auth verification failed', { error: error?.message });
res.status(401).json({ error: 'Invalid or expired token' });
return;
}
// Attach user info to the request
(req as AuthenticatedRequest).userId = data.user.id;
(req as AuthenticatedRequest).userEmail = data.user.email || '';
next();
} catch (err) {
logger.error('Auth middleware unexpected error', {
error: err instanceof Error ? err.message : String(err),
});
res.status(401).json({ error: 'Authentication failed' });
}
}