@intuitionrobotics/user-account
Version:
113 lines • 3.17 kB
JavaScript
import { BadImplementationException, currentTimeMillies } from "@intuitionrobotics/ts-common";
import { sign, ALGORITHMS } from "jws";
import { SecretsModule } from "./SecretsModule.js";
//Header
export const ALGORITHM = "alg";
export const CONTENT_TYPE = "cty";
export const TYPE = "typ";
export const KEY_ID = "kid";
//Payload
export const ISSUER = "iss";
export const SUBJECT = "sub";
export const EXPIRES_AT = "exp";
export const NOT_BEFORE = "nbf";
export const ISSUED_AT = "iat";
export const JWT_ID = "jti";
export const AUDIENCE = "aud";
export const TYP_DEFAULT = "JWT";
export class JWTBuilder {
payload = {};
header;
constructor(alg) {
this.assertAlg(alg);
this.header = {
[ALGORITHM]: alg
};
}
// Generic
addClaims(claims) {
Object.keys(claims).forEach(k => this.addClaim(k, claims[k]));
return this;
}
addClaim(key, value) {
this.payload[key] = value;
return this;
}
addHeader(key, value) {
this.header[key] = value;
return this;
}
// End Generic
setContentType = (cty) => {
this.header[CONTENT_TYPE] = cty;
return this;
};
setType = (typ) => {
this.header[TYPE] = typ;
return this;
};
setKeyID = (kid) => {
this.header[KEY_ID] = kid;
return this;
};
// Payload
setIssuer(iss) {
this.payload[ISSUER] = iss;
return this;
}
setSub(iss) {
this.payload[SUBJECT] = iss;
return this;
}
setExpiration(exp) {
this.payload[EXPIRES_AT] = exp;
return this;
}
setNotBefore(nbf) {
this.payload[NOT_BEFORE] = nbf;
return this;
}
setIssuedAt() {
this.payload[ISSUED_AT] = Math.floor(currentTimeMillies() / 1000);
}
setJWTID(jti) {
this.payload[JWT_ID] = jti;
return this;
}
setAudience(aud) {
this.payload[AUDIENCE] = aud;
return this;
}
// End Payload
getIssuer() {
return this.payload[ISSUER];
}
getAlgorithm() {
return this.header[ALGORITHM];
}
getExpiration() {
return this.payload[EXPIRES_AT];
}
getType() {
return this.header[TYPE];
}
assertAlg(alg) {
const foundAlg = ALGORITHMS.find(a => a === alg);
if (!foundAlg)
throw new BadImplementationException(`Algorithm with name ${alg} is not valid`);
}
build(secret) {
this.setIssuedAt();
if (!this.getType())
this.setType(TYP_DEFAULT);
if (!this.getIssuer())
// TODO move the config to the module which I need to create
this.setIssuer(SecretsModule.getIss());
if (!this.getExpiration())
throw new BadImplementationException("Missing expiration, cannot build a valid JWT without this value");
if (!this.getAlgorithm())
throw new BadImplementationException("Missing algorithm, cannot build a valid JWT without this value");
return sign({ secret, payload: this.payload, header: this.header });
}
}
//# sourceMappingURL=JWTBuilder.js.map