inital
This commit is contained in:
122
backend/src/services/token.service.ts
Normal file
122
backend/src/services/token.service.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import jwt from 'jsonwebtoken';
|
||||
import environment from '../config/environment';
|
||||
import logger from '../utils/logger';
|
||||
import { JwtPayload, RefreshTokenPayload } from '../types/auth.types';
|
||||
|
||||
class TokenService {
|
||||
/**
|
||||
* Generate JWT access token
|
||||
*/
|
||||
generateToken(payload: JwtPayload): string {
|
||||
try {
|
||||
const token = jwt.sign(
|
||||
{
|
||||
userId: payload.userId,
|
||||
email: payload.email,
|
||||
authentikSub: payload.authentikSub,
|
||||
},
|
||||
environment.jwt.secret,
|
||||
{
|
||||
expiresIn: environment.jwt.expiresIn as any,
|
||||
}
|
||||
);
|
||||
|
||||
logger.info('Generated JWT token', { userId: payload.userId });
|
||||
return token;
|
||||
} catch (error) {
|
||||
logger.error('Failed to generate JWT token', { error });
|
||||
throw new Error('Token generation failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify and decode JWT token
|
||||
*/
|
||||
verifyToken(token: string): JwtPayload {
|
||||
try {
|
||||
const decoded = jwt.verify(
|
||||
token,
|
||||
environment.jwt.secret
|
||||
) as JwtPayload;
|
||||
|
||||
logger.debug('JWT token verified', { userId: decoded.userId });
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.warn('JWT token expired');
|
||||
throw new Error('Token expired');
|
||||
} else if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.warn('Invalid JWT token', { error: error.message });
|
||||
throw new Error('Invalid token');
|
||||
} else {
|
||||
logger.error('Failed to verify JWT token', { error });
|
||||
throw new Error('Token verification failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate refresh token (longer lived)
|
||||
*/
|
||||
generateRefreshToken(payload: RefreshTokenPayload): string {
|
||||
try {
|
||||
const token = jwt.sign(
|
||||
{
|
||||
userId: payload.userId,
|
||||
email: payload.email,
|
||||
},
|
||||
environment.jwt.secret,
|
||||
{
|
||||
expiresIn: '7d', // Refresh tokens valid for 7 days
|
||||
}
|
||||
);
|
||||
|
||||
logger.info('Generated refresh token', { userId: payload.userId });
|
||||
return token;
|
||||
} catch (error) {
|
||||
logger.error('Failed to generate refresh token', { error });
|
||||
throw new Error('Refresh token generation failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify refresh token
|
||||
*/
|
||||
verifyRefreshToken(token: string): RefreshTokenPayload {
|
||||
try {
|
||||
const decoded = jwt.verify(
|
||||
token,
|
||||
environment.jwt.secret
|
||||
) as RefreshTokenPayload;
|
||||
|
||||
logger.debug('Refresh token verified', { userId: decoded.userId });
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.warn('Refresh token expired');
|
||||
throw new Error('Refresh token expired');
|
||||
} else if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.warn('Invalid refresh token', { error: error.message });
|
||||
throw new Error('Invalid refresh token');
|
||||
} else {
|
||||
logger.error('Failed to verify refresh token', { error });
|
||||
throw new Error('Refresh token verification failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode token without verification (for debugging)
|
||||
*/
|
||||
decodeToken(token: string): JwtPayload | null {
|
||||
try {
|
||||
const decoded = jwt.decode(token) as JwtPayload;
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
logger.error('Failed to decode token', { error });
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new TokenService();
|
||||
Reference in New Issue
Block a user