UNPKG

@immobiliarelabs/backstage-plugin-ldap-auth-backend

Version:

Backstage LDAP Authentication plugin, this packages adds backend authentication and token generation/validation/management; sibling of @immobiliarelabs/backstage-plugin-ldap-auth

139 lines (135 loc) 4.83 kB
'use strict'; var errors = require('@backstage/errors'); var auth = require('./auth.cjs.js'); var errors$1 = require('./errors.cjs.js'); var jwt = require('./jwt.cjs.js'); var ldap$1 = require('./ldap.cjs.js'); class ProviderLdapAuthProvider { checkUserExists; ldapAuthentication; authHandler; signInResolver; resolverContext; jwtValidator; ldapAuthenticationOptions; cookies; constructor(options) { this.authHandler = options.authHandler; this.signInResolver = options.signInResolver; this.checkUserExists = options.checkUserExists; this.ldapAuthentication = options.ldapAuthentication; this.resolverContext = options.resolverContext; this.ldapAuthenticationOptions = options.ldapAuthenticationOptions; this.cookies = options.cookies; this.jwtValidator = options.tokenValidator || new jwt.TokenValidatorNoop(); if (Array.isArray(this.ldapAuthenticationOptions?.ldapOpts?.url)) { this.ldapAuthenticationOptions.ldapOpts.url = this.ldapAuthenticationOptions.ldapOpts.url[0]; } } // must keep this methods for the interface async start() { return; } async frameHandler() { return; } async check(uid) { const exists = await this.checkUserExists({ ...this.ldapAuthenticationOptions, username: uid }); if (!exists) throw new errors.AuthenticationError(errors$1.JWT_INVALID_TOKEN); } async refresh(req, res) { try { if (req.method !== "POST") { throw new errors.AuthenticationError("Method not allowed"); } const { username, password } = req.body; const ctx = this.resolverContext; const token = req.cookies?.[this.cookies.field]; let result; if (username && password) { const { uid } = await this.ldapAuthentication( username, password, this.ldapAuthenticationOptions ); result = { uid }; } else if (token) { await this.jwtValidator.isValid(token); const { sub } = jwt.parseJwtPayload(token); const uid = sub.split(":").at(-1)?.split("/").at(-1); await this.check(uid); result = { uid }; } else { throw new errors.AuthenticationError(errors$1.AUTH_MISSING_CREDENTIALS); } const { profile } = await this.authHandler( { uid: result.uid }, ctx ); const backstageIdentity = await this.signInResolver( { profile, result }, ctx ); const response = { providerInfo: {}, profile, // this backstage user information from the token and formats // the reponse in way that's usable by the FE backstageIdentity: auth.prepareBackstageIdentityResponse(backstageIdentity) }; const { exp } = jwt.parseJwtPayload(backstageIdentity.token); const maxAge = Math.ceil( new Date(exp * 1e3).valueOf() - Date.now() + (this.jwtValidator?.increaseTokenExpireMs || 0) ); res.cookie(this.cookies.field, backstageIdentity.token, { maxAge, httpOnly: true, secure: this.cookies.secure }); res.json(response); } catch (e) { res.clearCookie(this.cookies.field); throw e; } } async logout(req, res) { const token = req.cookies?.[this.cookies.field]; await this.jwtValidator.isValid(token); this.jwtValidator.logout(token, jwt.normalizeTime(Date.now())); res.clearCookie(this.cookies.field); res.status(200).end(); } } const ldap = { create(options) { return ({ config, resolverContext }) => { const cnf = config.get( process.env.NODE_ENV || "development" ); cnf.cookies = { field: cnf?.cookies?.field || jwt.COOKIE_FIELD_KEY, secure: cnf?.cookies?.secure || false }; const authHandler = typeof options?.authHandler === "function" ? options?.authHandler : auth.defaultAuthHandler; const signInResolver = typeof options?.signIn?.resolver === "function" ? options?.signIn?.resolver : auth.defaultSigninResolver; const ldapAuthentication = typeof options?.resolvers?.ldapAuthentication === "function" ? options?.resolvers?.ldapAuthentication : ldap$1.defaultLDAPAuthentication; const checkUserExists = typeof options?.resolvers?.checkUserExists === "function" ? options?.resolvers?.checkUserExists : ldap$1.defaultCheckUserExists; return new ProviderLdapAuthProvider({ ldapAuthenticationOptions: cnf.ldapAuthenticationOptions, cookies: cnf.cookies, authHandler, signInResolver, checkUserExists, ldapAuthentication, resolverContext, tokenValidator: options.tokenValidator }); }; } }; exports.ProviderLdapAuthProvider = ProviderLdapAuthProvider; exports.ldap = ldap; //# sourceMappingURL=provider.cjs.js.map