@sphereon/ssi-express-support
Version:
944 lines (933 loc) • 30.5 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
EntraIDAuth: () => EntraIDAuth,
ExpressBuilder: () => ExpressBuilder,
ExpressCorsConfigurer: () => ExpressCorsConfigurer,
MapBasedStaticBearerUserProvider: () => MapBasedStaticBearerUserProvider,
OpenIDConnectAuthApi: () => OpenIDConnectAuthApi,
StaticBearerAuth: () => StaticBearerAuth,
checkAuth: () => checkAuth,
checkAuthenticationOnly: () => checkAuthenticationOnly,
checkAuthorizationOnly: () => checkAuthorizationOnly,
checkUserIsInRole: () => checkUserIsInRole,
copyGlobalAuthToEndpoint: () => copyGlobalAuthToEndpoint,
copyGlobalAuthToEndpoints: () => copyGlobalAuthToEndpoints,
env: () => env,
getAuthenticatedUserEndpoint: () => getAuthenticatedUserEndpoint,
getIdTokenEndpoint: () => getIdTokenEndpoint,
getLoginCallbackEndpoint: () => getLoginCallbackEndpoint,
getLoginEndpoint: () => getLoginEndpoint,
getLogoutCallbackEndpoint: () => getLogoutCallbackEndpoint,
getLogoutEndpoint: () => getLogoutEndpoint,
hasEndpointOpts: () => hasEndpointOpts,
isUserAuthenticated: () => isUserAuthenticated,
isUserNotAuthenticated: () => isUserNotAuthenticated,
jsonErrorHandler: () => jsonErrorHandler,
oidcDiscoverIssuer: () => oidcDiscoverIssuer,
oidcGetClient: () => oidcGetClient,
sendErrorResponse: () => sendErrorResponse
});
module.exports = __toCommonJS(index_exports);
// src/entra-id-auth.ts
var import_passport = __toESM(require("passport"), 1);
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) => import_passport.default.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/static-bearer-auth.ts
var import_passport2 = __toESM(require("passport"), 1);
var import_to_string = require("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;
import_passport2.default.use(this.strategy, new httpBearer.Strategy({
passReqToCallback: false
}, function(token, cb) {
if (hashTokens) {
import("@noble/hashes/sha256").then((hash) => {
findUser((0, import_to_string.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 = (0, import_to_string.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
var import_passport3 = __toESM(require("passport"), 1);
// 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);
import_passport3.default.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
var import_body_parser = __toESM(require("body-parser"), 1);
var import_cors = __toESM(require("cors"), 1);
var import_express = __toESM(require("express"), 1);
var import_express_session = __toESM(require("express-session"), 1);
var import_http_terminator = require("http-terminator");
var import_morgan = __toESM(require("morgan"), 1);
var import_passport4 = __toESM(require("passport"), 1);
// 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 ?? (0, import_morgan.default)(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 = (0, import_http_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 ?? (0, import_express.default)();
if (this._morgan) {
app.use(this._morgan);
}
if (this._sessionOpts) {
const store = this._sessionOpts.store ?? new import_express_session.default.MemoryStore();
this._sessionOpts.store = store;
app.use((0, import_express_session.default)(this._sessionOpts));
}
if (this._usePassportAuth) {
app.use(import_passport4.default.initialize(this._passportInitOpts));
if (this._sessionOpts) {
app.use(import_passport4.default.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(import_body_parser.default.urlencoded({
extended: true
}));
app.use(import_body_parser.default.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("*", (0, import_cors.default)(corsOptions));
}
express3.use((0, import_cors.default)(corsOptions));
}
};
// src/openid-connect-rp.ts
var import_express2 = __toESM(require("express"), 1);
var import_openid_client = require("openid-client");
var import_passport5 = __toESM(require("passport"), 1);
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 import_openid_client.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();
}, import_passport5.default.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, import_passport5.default.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 = import_express2.default.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;
}
};
//# sourceMappingURL=index.cjs.map