Phase 1-2 of server consolidation + security hardening
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
export class TokenError extends Error {
|
||||
constructor(message, code) {
|
||||
super(message);
|
||||
this.name = 'TokenError';
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
export function extractBearerToken(authorizationHeader) {
|
||||
if (!authorizationHeader || typeof authorizationHeader !== 'string') {
|
||||
throw new TokenError('No token provided', 'missing');
|
||||
}
|
||||
if (!authorizationHeader.startsWith('Bearer ')) {
|
||||
throw new TokenError('Malformed Authorization header', 'malformed');
|
||||
}
|
||||
const token = authorizationHeader.slice(7).trim();
|
||||
if (!token) {
|
||||
throw new TokenError('Empty bearer token', 'malformed');
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export function verifyToken(token, secret) {
|
||||
if (!secret) {
|
||||
throw new TokenError('JWT_SECRET not configured', 'misconfigured');
|
||||
}
|
||||
try {
|
||||
return jwt.verify(token, secret);
|
||||
} catch (err) {
|
||||
if (err.name === 'TokenExpiredError') {
|
||||
throw new TokenError('Token expired', 'expired');
|
||||
}
|
||||
throw new TokenError('Invalid token', 'invalid');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user