@httpc/kit
Version:
httpc toolbox for building function-based API with minimal code and end-to-end type safety
133 lines (132 loc) • 5.05 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JwtService = exports.JWT_CLAIMS = void 0;
const jws_1 = __importDefault(require("jws"));
const tsyringe_1 = require("tsyringe");
const logging_1 = require("../logging");
const di_1 = require("../di");
const services_1 = require("../services");
const utils_1 = require("../utils");
const JWT_CLAIMS_MAP = {
audience: "aud",
expireAt: "exp",
issuer: "iss",
subject: "sub"
};
exports.JWT_CLAIMS = [
"sub",
"aud",
"iss",
"exp",
"exp",
"nbf",
"jti",
"iat"
];
let JwtService = class JwtService extends (0, services_1.BaseService)() {
constructor(logger, options = {}) {
//@ts-expect-error
super(...arguments);
this.options = options;
if (!options.secret) {
this.logger.warn("No JwtSecret set");
}
}
createToken(payload, options) {
const { secret = this.options?.secret, expireIn = this.options.defaultDuration, ...jwtProps } = options || {};
if (!secret) {
this._raiseError("misconfiguration", "Missing jwt-secret configuration");
}
payload = { ...payload }; // clone it because
if (!payload.exp && expireIn && expireIn > 0) {
jwtProps.expireAt = Math.floor(Date.now() / 1000) + expireIn;
}
// map options to props ( expireAt -> exp, audience -> aud, ... )
for (const key in JWT_CLAIMS_MAP) {
if (key in jwtProps) {
payload[JWT_CLAIMS_MAP[key]] = jwtProps[key];
}
}
return this.sign(payload, {
secret
});
}
decode(token, options) {
const secret = options?.secret || this.options.secret;
if (!secret) {
this._raiseError("misconfiguration", "Missing jwt-secret configuration");
}
const { header, payload } = jws_1.default.decode(token);
if (!jws_1.default.verify(token, header.alg, secret)) {
return;
}
return { header, payload };
}
validate(token, options) {
let header;
let payload;
try {
({ header, payload } = this.decode(token, options) || {});
}
catch (err) {
this.logger.warn("JwtToken malformed", err);
return { success: false, error: "malformed" };
}
if (!payload || !header) {
return { success: false, error: "invalid" };
}
const algorithm = options?.algorithm || "HS256";
if (header.alg !== algorithm) {
return { success: false, error: "invalid" };
}
const { exp } = payload;
if (exp && exp <= (Date.now() / 1000)) {
return { success: false, error: "expired", payload };
}
return { success: true, payload };
}
sign(payload, options) {
const secret = options?.secret || this.options.secret;
if (!secret) {
this._raiseError("misconfiguration", "Missing jwt-secret configuration");
}
return jws_1.default.sign({
header: { alg: "HS256", typ: "JWT" },
payload: (0, utils_1.cleanNotDefined)(payload),
secret,
});
}
};
JwtService = __decorate([
(0, tsyringe_1.singleton)(),
__param(0, (0, logging_1.logger)()),
__param(1, (0, di_1.options)(undefined)),
__metadata("design:paramtypes", [Object, Object])
], JwtService);
exports.JwtService = JwtService;
let DefaultJwtServiceOptions = class DefaultJwtServiceOptions {
constructor(secret) {
this.secret = secret;
}
};
DefaultJwtServiceOptions = __decorate([
(0, tsyringe_1.singleton)(),
(0, di_1.optionsOf)(JwtService),
__param(0, (0, di_1.env)("JWT_SECRET")),
__metadata("design:paramtypes", [String])
], DefaultJwtServiceOptions);