mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 12:50:09 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Component: JWT Token Utilities
|
||||
* Documentation: documentation/backend/services/auth.md
|
||||
*/
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'change-this-to-a-random-secret-key';
|
||||
const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || 'change-this-to-another-random-secret-key';
|
||||
|
||||
const ACCESS_TOKEN_EXPIRY = '1h'; // 1 hour
|
||||
const REFRESH_TOKEN_EXPIRY = '7d'; // 7 days
|
||||
|
||||
export interface TokenPayload {
|
||||
sub: string; // User ID
|
||||
plexId: string;
|
||||
username: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export interface RefreshTokenPayload {
|
||||
sub: string;
|
||||
type: 'refresh';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate access token (short-lived)
|
||||
*/
|
||||
export function generateAccessToken(payload: TokenPayload): string {
|
||||
return jwt.sign(payload, JWT_SECRET, {
|
||||
expiresIn: ACCESS_TOKEN_EXPIRY,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate refresh token (long-lived)
|
||||
*/
|
||||
export function generateRefreshToken(userId: string): string {
|
||||
const payload: RefreshTokenPayload = {
|
||||
sub: userId,
|
||||
type: 'refresh',
|
||||
};
|
||||
|
||||
return jwt.sign(payload, JWT_REFRESH_SECRET, {
|
||||
expiresIn: REFRESH_TOKEN_EXPIRY,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify access token
|
||||
*/
|
||||
export function verifyAccessToken(token: string): TokenPayload | null {
|
||||
try {
|
||||
const decoded = jwt.verify(token, JWT_SECRET) as TokenPayload;
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
console.error('[JWT] Access token verification failed:', error);
|
||||
if (error instanceof Error) {
|
||||
console.error('[JWT] Error details:', error.message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify refresh token
|
||||
*/
|
||||
export function verifyRefreshToken(token: string): RefreshTokenPayload | null {
|
||||
try {
|
||||
const decoded = jwt.verify(token, JWT_REFRESH_SECRET) as RefreshTokenPayload;
|
||||
if (decoded.type !== 'refresh') {
|
||||
return null;
|
||||
}
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
console.error('Refresh token verification failed:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode token without verification (for debugging)
|
||||
*/
|
||||
export function decodeToken(token: string): any {
|
||||
try {
|
||||
return jwt.decode(token);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user