import { IChassisContext, IChassisPlugin } from "../index"; import { jwt } from "../middleware"; import * as _ from "lodash"; import * as fs from "fs"; import axios from "axios"; import { KeycloakCerts } from "../helpers/KeycloakCerts"; /** * plugin has injects middleware 'after' every response is generated * * @param context * @param options * @returns {exports} */ export default class JWTPlugin implements IChassisPlugin { ALLOWED_ALGOS = ["RS256"]; name = "jwt"; title = "Inject plugins 'jwt' middleware"; context: IChassisContext; secretOrCertificate: string = null; ignoreVerify: boolean = false; algo: string; debug: boolean = false; keycloakCerts: KeycloakCerts; hasCertificate() { return !!this.secretOrCertificate; } getCertificate() { return this.secretOrCertificate; } install(_context: IChassisContext, _options: any) { this.context = _context; let options = _options as any; this.debug = _options.debug || false; this.secretOrCertificate = options.secret || null; if (options.certificateFile) { this.secretOrCertificate = this._loadPublicKey( options.certificateFile ); } this.ignoreVerify = options.verify === false; if (!this.ignoreVerify) { if (options.realmURL) { this._downloadPublicKey(options.realmURL); } if (options.keycloakURL) { this._downloadKeycloakCerts(options.keycloakURL); } } this.algo = options.algo || this.ALLOWED_ALGOS[0]; _context.middleware.set(new jwt(this)); this.context.log({ code: "plugin:jwt:installed", algo: this.algo, verify: options.verify, ignoreVerify: this.ignoreVerify, }); } _loadPublicKey(certificateFile: string) { const key = fs.readFileSync(certificateFile, "utf8"); this.context.log({ code: "plugin:jwt:cert:loaded", certificateFile: certificateFile, fileFound: !!key, }); return key; } _downloadKeycloakCerts(url: string) { this.keycloakCerts = new KeycloakCerts(this.context, url); this.context.log({ code: "plugin:jwt:keycloak:cert:loaded" }); // console.log("keyCloakCerts: %j", this.keycloakCerts); } _downloadPublicKey(url: string) { axios({ url: url }) .then((r) => { this.secretOrCertificate = "-----BEGIN RSA PUBLIC KEY-----\n" + r.data.public_key + "\n-----END RSA PUBLIC KEY-----"; this.context.log({ code: "plugin:jwt:cert:loaded", secretOrCertificate: this.secretOrCertificate, }); }) .catch((err) => { this.context.error({ code: "plugin:jwt:cert:load:failed", message: err.message, url: url, }); }); } }