UNPKG

jwt-smith

Version:

Enhanced JWT Authentication and Authorization Module

732 lines (718 loc) 30.9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { JwtManager: () => JwtManager, roleBasedAuthenticationMiddleware: () => role_based_authentication_middleware_default, setDefaultSignOptions: () => setDefaultSignOptions, setDefaultVerifyOptions: () => setDefaultVerifyOptions, sign: () => sign, validateJwtCookieMiddleware: () => auth_cookie_verification_middleware_default, validateJwtHeaderMiddleware: () => auth_header_verification_middleware_default, verify: () => verify }); module.exports = __toCommonJS(src_exports); // src/lib/core.ts var import_joi3 = __toESM(require("joi")); // src/lib/logger.ts var LOGGER_PREFIX = "[JWT-Smith] "; var currentLogger = console; var logSettings = { setPrefix: true }; var setLogger = (logger, options) => { currentLogger = logger; logSettings = { ...logSettings, ...options || {} }; }; var getLogger = () => { return currentLogger; }; var logFormat = (message) => { return `${logSettings.setPrefix ? LOGGER_PREFIX : ""}${message}`; }; var log = (level, message, ...args) => { const logger = getLogger(); if (logger[level]) { logger[level](logFormat(message), ...args); } else { console.error(logFormat(`Invalid log level: ${level}`)); } }; // src/lib/signing-token.ts var import_jsonwebtoken = __toESM(require("jsonwebtoken")); var import_joi = __toESM(require("joi")); var signTokenOptionsSchema = import_joi.default.object({ algorithm: import_joi.default.string().default("HS256"), keyid: import_joi.default.string(), expiresIn: import_joi.default.alternatives().try(import_joi.default.string(), import_joi.default.number()), notBefore: import_joi.default.alternatives().try(import_joi.default.string(), import_joi.default.number()), audience: import_joi.default.alternatives().try(import_joi.default.string(), import_joi.default.array().items(import_joi.default.string())), subject: import_joi.default.string(), issuer: import_joi.default.string(), jwtid: import_joi.default.string(), mutatePayload: import_joi.default.bool(), noTimestamp: import_joi.default.bool(), header: import_joi.default.object(), encoding: import_joi.default.string(), allowInsecureKeySizes: import_joi.default.bool(), allowInvalidAsymmetricKeyTypes: import_joi.default.boolean() }); var secretSchema = import_joi.default.alternatives().try( import_joi.default.string(), import_joi.default.binary(), import_joi.default.object().instance(Buffer), import_joi.default.object({ key: import_joi.default.alternatives().try(import_joi.default.string(), import_joi.default.binary()), passphrase: import_joi.default.string() }) ).not(""); var signTokenParamsSchema = import_joi.default.object({ payload: import_joi.default.alternatives().try(import_joi.default.string(), import_joi.default.object(), import_joi.default.binary()).required(), secret: secretSchema.required(), options: signTokenOptionsSchema.optional() }); var defaultSignOptions = {}; var sign = (parameters) => { return new Promise((resolve, reject) => { const { error, warning, value } = signTokenParamsSchema.validate(parameters); if (error) { reject(logFormat(`Parameter Validation Error: ${error.message}`)); } else if (warning) { log("warn", "Parameter Validation Warning:", { warning_details: warning }); } const { payload, secret, options = {} } = value; const signOptions = { ...defaultSignOptions, ...options }; import_jsonwebtoken.default.sign(payload, secret, signOptions, (err, token) => { if (err) { reject(err); } else { resolve(token); } }); }); }; var setDefaultSignOptions = (options) => { const { error, warning, value } = signTokenOptionsSchema.validate(options); if (error) { throw new Error(logFormat(`Parameter Validation Error: ${error.message}`)); } else if (warning) { log("warn", "Parameter Validation Warning:", { warning_details: warning }); } defaultSignOptions = value; }; // src/lib/verify-token.ts var import_jsonwebtoken2 = __toESM(require("jsonwebtoken")); var import_joi2 = __toESM(require("joi")); var verifyTokenOptionsSchema = import_joi2.default.object({ algorithms: import_joi2.default.array().items(import_joi2.default.string()), audience: import_joi2.default.alternatives().try(import_joi2.default.string(), import_joi2.default.array().items(import_joi2.default.string())), clockTimestamp: import_joi2.default.number(), clockTolerance: import_joi2.default.number(), complete: import_joi2.default.bool(), issuer: import_joi2.default.alternatives().try(import_joi2.default.string(), import_joi2.default.array().items(import_joi2.default.string())), ignoreExpiration: import_joi2.default.boolean(), ignoreNotBefore: import_joi2.default.boolean(), jwtid: import_joi2.default.string(), nonce: import_joi2.default.string(), subject: import_joi2.default.string(), maxAge: import_joi2.default.alternatives().try(import_joi2.default.string(), import_joi2.default.number()), allowInvalidAsymmetricKeyTypes: import_joi2.default.boolean() }); var secretSchema2 = import_joi2.default.alternatives().try( import_joi2.default.string().not(""), import_joi2.default.binary(), import_joi2.default.object().instance(Buffer), import_joi2.default.object({ key: import_joi2.default.alternatives().try(import_joi2.default.string(), import_joi2.default.binary()), passphrase: import_joi2.default.string() }) ); var verifyTokenParamsSchema = import_joi2.default.object({ token: import_joi2.default.string().not("").required(), secret: secretSchema2.required(), options: verifyTokenOptionsSchema.optional() }); var defaultVerifyOptions = {}; var verify = (parameters) => { return new Promise((resolve, reject) => { const { error, warning, value } = verifyTokenParamsSchema.validate(parameters); if (error) { reject(logFormat(`Parameter Validation Error: ${error.message}`)); } else if (warning) { log("warn", "Parameter Validation Warning:", { warning_details: warning }); } const { token, secret, options = {} } = value; const verifyOptions = { ...defaultVerifyOptions, options }; import_jsonwebtoken2.default.verify(token, secret, verifyOptions, (err, decoded) => { if (err) { reject(err); } else { resolve(decoded); } }); }); }; var setDefaultVerifyOptions = (options) => { const { error, warning, value } = verifyTokenOptionsSchema.validate(options); if (error) { throw new Error(logFormat(`Parameter Validation Error: ${error.message}`)); } else if (warning) { log("warn", "Parameter Validation Warning:", { warning_details: warning }); } defaultVerifyOptions = value; }; // src/helper/utils.ts var extractAuthHeaderValue = (header) => { let tokenValue; if (header && header.split(" ")[1]) { tokenValue = header.split(" ")[1]; } return tokenValue; }; var appendTokenPayloadToRequest = (req, appendToRequest, decodedTokenPayload) => { if (Array.isArray(appendToRequest) && appendToRequest?.length > 0 && decodedTokenPayload && typeof decodedTokenPayload !== "string") { log("debug", `Properties to append to the request: ${appendToRequest}`); try { const castedPayload = decodedTokenPayload; appendToRequest.forEach((item) => { if (Object.hasOwn(castedPayload, item)) { req[item] = castedPayload[item]; } }); } catch (error) { log("error", "Token payload appending to the request failed!", error); } } else if (typeof appendToRequest === "boolean" && typeof decodedTokenPayload === "string") { log("debug", `Token payload appending to the request: ${decodedTokenPayload}`); req.tokenPayload = decodedTokenPayload; } }; var defaultTokenGenerationHandler = async (refreshTokenPayload) => { if (process.env.NODE_ENV === "production") { throw new Error("Token generation handler not implemented."); } else { log("warn", "Token generation handler not implemented. Using default handler."); console.debug({ refreshTokenPayload }); } return { token: "new-token", refreshToken: "new-refresh-token" }; }; var defaultAuthTokenPayloadVerifier = async (tokenPayload) => { if (!tokenPayload) { throw new Error("Empty payload in the auth token."); } }; var defaultRefreshTokenPayloadVerifier = async (tokenPayload) => { const user = tokenPayload?.user; const userId = user?.id; if (!userId) { throw new Error("Refresh token process failed. User ID not found in the refresh payload."); } }; var defaultRefreshTokenHolderVerifier = async (tokenHolder, tokenPayload) => { const user = tokenPayload?.user; const userId = user?.id || user?.userId; const tokenHolderId = tokenHolder?.id || tokenHolder?.userId; return tokenHolderId === userId; }; var defaultExtractApiVersion = async (req) => { const version = req.headers["api-version"]; return version ?? req.baseUrl.split("/")[1]; }; // src/lib/core.ts var publicKey; var refreshTokenKey; var middlewareConfigs = { tokenStorage: void 0, authHeaderName: "authorization", appendToRequest: [], cookieSettings: { accessTokenCookieName: "accessToken", accessCookieOptions: {}, refreshTokenCookieName: void 0 }, authTokenExtractor: extractAuthHeaderValue, tokenGenerationHandler: defaultTokenGenerationHandler, refreshTokenPayloadVerifier: defaultRefreshTokenPayloadVerifier, refreshTokenHolderVerifier: defaultRefreshTokenHolderVerifier, extractApiVersion: defaultExtractApiVersion }; var secretSchema3 = import_joi3.default.alternatives().try( import_joi3.default.string(), import_joi3.default.binary(), import_joi3.default.object().instance(Buffer), import_joi3.default.object({ key: import_joi3.default.alternatives().try(import_joi3.default.string(), import_joi3.default.binary()), passphrase: import_joi3.default.string() }) ); var configOptionsSchema = import_joi3.default.object({ logger: import_joi3.default.object().optional(), publicKey: secretSchema3.optional(), refreshTokenKey: secretSchema3.optional(), signOptions: import_joi3.default.object().optional(), verifyOptions: import_joi3.default.object().optional(), middlewareConfigs: import_joi3.default.object().optional() }); var JwtManager = (options) => { const { error, warning, value } = configOptionsSchema.validate(options); if (error) { throw new Error(logFormat(`Parameter Validation Error: ${error.message}`)); } else if (warning) { log("warn", "Parameter Validation Warning:", { warning_details: warning }); } if (value.logger) setLogger(value.logger); if (value.publicKey) publicKey = value.publicKey; if (value.refreshTokenKey) refreshTokenKey = value.refreshTokenKey; if (value.signOptions) setDefaultSignOptions(value.signOptions); if (value.verifyOptions) setDefaultVerifyOptions(value.verifyOptions); if (value.middlewareConfigs) middlewareConfigs = { ...middlewareConfigs, ...value.middlewareConfigs }; }; // src/module/token-storage.ts var DefaultTokenStorage = class { tokens = /* @__PURE__ */ new Map(); defectedTokens = /* @__PURE__ */ new Map(); async saveOrUpdateToken(userId, tokenOrRefreshToken, token) { const existingData = this.tokens.get(userId) || { refreshTokens: [], tokens: [] }; let update = { refreshTokens: [] }; update = { ...existingData, refreshTokens: [...existingData.refreshTokens || [], tokenOrRefreshToken] }; if (token) { update = { ...update, tokens: [...existingData.tokens || [], token] }; } this.tokens.set(userId, update); } async getRefreshTokenHolder(refreshToken) { let holder = null; this.tokens.forEach((data, userId) => { if (data.refreshTokens?.includes(refreshToken)) { holder = { id: userId, ...this.tokens.get(userId) }; return; } }); return holder; } async getRefreshToken(userId) { return this.tokens.get(userId)?.refreshTokens || null; } async deleteToken(userId) { this.tokens.delete(userId); } async getToken(userId) { return this.tokens.get(userId)?.tokens || null; } async blackListRefreshToken(token, relatedData) { this.defectedTokens.set(token, relatedData || {}); } async checkBlackListedRefreshToken(token) { return this.defectedTokens.get(token); } }; // src/module/refresh-token-handler.ts var import_jsonwebtoken3 = require("jsonwebtoken"); var TokenHandler = class { refreshTokenStorage; tokenGenerationHandler; authTokenPayloadVerifier; refreshTokenPayloadVerifier; refreshTokenHolderVerifier; constructor(options) { this.refreshTokenStorage = options.refreshTokenStorage || new DefaultTokenStorage(); this.tokenGenerationHandler = options.tokenGenerationHandler; this.authTokenPayloadVerifier = options.authTokenPayloadVerifier || defaultAuthTokenPayloadVerifier; this.refreshTokenPayloadVerifier = options.refreshTokenPayloadVerifier || defaultRefreshTokenPayloadVerifier; this.refreshTokenHolderVerifier = options.refreshTokenHolderVerifier || defaultRefreshTokenHolderVerifier; if (!options.refreshTokenStorage) { const logType = process.env.NODE_ENV === "production" ? "error" : "warn"; log(logType, "[TokenHandler]: Using default in-memory token storage. This is not recommended for production."); } } async validateOrRefreshAuthToken(authToken, refreshToken) { let decodedToken; let token = authToken; let nextRefreshToken = refreshToken; await this.validateAuthToken(authToken).then((tokenPayload) => { decodedToken = tokenPayload; }).catch(async (error) => { if (error instanceof import_jsonwebtoken3.TokenExpiredError && refreshToken) { const response = await this.rotateRefreshToken(refreshToken, authToken); token = response.token; nextRefreshToken = response.refreshToken; decodedToken = await verify({ token, secret: publicKey }); } else { log("info", "Refresh token not found."); throw error; } }); return { decodedToken, nextRefreshToken, token }; } async validateAuthToken(authToken) { const tokenPayload = await verify({ token: authToken, secret: publicKey }); await this.authTokenPayloadVerifier(tokenPayload); log("info", "Auth token validation complete!"); return tokenPayload; } async rotateRefreshToken(refreshToken, token) { try { const isBlackListed = await this.refreshTokenStorage.checkBlackListedRefreshToken(refreshToken); log("debug", "Checking if the refresh token is blacklisted."); if (isBlackListed) { log("error", "Blacklisted refresh token received!", { refreshToken }); throw new Error("Blacklisted refresh token found!"); } const decodedTokenPayload = await verify({ token: refreshToken, secret: refreshTokenKey || publicKey }); log("debug", "Decoded the refresh token payload."); if (!decodedTokenPayload) { throw new Error("Refresh token payload is undefined!"); } await this.refreshTokenPayloadVerifier(decodedTokenPayload); log("debug", "Refresh token payload verification complete."); const tokenHolder = await this.refreshTokenStorage.getRefreshTokenHolder(refreshToken); log("debug", "Retrieved the refresh token holder."); if (!tokenHolder) { throw new Error("Could not find a matching token holder for the refresh token."); } const isHolderVerified = await this.refreshTokenHolderVerifier(tokenHolder, decodedTokenPayload); log("debug", "Refresh token holder verification complete."); if (!isHolderVerified) { await this.refreshTokenStorage.blackListRefreshToken(refreshToken); throw new Error("Refresh token holder verification failed."); } const response = await this.tokenGenerationHandler(decodedTokenPayload, tokenHolder); log("debug", "Generated new tokens."); const userId = tokenHolder.id || (typeof decodedTokenPayload !== "string" && "user" in decodedTokenPayload ? decodedTokenPayload.user?.id : void 0); await this.refreshTokenStorage.saveOrUpdateToken(userId, response.refreshToken, response.token); log("debug", "Saved the new tokens."); return response; } catch (error) { await this.cleanupInvalidRefreshToken(refreshToken, token); throw error; } } async cleanupInvalidRefreshToken(refreshToken, token) { const tokenHolder = await this.refreshTokenStorage.getRefreshTokenHolder(refreshToken); if (tokenHolder && Object.hasOwn(tokenHolder, "id")) { const userId = tokenHolder.id; await this.refreshTokenStorage.deleteToken(userId, token, refreshToken); } } }; // src/middleware/auth-header-verification.middleware.ts var validateJwtHeaderMiddleware = async (req, res, next) => { try { const { appendToRequest = [], authHeaderName, refreshTokenHeaderName, authTokenExtractor, tokenGenerationHandler, cookieSettings = {}, authTokenPayloadVerifier, refreshTokenPayloadVerifier, refreshTokenHolderVerifier, tokenStorage } = middlewareConfigs; let authHeader = req.headers[authHeaderName ?? ""]; log("debug", "Auth header and middleware configurations extracted."); if (Array.isArray(authHeader)) authHeader = authHeader.join("__"); log("debug", `Auth header: ${authHeader}`); if (!authHeader || !authHeader.startsWith("Bearer ")) { throw new Error("Valid auth header not found"); } if (authTokenExtractor) { log("debug", "Auth token extractor method found."); const tokenValue = authTokenExtractor(authHeader); log("debug", `Auth token value: ${tokenValue}`); if (!tokenValue) { throw new Error("Auth token not found"); } let refreshToken = req.cookies && cookieSettings.refreshTokenCookieName ? req.cookies[cookieSettings.refreshTokenCookieName] : void 0; if (!refreshToken && refreshTokenHeaderName) { refreshToken = req.headers[refreshTokenHeaderName]; } log("debug", "Refresh token extracted."); const refreshTokenHandler = new TokenHandler({ refreshTokenStorage: tokenStorage, tokenGenerationHandler, authTokenPayloadVerifier, refreshTokenPayloadVerifier, refreshTokenHolderVerifier }); log("debug", "Token handler created."); log("debug", `Auth token: ${tokenValue} | Refresh token: ${refreshToken}`); const { decodedToken, nextRefreshToken, token } = await refreshTokenHandler.validateOrRefreshAuthToken( tokenValue, refreshToken ); log("debug", "Token handler validated or refreshed the auth token."); if (!decodedToken) { throw new Error("Auth cookie payload is undefined!"); } appendTokenPayloadToRequest(req, appendToRequest, decodedToken); log("debug", "Token payload appended to the request object."); res.setHeader(authHeaderName ?? "authorization", token); if (cookieSettings.refreshTokenCookieName && nextRefreshToken) { log("debug", "New refresh token set in the cookie."); res.cookie(cookieSettings.refreshTokenCookieName, nextRefreshToken, cookieSettings.refreshCookieOptions || {}); } else if (refreshTokenHeaderName && nextRefreshToken) { log("debug", "New refresh token set in the header."); res.setHeader(refreshTokenHeaderName, nextRefreshToken); } log("debug", "Next middleware called."); return next(); } else { throw new Error("Token value extractor method not found"); } } catch (error) { log("error", "Error occurred while authenticating the JST token.", error); const errorMessage = error instanceof Error ? error.message : "Unknown error"; res.status(401).json({ message: "Unauthorized", error: errorMessage }); } }; var auth_header_verification_middleware_default = validateJwtHeaderMiddleware; // src/middleware/role-based-authentication.middleware.ts var import_promises = __toESM(require("fs/promises")); var import_joi4 = __toESM(require("joi")); // src/helper/constants.ts var RolePermissionConfigFilePath = "./.auth-permissions.json"; // src/middleware/role-based-authentication.middleware.ts var permissionSchema = import_joi4.default.object({ roles: import_joi4.default.array().items(import_joi4.default.string().required()).required(), actions: import_joi4.default.array().items(import_joi4.default.string().required()).required() }); var endpointSchema = import_joi4.default.object({ path: import_joi4.default.string().required(), methods: import_joi4.default.array().items(import_joi4.default.string().valid("GET", "POST", "PUT", "PATCH", "DELETE")).required(), permissions: import_joi4.default.array().items(permissionSchema).required() }); var groupSchema = import_joi4.default.object({ basePath: import_joi4.default.string().required(), permissions: import_joi4.default.array().items(permissionSchema).required(), endpoints: import_joi4.default.array().items(endpointSchema).required() }); var commonRolesSchema = import_joi4.default.object({ name: import_joi4.default.string().required(), permissions: import_joi4.default.array().items(import_joi4.default.string().required()).required() }); var permissionsConfigSchema = import_joi4.default.object({ versioned: import_joi4.default.boolean().optional(), activeVersions: import_joi4.default.array().items(import_joi4.default.string().required()).optional(), common: import_joi4.default.object({ roles: import_joi4.default.array().items(commonRolesSchema).required() }).optional(), groups: import_joi4.default.object().pattern(import_joi4.default.string(), groupSchema).optional(), endpoints: import_joi4.default.array().items(endpointSchema).optional() }); var getPermissionConfigs = async () => { await import_promises.default.stat(RolePermissionConfigFilePath).catch((e) => { log("error", "Auth permissions configuration file could not found"); throw e; }); return JSON.parse(await import_promises.default.readFile(RolePermissionConfigFilePath, "utf-8")); }; var roleBasedAuthenticationMiddleware = (requiredAction) => { return async (req, res, next) => { const { extractApiVersion } = middlewareConfigs; const { user, role } = req; const userRole = user && Object.hasOwn(user, "role") ? user.role : role; const endpointPath = req.baseUrl; const method = req.method; let requestVersion = void 0; let versionValidationError = void 0; log("debug", "Role-based authentication middleware invoked."); if (extractApiVersion) { const version = await extractApiVersion(req); if (version) { requestVersion = version; } } log("debug", "Role-based authentication middleware configurations extracted."); log( "debug", `User role: ${userRole} | Required action: ${requiredAction} | Endpoint: ${endpointPath} | Method: ${method}` ); log("debug", `API version extracted from the request: ${requestVersion}`); if (!userRole) { res.status(403).json({ error: "Access denied. Role not found." }); } else { const permissionsConfig = await getPermissionConfigs(); log("debug", "Auth permissions configuration file loaded."); const { error } = permissionsConfigSchema.validate(permissionsConfig); log("debug", "Auth permissions configuration file validated."); if (error) { log("error", "Auth Permissions config file's validation failed.", error); throw error; } if (!permissionsConfig.common && !permissionsConfig.groups && !permissionsConfig.endpoints) { log("error", "At least one permission set should be in the configs."); throw new Error("Permission configurations is empty."); } if (permissionsConfig.versioned) { if (!requestVersion) { versionValidationError = "Access denied. Insufficient permissions."; } if (requestVersion && !permissionsConfig.activeVersions?.includes(requestVersion)) { versionValidationError = "Unsupported API version."; } } log("debug", "Permission configurations validated."); if (versionValidationError) { log("error", versionValidationError); res.status(400).json({ error: versionValidationError }); } else { log("debug", "Permission configurations validating..."); if (permissionsConfig.endpoints) { const standaloneEndpoint = permissionsConfig.endpoints.find( (ep) => ep.path === endpointPath && ep.methods.includes(method) ); if (standaloneEndpoint) { if (checkPermissions(userRole, requiredAction, [], standaloneEndpoint.permissions)) { return next(); } } } if (permissionsConfig.groups) { const groups = Object.values(permissionsConfig.groups); const matchedGroup = groups.find( (group) => endpointPath.startsWith(group.basePath) && group.endpoints.some((ep) => ep.path === endpointPath) ); if (matchedGroup) { const groupPermissions = matchedGroup.permissions || []; const endpointPermissions = matchedGroup.endpoints.find( (ep) => ep.path === endpointPath && ep.methods.includes(method) )?.permissions || []; if (checkPermissions(userRole, requiredAction, groupPermissions, endpointPermissions)) { return next(); } } } if (permissionsConfig.common) { const commonRoles = permissionsConfig.common.roles || []; const commonRole = commonRoles.find((role2) => role2.name === userRole); if (commonRole && commonRole.permissions.includes("*:*")) { return next(); } } res.status(403).json({ error: "Access denied. Insufficient permissions." }); } } }; }; function checkPermissions(userRole, requiredAction, groupPermissions, endpointPermissions) { const combinedPermissions = [...groupPermissions, ...endpointPermissions]; return combinedPermissions.some((permission) => { if (permission.roles.includes(userRole)) { return permission.actions.includes(requiredAction) || permission.actions.includes("*:*"); } return false; }); } var role_based_authentication_middleware_default = roleBasedAuthenticationMiddleware; // src/middleware/auth-cookie-verification.middleware.ts var validateJwtCookieMiddleware = async (req, res, next) => { try { const { appendToRequest = [], tokenGenerationHandler, cookieSettings = {}, authTokenPayloadVerifier, refreshTokenPayloadVerifier, refreshTokenHolderVerifier, tokenStorage } = middlewareConfigs; const accessToken = req.cookies && cookieSettings.accessTokenCookieName ? req.cookies[cookieSettings.accessTokenCookieName] : void 0; const refreshToken = req.cookies && cookieSettings.refreshTokenCookieName ? req.cookies[cookieSettings.refreshTokenCookieName] : void 0; if (!accessToken && !refreshToken) { throw new Error("Auth cookie not found!"); } log("debug", "Auth cookie and middleware configurations extracted."); log("debug", `Access token: ${accessToken} | Refresh token: ${refreshToken}`); const refreshTokenHandler = new TokenHandler({ refreshTokenStorage: tokenStorage, tokenGenerationHandler, authTokenPayloadVerifier, refreshTokenPayloadVerifier, refreshTokenHolderVerifier }); log("debug", "Token handler created."); const { decodedToken, nextRefreshToken, token } = await refreshTokenHandler.validateOrRefreshAuthToken( accessToken, refreshToken ); log("debug", "Token handler validated or refreshed the auth token."); if (!decodedToken) { throw new Error("Auth cookie payload is undefined!"); } appendTokenPayloadToRequest(req, appendToRequest, decodedToken); log("debug", "Token payload appended to the request object."); if (cookieSettings.accessTokenCookieName) { log("debug", "New access token set in the cookie."); res.cookie(cookieSettings.accessTokenCookieName, token, cookieSettings.accessCookieOptions || {}); } if (cookieSettings.refreshTokenCookieName && nextRefreshToken) { log("debug", "New refresh token set in the cookie."); res.cookie(cookieSettings.refreshTokenCookieName, nextRefreshToken, cookieSettings.refreshCookieOptions || {}); } log("debug", "Token handler completed successfully."); next(); } catch (error) { log("error", "Error occurred while authenticating the JST token.", error); const errorMessage = error instanceof Error ? error.message : "Unknown error"; res.status(401).json({ message: "Unauthorized", error: errorMessage }); } }; var auth_cookie_verification_middleware_default = validateJwtCookieMiddleware; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { JwtManager, roleBasedAuthenticationMiddleware, setDefaultSignOptions, setDefaultVerifyOptions, sign, validateJwtCookieMiddleware, validateJwtHeaderMiddleware, verify }); //# sourceMappingURL=index.js.map