@sphereon/ssi-express-support
Version:
1,031 lines (1,020 loc) • 31 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/entra-id-auth.ts
import passport from "passport";
var EntraIDAuth = class _EntraIDAuth {
static {
__name(this, "EntraIDAuth");
}
strategy;
options;
static init(strategy) {
return new _EntraIDAuth(strategy);
}
constructor(strategy) {
this.strategy = strategy;
}
withOptions(options) {
this.options = {
...options,
passReqToCallback: "passReqToCallback" in options ? options.passReqToCallback : false
};
return this;
}
connectPassport() {
const _options = this.options;
if (!_options) {
throw Error("No options supplied for EntraID");
}
import("passport-azure-ad").then((entraID) => passport.use(this.strategy, new entraID.BearerStrategy(_options, function(token, cb) {
if (token) {
return cb(null, token);
}
return cb("bearer token not found or incorrect", null);
}))).catch((reason) => {
console.log(reason);
throw Error('Could not create bearer strategy. Did you include the "passport-azure-ad/bearer-strategy" dependency in package.json?');
});
}
};
// src/oidc-bearer-auth.ts
import passport2 from "passport";
var OIDCBearerAuth = class _OIDCBearerAuth {
static {
__name(this, "OIDCBearerAuth");
}
strategy;
options = {};
static init(strategy) {
return new _OIDCBearerAuth(strategy);
}
constructor(strategy) {
this.strategy = strategy;
}
withIssuer(issuer) {
this.options = {
...this.options,
issuer
};
return this;
}
withAudience(audience) {
this.options = {
...this.options,
audience
};
return this;
}
withJwksUri(jwksUri) {
this.options = {
...this.options,
jwksUri
};
return this;
}
withAlgorithms(algorithms) {
this.options = {
...this.options,
algorithms
};
return this;
}
withOptions(options) {
this.options = {
...this.options,
...options
};
return this;
}
async connectPassport() {
const { issuer, audience, algorithms } = this.options;
if (!issuer) {
return Promise.reject(new Error("No issuer supplied for OIDC Bearer Auth"));
}
let jwksUri = this.options.jwksUri;
if (!jwksUri) {
jwksUri = await this.discoverJwksUri(issuer);
}
try {
const [passportJwt, jwksRsa] = await Promise.all([
import("passport-jwt"),
import("jwks-rsa")
]);
const { Strategy: JwtStrategy, ExtractJwt } = passportJwt;
const { passportJwtSecret } = jwksRsa;
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri
}),
issuer,
audience,
algorithms: algorithms ?? [
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512"
]
};
passport2.use(this.strategy, new JwtStrategy(jwtOptions, (payload, done) => {
if (payload) {
return done(null, payload);
}
return done("Bearer token not found or incorrect", null);
}));
} catch (error) {
console.error("Failed to initialize OIDC Bearer Auth:", error);
return Promise.reject(new Error('Could not create JWT bearer strategy. Did you include "passport-jwt" and "jwks-rsa" dependencies in package.json?', {
cause: error
}));
}
}
async discoverJwksUri(issuer) {
const wellKnownUrl = `${issuer}${issuer.endsWith("/") ? "" : "/"}.well-known/openid-configuration`;
try {
const response = await fetch(wellKnownUrl);
if (!response.ok) {
return Promise.reject(new Error(`Failed to fetch OIDC configuration from ${wellKnownUrl}: ${response.status} ${response.statusText}`));
}
const config = await response.json();
if (!config.jwks_uri) {
return Promise.reject(new Error(`OIDC configuration at ${wellKnownUrl} does not contain jwks_uri`));
}
return config.jwks_uri;
} catch (error) {
return Promise.reject(new Error(`Failed to discover JWKS URI from OIDC configuration at ${wellKnownUrl}`, {
cause: error
}));
}
}
};
// src/static-bearer-auth.ts
import passport3 from "passport";
import { toString } from "uint8arrays/to-string";
var StaticBearerAuth = class _StaticBearerAuth {
static {
__name(this, "StaticBearerAuth");
}
strategy;
static providers = /* @__PURE__ */ new Map();
static verifyOptions = /* @__PURE__ */ new Map();
hashTokens = false;
static init(strategy, provider) {
return new _StaticBearerAuth(strategy ?? "bearer", provider ?? new MapBasedStaticBearerUserProvider(strategy));
}
constructor(strategy, provider) {
this.strategy = strategy;
if (_StaticBearerAuth.providers.has(strategy)) {
if (_StaticBearerAuth.providers.get(strategy) !== provider) {
throw Error("Cannot register another user provider for strategy: " + strategy);
}
} else {
_StaticBearerAuth.providers.set(strategy, provider);
}
}
get provider() {
const provider = _StaticBearerAuth.providers.get(this.strategy);
if (!provider) {
throw Error("Could not get user provider for " + this.strategy);
}
return provider;
}
withHashTokens(hashTokens) {
this.hashTokens = hashTokens;
return this;
}
withUsers(users) {
this.addUser(users);
return this;
}
addUser(user) {
this.provider.addUser(user);
return this;
}
withVerifyOptions(options) {
_StaticBearerAuth.verifyOptions.set(this.strategy, options);
return this;
}
connectPassport() {
const _provider = this.provider;
function findUser(token, cb) {
const user = _provider.getUser(token);
if (user) {
return cb(null, user);
}
return cb("bearer token not found or incorrect", false);
}
__name(findUser, "findUser");
import("passport-http-bearer").then((httpBearer) => {
const hashTokens = this.hashTokens ?? false;
passport3.use(this.strategy, new httpBearer.Strategy({
passReqToCallback: false
}, function(token, cb) {
if (hashTokens) {
import("@noble/hashes/sha256").then((hash) => {
findUser(toString(hash.sha256(token)), cb);
}).catch((error) => {
console.log(`hash problem: ${error}`);
throw Error("Did you include @noble/hashes in package.json?");
});
} else {
findUser(token, cb);
}
}));
}).catch((error) => {
console.log(`passport-http-bearer package problem: ${error}`);
throw Error("Did you include passport-http-bearer in package.json?");
});
}
};
var MapBasedStaticBearerUserProvider = class {
static {
__name(this, "MapBasedStaticBearerUserProvider");
}
_strategy;
_users = [];
_hashedTokens;
constructor(strategy, hashedTokens) {
this._strategy = strategy;
this._hashedTokens = hashedTokens ?? false;
}
get users() {
return this._users;
}
get hashedTokens() {
return this._hashedTokens;
}
get strategy() {
return this._strategy;
}
getUser(token) {
return this.users.find((user) => user.token === token);
}
addUser(user, hashToken) {
const users = Array.isArray(user) ? user : [
user
];
if (hashToken) {
if (!this.hashedTokens) {
throw Error("Cannot hash token, when hashed tokens is not enabled on the user provider for strategy " + this.strategy);
}
import("@noble/hashes/sha256").then((hash) => {
users.forEach((user2) => user2.token = toString(hash.sha256(user2.token)));
}).catch((error) => {
console.log(`hash problem: ${error}`);
throw Error("Did you include @noble/hashes in package.json?");
});
}
this._users.push(...users);
}
getUsers() {
return this._users;
}
};
// src/auth-utils.ts
import passport4 from "passport";
// src/express-utils.ts
function sendErrorResponse(response, statusCode, message, error) {
let msg = message;
if (!msg) {
console.error("Message was null when calling sendErrorResponse. This should not happen");
msg = "An unexpected error occurred";
statusCode = 500;
} else {
console.error(`sendErrorResponse (${statusCode}): ${typeof msg === "string" ? msg : JSON.stringify(msg)}`);
}
if (error) {
if (error instanceof Error) {
console.error(`error message: ${error.message}`);
}
console.error(`error object: ${JSON.stringify(error)}`);
}
if (statusCode >= 500) {
console.error("Original error stack (if any) and REST API error stack:");
console.error(error?.stack);
console.error(Error().stack);
}
if (response.headersSent) {
console.error(`sendErrorResponse headers already sent`);
return response;
}
response.statusCode = statusCode;
if (typeof msg === "string" && !msg.startsWith("{")) {
msg = {
error: msg
};
}
if (typeof msg === "string" && msg.startsWith("{")) {
response.header("Content-Type", "application/json");
return response.status(statusCode).end(msg);
}
return response.status(statusCode).json(msg);
}
__name(sendErrorResponse, "sendErrorResponse");
var jsonErrorHandler = /* @__PURE__ */ __name((err, req, res, next) => {
const statusCode = "statusCode" in err ? err.statusCode : 500;
let errorMsg = typeof err === "string" ? err : err.message ?? err;
if (typeof errorMsg !== "string") {
errorMsg = JSON.stringify(errorMsg);
}
if (res.headersSent) {
console.log("Headers already sent, when calling error handler. Will defer to next error handler");
console.log(`Error was: ${JSON.stringify(err)}`);
return next(err);
}
return sendErrorResponse(res, statusCode, errorMsg, err);
}, "jsonErrorHandler");
// src/types.ts
function hasEndpointOpts(opts) {
return "endpointOpts" in opts && opts.endpointOpts;
}
__name(hasEndpointOpts, "hasEndpointOpts");
// src/auth-utils.ts
var checkUserIsInRole = /* @__PURE__ */ __name((opts) => (req, res, next) => {
if (!opts?.roles || opts.roles.length === 0) {
return next();
}
const roles = Array.isArray(opts.roles) ? opts.roles : [
opts.roles
];
if (!req?.user || !("role" in req.user)) {
return res.status(401).end();
}
const hasRole = roles.find((role) => req.user.role.toLowerCase() === role.toLowerCase());
if (!hasRole) {
return res.status(403).end();
}
return next();
}, "checkUserIsInRole");
var checkAuthenticationImpl = /* @__PURE__ */ __name((req, res, next, opts) => {
const defaultCallback = /* @__PURE__ */ __name((err, user, _info, _status) => {
if (err) {
const message = "message" in err ? err.message : err;
console.log("Authentication failed, error: " + JSON.stringify(message));
return next({
statusCode: 403,
message
});
} else if (!user) {
console.log("Authentication failed, no user object present in request. Redirecting to /login");
return res.redirect("/authentication/login");
}
if (options.session) {
req.logIn(user, function(err2) {
if (err2) {
return next(err2);
}
});
}
return next();
}, "defaultCallback");
if (!opts || !opts.authentication || opts.authentication.enabled === false) {
return next();
}
if (!opts.authentication.strategy) {
console.log(`Authentication enabled, but no strategy configured. All auth request will be denied!`);
return res.status(401).end();
}
const options = {
...opts?.authentication?.strategyOptions,
authInfo: opts?.authentication?.authInfo !== false,
session: opts?.authentication?.session !== false
};
const callback = opts?.authentication?.callback ?? (opts?.authentication?.useDefaultCallback ? defaultCallback : void 0);
passport4.authenticate(opts.authentication.strategy, options, callback).call(void 0, req, res, next);
}, "checkAuthenticationImpl");
var checkAuthorizationImpl = /* @__PURE__ */ __name((req, res, next, opts) => {
if (!opts || !opts.authentication || !opts.authorization || opts.authentication.enabled === false || opts?.authorization.enabled === false) {
return next();
}
const authorization = opts.authorization;
if (!authorization.enforcer && (!authorization.requireUserInRoles || authorization.requireUserInRoles.length === 0)) {
console.log(`Authorization enabled for endpoint, but no enforcer or roles supplied`);
return res.status(401).end();
}
if (authorization.requireUserInRoles && authorization.requireUserInRoles.length > 0) {
checkUserIsInRole({
roles: authorization.requireUserInRoles
});
}
if (authorization.enforcer) {
const enforcer = authorization.enforcer;
const permitted = enforcer.enforceSync(req.user, opts.resource, opts.operation);
if (!permitted) {
console.log(`Access to ${opts.resource} and op ${opts.operation} not allowed for ${req.user}`);
return res.status(403).end();
}
}
return next();
}, "checkAuthorizationImpl");
var checkAuthenticationOnly = /* @__PURE__ */ __name((opts) => (req, res, next) => {
return checkAuthenticationImpl(req, res, next, opts);
}, "checkAuthenticationOnly");
var checkAuthorizationOnly = /* @__PURE__ */ __name((opts) => (req, res, next) => {
return checkAuthorizationImpl(req, res, next, opts);
}, "checkAuthorizationOnly");
var isUserNotAuthenticated = /* @__PURE__ */ __name((req, res, next) => {
if (!req.user) {
next();
}
}, "isUserNotAuthenticated");
var isUserAuthenticated = /* @__PURE__ */ __name((req, res, next) => {
if (!req.user) {
return sendErrorResponse(res, 401, "Authentication required");
} else {
return next();
}
}, "isUserAuthenticated");
var checkAuth = /* @__PURE__ */ __name((opts) => {
const handlers = [];
handlers.push(checkAuthenticationOnly(opts));
handlers.push(checkAuthorizationOnly(opts));
opts?.handlers && handlers.push(...opts.handlers);
return handlers;
}, "checkAuth");
function copyGlobalAuthToEndpoint(args) {
const opts = args?.opts;
const key = args?.key;
if (!opts || !key || !hasEndpointOpts(opts)) {
return;
}
if (key === "basePath") {
return;
}
if (opts.endpointOpts?.globalAuth) {
if (opts.endpointOpts[key]?.disableGlobalAuth === true) {
return;
}
opts.endpointOpts[key] = {
...opts.endpointOpts[key],
endpoint: {
...opts.endpointOpts.globalAuth,
...opts.endpointOpts[key]?.endpoint
}
};
}
}
__name(copyGlobalAuthToEndpoint, "copyGlobalAuthToEndpoint");
function copyGlobalAuthToEndpoints(args) {
args?.keys.forEach((key) => copyGlobalAuthToEndpoint({
opts: args?.opts,
key
}));
}
__name(copyGlobalAuthToEndpoints, "copyGlobalAuthToEndpoints");
// src/express-builders.ts
import bodyParser from "body-parser";
import cors from "cors";
import express from "express";
import expressSession from "express-session";
import { createHttpTerminator } from "http-terminator";
import morgan from "morgan";
import passport5 from "passport";
// src/functions.ts
function env(key, prefix) {
if (!key) {
return void 0;
}
return process.env[`${prefix ? prefix.trim() : ""}${key}`];
}
__name(env, "env");
// src/express-builders.ts
var ExpressBuilder = class _ExpressBuilder {
static {
__name(this, "ExpressBuilder");
}
existingExpress;
hostnameOrIP;
port;
_handlers = [];
listenCallback;
_startListen = void 0;
envVarPrefix;
_corsConfigurer;
_sessionOpts;
_usePassportAuth = false;
_passportInitOpts;
_userIsInRole;
_enforcer;
_server;
_terminator;
_morgan;
constructor(opts) {
const { existingExpress, envVarPrefix } = opts ?? {};
if (existingExpress) {
this.withExpress(existingExpress);
}
this.envVarPrefix = envVarPrefix ?? "";
}
static fromExistingExpress(opts) {
return new _ExpressBuilder(opts ?? {});
}
static fromServerOpts(opts) {
const builder = new _ExpressBuilder({
existingExpress: opts?.existingExpress,
envVarPrefix: opts?.envVarPrefix
});
return builder.withEnableListenOpts({
...opts,
hostnameOrIP: opts.hostname,
startOnBuild: opts.startListening ?? false
});
}
enableListen(startOnBuild) {
if (startOnBuild !== void 0) {
this._startListen = startOnBuild;
}
return this;
}
withMorganLogging(opts) {
if (opts?.existingMorgan && (opts.format || opts.options)) {
throw Error("Cannot using an existing morgan with either a format or options");
}
this._morgan = opts?.existingMorgan ?? morgan(opts?.format ?? "dev", opts?.options);
return this;
}
withEnableListenOpts({ port, hostnameOrIP, callback, startOnBuild }) {
port && this.withPort(port);
hostnameOrIP && this.withHostname(hostnameOrIP);
if (typeof callback === "function") {
this.withListenCallback(callback);
}
this._startListen = startOnBuild === true;
return this;
}
withPort(port) {
this.port = port;
return this;
}
withHostname(hostnameOrIP) {
this.hostnameOrIP = hostnameOrIP;
return this;
}
withListenCallback(callback) {
this.listenCallback = callback;
return this;
}
withExpress(existingExpress) {
this.existingExpress = existingExpress;
this._startListen = false;
return this;
}
withCorsConfigurer(configurer) {
this._corsConfigurer = configurer;
return this;
}
withPassportAuth(usePassport, initializeOptions) {
this._usePassportAuth = usePassport;
this._passportInitOpts = initializeOptions;
return this;
}
withGlobalUserIsInRole(userIsInRole) {
this._userIsInRole = userIsInRole;
return this;
}
withEnforcer(enforcer) {
this._enforcer = enforcer;
return this;
}
startListening(express3) {
this._server = express3.listen(this.getPort(), this.getHostname(), this.listenCallback);
this._terminator = createHttpTerminator({
server: this._server
});
return {
server: this._server,
terminator: this._terminator
};
}
getHostname() {
return this.hostnameOrIP ?? env("HOSTNAME", this.envVarPrefix) ?? "0.0.0.0";
}
getPort() {
return this.port ?? env("PORT", this.envVarPrefix) ?? 5e3;
}
setHandlers(handlers) {
if (Array.isArray(handlers)) {
this._handlers = handlers;
} else if (handlers) {
if (!this._handlers) {
this._handlers = [];
}
this._handlers.push(handlers);
} else {
this._handlers = [];
}
return this;
}
addHandler(handler) {
if (!this._handlers) {
this._handlers = [];
}
this._handlers.push(handler);
return this;
}
withSessionOptions(sessionOpts) {
this._sessionOpts = sessionOpts;
return this;
}
build(opts) {
const express3 = this.buildExpress(opts);
const startListening = opts?.startListening === void 0 ? this._startListen !== true : opts.startListening;
let started = this._server !== void 0;
if (startListening && !started) {
this.startListening(express3);
started = true;
}
return {
express: express3,
port: this.getPort(),
hostname: this.getHostname(),
userIsInRole: this._userIsInRole,
startListening,
enforcer: this._enforcer,
start: /* @__PURE__ */ __name((opts2) => {
if (opts2?.doNotStartListening) {
console.log("Express will not start listening. You will have to start it yourself");
} else {
if (!started) {
this.startListening(express3);
started = true;
}
}
if (opts2?.disableErrorHandler !== true) {
express3.use(jsonErrorHandler);
}
return {
server: this._server,
terminator: this._terminator
};
}, "start"),
stop: /* @__PURE__ */ __name(async (terminator) => {
const term = terminator ?? this._terminator;
if (!term) {
return false;
}
return await term.terminate().then(() => true);
}, "stop")
};
}
buildExpress(opts) {
const app = opts?.express ?? this.existingExpress ?? express();
if (this._morgan) {
app.use(this._morgan);
}
if (this._sessionOpts) {
const store = this._sessionOpts.store ?? new expressSession.MemoryStore();
this._sessionOpts.store = store;
app.use(expressSession(this._sessionOpts));
}
if (this._usePassportAuth) {
app.use(passport5.initialize(this._passportInitOpts));
if (this._sessionOpts) {
app.use(passport5.session());
}
}
if (this._userIsInRole) {
app.use(checkUserIsInRole({
roles: this._userIsInRole
}));
}
if (this._corsConfigurer) {
this._corsConfigurer.configure({
existingExpress: app
});
}
this._handlers && this._handlers.length > 0 && app.use(this._handlers);
opts?.handlers && app.use(opts.handlers);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json({
limit: "5mb"
}));
return app;
}
};
var ExpressCorsConfigurer = class {
static {
__name(this, "ExpressCorsConfigurer");
}
_disableCors;
_enablePreflightOptions;
_allowOrigin;
_allowMethods;
_allowedHeaders;
_allowCredentials;
_express;
_envVarPrefix;
constructor(args) {
const { existingExpress, envVarPrefix } = args ?? {};
this._express = existingExpress;
this._envVarPrefix = envVarPrefix;
}
allowOrigin(value) {
this._allowOrigin = value;
return this;
}
disableCors(value) {
this._disableCors = value;
return this;
}
allowMethods(value) {
this._allowMethods = value;
return this;
}
allowedHeaders(value) {
this._allowedHeaders = value;
return this;
}
allowCredentials(value) {
this._allowCredentials = value;
return this;
}
configure({ existingExpress }) {
const express3 = existingExpress ?? this._express;
if (!express3) {
throw Error("No express passed in during construction or configure");
}
const disableCorsEnv = env("CORS_DISABLE", this._envVarPrefix);
const corsDisabled = this._disableCors ?? (disableCorsEnv ? /true/.test(disableCorsEnv) : false);
if (corsDisabled) {
return;
}
const envAllowOriginStr = env("CORS_ALLOW_ORIGIN", this._envVarPrefix) ?? "*";
let envAllowOrigin;
if (envAllowOriginStr.includes(",")) {
envAllowOrigin = envAllowOriginStr.split(",");
} else if (envAllowOriginStr.includes(" ")) {
envAllowOrigin = envAllowOriginStr.split(" ");
} else {
envAllowOrigin = envAllowOriginStr;
}
if (Array.isArray(envAllowOrigin) && envAllowOrigin.length === 1) {
envAllowOrigin = envAllowOrigin[0];
}
const corsOptions = {
origin: this._allowOrigin ?? envAllowOrigin,
// todo: env vars
...this._allowMethods && {
methods: this._allowMethods
},
...this._allowedHeaders && {
allowedHeaders: this._allowedHeaders
},
...this._allowCredentials !== void 0 && {
credentials: this._allowCredentials
},
optionsSuccessStatus: 204
};
if (this._enablePreflightOptions) {
express3.options("*", cors(corsOptions));
}
express3.use(cors(corsOptions));
}
};
// src/openid-connect-rp.ts
import express2 from "express";
import { Issuer } from "openid-client";
import passport6 from "passport";
var PREFIX = process.env.PREFIX ?? "";
async function oidcDiscoverIssuer(opts) {
const issuerUrl = opts?.issuerUrl ?? env("OIDC_ISSUER", PREFIX) ?? "https://auth01.test.sphereon.com/auth/realms/energy-shr";
const issuer = await Issuer.discover(issuerUrl);
console.log("Discovered issuer %s %O", issuer.issuer, issuer.metadata);
return {
issuer,
issuerUrl
};
}
__name(oidcDiscoverIssuer, "oidcDiscoverIssuer");
async function oidcGetClient(issuer, metadata, opts) {
return new issuer.Client(metadata, opts?.jwks, opts?.options);
}
__name(oidcGetClient, "oidcGetClient");
function getLoginEndpoint(router, opts) {
if (opts?.enabled === false) {
console.log(`Login endpoint is disabled`);
return;
}
const strategy = opts?.endpoint?.authentication?.strategy;
if (!strategy) {
throw Error("strategy needs to be provided");
}
const path = opts?.path ?? "/authentication/login";
router.get(path, (req, res, next) => {
const redirectPage = req.get("referer") ?? "/";
req.session.redirectPage = redirectPage;
next();
}, passport6.authenticate(strategy, {
...opts.authentication?.strategyOptions,
...opts.endpoint?.authentication?.strategyOptions,
keepSessionInfo: false
}, void 0));
}
__name(getLoginEndpoint, "getLoginEndpoint");
function getLoginCallbackEndpoint(router, opts) {
if (opts?.enabled === false) {
console.log(`Auth callback endpoint is disabled`);
return;
}
const strategy = opts?.endpoint?.authentication?.strategy;
if (!strategy) {
throw Error("strategy needs to be provided");
}
const path = opts?.path ?? "/authentication/callback";
router.get(path, passport6.authenticate(strategy, {
...opts.authentication?.strategyOptions,
...opts.endpoint?.authentication?.strategyOptions,
keepSessionInfo: true
}, void 0), (req, res, next) => {
if (req.user) {
console.log("User authenticated", req.user?.name);
const redirectPage = req.session.redirectPage ?? "/search";
delete req.session.redirectPage;
return res.redirect(redirectPage);
} else {
return res.redirect(env("OIDC_FRONTEND_LOGIN_URL", PREFIX) ?? "http://localhost:3001/authentication/login");
}
});
}
__name(getLoginCallbackEndpoint, "getLoginCallbackEndpoint");
function getLogoutEndpoint(router, client, opts) {
if (opts?.enabled === false) {
console.log(`Logout endpoint is disabled`);
return;
}
const path = opts?.path ?? "/authentication/logout";
router.get(path, (req, res) => {
try {
if (client.endSessionUrl()) {
return res.redirect(client.endSessionUrl());
} else {
console.log("IDP does not support end session url");
return res.redirect("/authentication/logout-callback");
}
} catch (error) {
console.log(error);
return res.redirect("/authentication/logout-callback");
}
});
}
__name(getLogoutEndpoint, "getLogoutEndpoint");
function getLogoutCallbackEndpoint(router, opts) {
if (opts?.enabled === false) {
console.log(`Logout callback endpoint is disabled`);
return;
}
const path = opts?.path ?? "/authentication/logout-callback";
router.get(path, (req, res, next) => {
try {
req.logout((err) => {
if (err) {
console.log(`Error during calling logout-callback: ${JSON.stringify(err)}`);
}
});
return res.redirect(env("OIDC_FRONTEND_LOGOUT_REDIRECT_URL", PREFIX) ?? "/");
} catch (e) {
return sendErrorResponse(res, 500, "An unexpected error occurred during logout callback", e);
}
});
}
__name(getLogoutCallbackEndpoint, "getLogoutCallbackEndpoint");
function getIdTokenEndpoint(router, client, opts) {
if (opts?.enabled === false) {
console.log(`ID Token endpoint is disabled`);
return;
}
const path = opts.path ?? "/authentication/tokens/id";
router.get(path, isUserAuthenticated, (req, res) => {
if (req.session.tokens.id_token) {
return res.json({
id_token: req.session.tokens.id_token
});
} else {
return sendErrorResponse(res, 401, "Authentication required");
}
});
}
__name(getIdTokenEndpoint, "getIdTokenEndpoint");
function getAuthenticatedUserEndpoint(router, opts) {
if (opts?.enabled === false) {
console.log(`Authenticated User endpoint is disabled`);
return;
}
const path = opts?.path ?? "/authentication/user";
router.get(path, isUserAuthenticated, (req, res, next) => {
if (!req.user) {
return sendErrorResponse(res, 401, "Authentication required");
}
let user = req.user;
return res.json(user);
});
}
__name(getAuthenticatedUserEndpoint, "getAuthenticatedUserEndpoint");
var OpenIDConnectAuthApi = class {
static {
__name(this, "OpenIDConnectAuthApi");
}
get router() {
return this._router;
}
_express;
_agent;
_opts;
_router;
constructor(args) {
const { agent, opts } = args;
this._agent = agent;
copyGlobalAuthToEndpoints({
opts,
keys: [
"getLogin"
]
});
copyGlobalAuthToEndpoints({
opts,
keys: [
"getIdToken"
]
});
copyGlobalAuthToEndpoints({
opts,
keys: [
"getAuthenticatedUser"
]
});
this._opts = opts;
this._express = args.expressSupport.express;
this._router = express2.Router();
const features = opts?.enabledFeatures ?? [
"login",
"logout",
"id-token",
"authenticated-user"
];
console.log(`Authentication API enabled`);
if (features.includes("login")) {
getLoginEndpoint(this.router, opts?.endpointOpts?.getLogin);
getLoginCallbackEndpoint(this.router, opts?.endpointOpts?.getLogin);
}
if (features.includes("logout")) {
getLogoutEndpoint(this.router, args.client, opts?.endpointOpts?.getLogout);
getLogoutCallbackEndpoint(this.router, opts?.endpointOpts?.getLogout);
}
if (features.includes("id-token")) {
if (opts.endpointOpts?.getIdToken === void 0) {
throw Error("Cannot enable id-token endpoint without providing id-token endpoint options");
}
getIdTokenEndpoint(this.router, args.client, opts?.endpointOpts?.getIdToken);
}
if (features.includes("authenticated-user")) {
getAuthenticatedUserEndpoint(this.router, opts?.endpointOpts?.getAuthenticatedUser);
}
this._express.use(opts?.endpointOpts?.basePath ?? "", this.router);
}
get agent() {
return this._agent;
}
get opts() {
return this._opts;
}
get express() {
return this._express;
}
};
export {
EntraIDAuth,
ExpressBuilder,
ExpressCorsConfigurer,
MapBasedStaticBearerUserProvider,
OIDCBearerAuth,
OpenIDConnectAuthApi,
StaticBearerAuth,
checkAuth,
checkAuthenticationOnly,
checkAuthorizationOnly,
checkUserIsInRole,
copyGlobalAuthToEndpoint,
copyGlobalAuthToEndpoints,
env,
getAuthenticatedUserEndpoint,
getIdTokenEndpoint,
getLoginCallbackEndpoint,
getLoginEndpoint,
getLogoutCallbackEndpoint,
getLogoutEndpoint,
hasEndpointOpts,
isUserAuthenticated,
isUserNotAuthenticated,
jsonErrorHandler,
oidcDiscoverIssuer,
oidcGetClient,
sendErrorResponse
};
//# sourceMappingURL=index.js.map