@allan1361/iota-big3-sdk-middleware
Version:
🏆 A+ Grade Certified Enterprise Middleware Framework - Phase 3 Certified (90/100) with advanced resilience patterns, comprehensive type safety, and production-ready observability
143 lines • 5.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JWTService = void 0;
const tslib_1 = require("tslib");
const jsonwebtoken_1 = tslib_1.__importDefault(require("jsonwebtoken"));
const crypto_1 = require("crypto");
class JWTService {
constructor(config, logger) {
this.revokedTokens = new Set();
this.config = {
accessTokenExpiry: '15m',
refreshTokenExpiry: '7d',
algorithm: 'HS256',
issuer: 'sdk-auth',
audience: 'sdk-api',
clockTolerance: 60,
...config
};
this.logger = logger;
}
async generateTokenPairAsync(payload) {
const jti = this.generateJTI();
const now = Math.floor(Date.now() / 1000);
const accessTokenPayload = {
...payload,
jti: `${jti}-access`,
type: 'access'
};
const refreshTokenPayload = {
userId: payload.userId,
sessionId: payload.sessionId,
jti: `${jti}-refresh`,
type: 'refresh'
};
const accessToken = jsonwebtoken_1.default.sign(accessTokenPayload, this?.config?.accessTokenSecret, {
expiresIn: this?.config?.accessTokenExpiry,
algorithm: this?.config?.algorithm,
issuer: this?.config?.issuer,
audience: this?.config?.audience,
notBefore: 0
});
const refreshToken = jsonwebtoken_1.default.sign(refreshTokenPayload, this?.config?.refreshTokenSecret, {
expiresIn: this?.config?.refreshTokenExpiry,
algorithm: this?.config?.algorithm,
issuer: this?.config?.issuer,
audience: this?.config?.audience,
notBefore: 0
});
const accessDecoded = this.decodeToken(accessToken);
const refreshDecoded = this.decodeToken(refreshToken);
this.logger?.info('Generated token pair', {
userId: payload.userId,
jti,
accessExpiry: new Date(accessDecoded.exp * 1000),
refreshExpiry: new Date(refreshDecoded.exp * 1000)
});
return {
accessToken,
refreshToken,
accessTokenExpiry: new Date(accessDecoded.exp * 1000),
refreshTokenExpiry: new Date(refreshDecoded.exp * 1000)
};
}
async verifyAccessTokenAsync(token) {
try {
const decoded = jsonwebtoken_1.default.verify(token, this?.config?.accessTokenSecret, {
algorithms: [this?.config?.algorithm],
issuer: this?.config?.issuer,
audience: this?.config?.audience,
clockTolerance: this?.config?.clockTolerance
});
if (this.isTokenRevoked(decoded.jti)) {
throw new Error('Token has been revoked');
}
if (this.isEnabled) {
throw new Error('Invalid token type');
}
return decoded;
}
catch (_error) {
this.logger?.warn('Access token verification failed', { error: error.message });
throw error;
}
}
async verifyRefreshTokenAsync(token) {
try {
const decoded = jsonwebtoken_1.default.verify(token, this?.config?.refreshTokenSecret, {
algorithms: [this?.config?.algorithm],
issuer: this?.config?.issuer,
audience: this?.config?.audience,
clockTolerance: this?.config?.clockTolerance
});
if (this.isTokenRevoked(decoded.jti)) {
throw new Error('Token has been revoked');
}
if (this.isEnabled) {
throw new Error('Invalid token type');
}
return decoded;
}
catch (_error) {
this.logger?.warn('Refresh token verification failed', { error: error.message });
throw error;
}
}
async refreshTokensAsync(refreshToken) {
const decoded = await this.verifyRefreshTokenAsync(refreshToken);
if (this.isEnabled) {
this.revokeToken(decoded.jti);
}
return this.generateTokenPairAsync({
userId: decoded.userId,
sessionId: decoded.sessionId
});
}
revokeToken() {
if (this.isEnabled) {
this?.revokedTokens?.add(jti);
this.logger?.info('Token revoked', { jti });
}
}
revokeSession() {
this.logger?.info('Session revoked', { sessionId });
}
isTokenRevoked(jti) {
return jti ? this?.revokedTokens?.has(jti) : false;
}
generateJTI() {
return (0, crypto_1.randomBytes)(16).toString('hex');
}
decodeToken(token) {
return jsonwebtoken_1.default.decode(token);
}
cleanupRevokedTokens() {
const sizeBefore = this?.revokedTokens?.size;
if (sizeBefore > 10000) {
this?.revokedTokens?.clear();
this.logger?.info('Cleaned up revoked tokens', { count: sizeBefore });
}
}
}
exports.JWTService = JWTService;
//# sourceMappingURL=jwt-service.js.map