68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import { jwtVerify } from "jose";
|
|
|
|
// Secret key for JWT verification (must match the one used for signing)
|
|
const rawSecret = (process.env.JWT_SECRET ?? "").trim().replace(/^"|"$/g, "");
|
|
const JWT_SECRET = new TextEncoder().encode(rawSecret);
|
|
|
|
export interface JWTPayload {
|
|
email: string;
|
|
role: string;
|
|
iat: number;
|
|
exp: number;
|
|
}
|
|
|
|
/**
|
|
* Validates a JWT token and returns the payload if valid
|
|
*/
|
|
export async function validateToken(token: string): Promise<JWTPayload | null> {
|
|
try {
|
|
const raw = token.startsWith("Bearer ") ? token.slice(7) : token;
|
|
const { payload } = await jwtVerify(raw, JWT_SECRET, {
|
|
algorithms: ["HS256"],
|
|
});
|
|
return payload as unknown as JWTPayload;
|
|
} catch (error) {
|
|
console.error("Token validation error:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if a token is expired
|
|
*/
|
|
export function isTokenExpired(payload: JWTPayload): boolean {
|
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
return payload.exp < currentTime;
|
|
}
|
|
|
|
/**
|
|
* Gets token expiration time in a human-readable format
|
|
*/
|
|
export function getTokenExpirationTime(payload: JWTPayload): Date {
|
|
return new Date(payload.exp * 1000);
|
|
}
|
|
|
|
/**
|
|
* Gets time until token expires in seconds
|
|
*/
|
|
export function getTimeUntilExpiration(payload: JWTPayload): number {
|
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
return Math.max(0, payload.exp - currentTime);
|
|
}
|
|
|
|
export function validatePassword(password: string) {
|
|
const errors: string[] = [];
|
|
|
|
if (password.length < 8) errors.push("At least 8 characters");
|
|
if (!/[A-Z]/.test(password)) errors.push("One uppercase letter");
|
|
if (!/[a-z]/.test(password)) errors.push("One lowercase letter");
|
|
if (!/[0-9]/.test(password)) errors.push("One number");
|
|
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password))
|
|
errors.push("One special character");
|
|
|
|
return {
|
|
valid: errors.length === 0,
|
|
errors,
|
|
};
|
|
}
|