From bb80cdf5a6157ca1f3a276e12e9faae9a4739cb7 Mon Sep 17 00:00:00 2001
From: dh_ackergaul <dh_ackergaul@dh-software.de>
Date: Di, 23 Jun 2026 11:16:18 +0200
Subject: [PATCH] Update emvheya - 23.6.2026, 11:16:10 [JD]
---
manufacturer/_furnview/furnplan-web/node_modules/@dh-software/opus-x-openid-client-helper/dist/functions.js | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/manufacturer/_furnview/furnplan-web/node_modules/@dh-software/opus-x-openid-client-helper/dist/functions.js b/manufacturer/_furnview/furnplan-web/node_modules/@dh-software/opus-x-openid-client-helper/dist/functions.js
new file mode 100644
index 0000000..55d3207
--- /dev/null
+++ b/manufacturer/_furnview/furnplan-web/node_modules/@dh-software/opus-x-openid-client-helper/dist/functions.js
@@ -0,0 +1,217 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+const BACKCHANNEL_LOGOUT_EVENT = "http://schemas.openid.net/event/backchannel-logout";
+/**
+ * Discovers the OpenID Connect provider configuration and returns an authenticated client configuration.
+ *
+ * Uses the `ClientSecretBasic` authentication method and performs
+ * [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)
+ * against the issuer URL.
+ *
+ * @param registration - The client registration details (issuer, credentials, redirect URI).
+ * @param allowInsecureRequests - When `true`, permits plain HTTP requests (useful for local development). Defaults to `false`.
+ * @returns A resolved `Configuration` that can be passed to {@link getAuthenticationAttempt} and {@link callback}.
+ * @throws If discovery fails or the issuer is unreachable.
+ *
+ * @example
+ * ```ts
+ * const config = await getConfig({
+ * issuer: "https://auth.example.com",
+ * clientId: "my-app",
+ * clientSecret: "secret",
+ * redirectUri: "https://my-app.example.com/callback"
+ * });
+ * ```
+ */
+export function getConfig(registration_1) {
+ return __awaiter(this, arguments, void 0, function* (registration, allowInsecureRequests = false) {
+ const openId = yield import("openid-client");
+ return openId.discovery(new URL(registration.issuer), registration.clientId, registration.clientSecret, openId.ClientSecretBasic(registration.clientSecret), { execute: allowInsecureRequests ? [openId.allowInsecureRequests] : [] });
+ });
+}
+/**
+ * Builds an authorization URL with PKCE and a random state parameter.
+ *
+ * Returns an {@link AuthenticationAttempt} whose `codeVerifier` and `state` must be
+ * persisted in the user's session so they can be validated in the {@link callback} step.
+ *
+ * @param config - The OpenID Connect configuration obtained from {@link getConfig}.
+ * @param redirectUri - The callback URI the provider should redirect to after authentication.
+ * @param scope - Space-separated OAuth 2.0 scopes to request. Defaults to `"openid offline_access profile"`.
+ * @returns An {@link AuthenticationAttempt} containing the authorization URL and PKCE/state values.
+ *
+ * @example
+ * ```ts
+ * const attempt = await getAuthenticationAttempt(config, "https://my-app.example.com/callback");
+ *
+ * // Store in session for later verification
+ * session.codeVerifier = attempt.codeVerifier;
+ * session.state = attempt.state;
+ *
+ * // Redirect the user's browser
+ * res.redirect(attempt.url.toString());
+ * ```
+ */
+export function getAuthenticationAttempt(config, redirectUri, scope) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const openId = yield import("openid-client");
+ const codeVerifier = openId.randomPKCECodeVerifier();
+ const codeChallenge = yield openId.calculatePKCECodeChallenge(codeVerifier);
+ const state = openId.randomState();
+ const url = openId.buildAuthorizationUrl(config, {
+ redirect_uri: redirectUri,
+ scope: scope || "openid offline_access profile",
+ code_challenge: codeChallenge,
+ code_challenge_method: "S256",
+ state
+ });
+ return { codeVerifier, codeChallenge, state, url };
+ });
+}
+/**
+ * Builds an RP-initiated logout URL for ending the user's session at the identity provider.
+ *
+ * Returns a URL that redirects the user's browser to the provider's end session endpoint,
+ * which will then redirect back to `postLogoutRedirectURI` after the logout completes.
+ *
+ * @param config - The OpenID Connect configuration obtained from {@link getConfig}.
+ * @param postLogoutRedirectURI - The URI the provider should redirect to after the user is logged out.
+ * @param idToken - The `id_token` received during login, passed as `id_token_hint` to identify the session being ended.
+ * @returns A `URL` to redirect the user's browser to in order to trigger logout at the identity provider.
+ *
+ * @example
+ * ```ts
+ * const logoutUrl = await buildLogoutURL(
+ * config,
+ * "https://my-app.example.com/",
+ * session.idToken
+ * );
+ * res.redirect(logoutUrl.toString());
+ * ```
+ */
+export function buildLogoutURL(config, postLogoutRedirectURI, idToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const openId = yield import("openid-client");
+ return openId.buildEndSessionUrl(config, {
+ post_logout_redirect_uri: postLogoutRedirectURI,
+ id_token_hint: idToken,
+ });
+ });
+}
+/**
+ * Handles the OAuth 2.0 authorization code callback.
+ *
+ * Exchanges the authorization code for tokens, decodes the ID token claims,
+ * and fetches additional user information from the UserInfo endpoint.
+ *
+ * @param config - The OpenID Connect configuration obtained from {@link getConfig}.
+ * @param codeVerifier - The PKCE code verifier stored during the {@link getAuthenticationAttempt} step.
+ * @param state - The state value stored during the {@link getAuthenticationAttempt} step.
+ * @param requestUrl - The full callback request URL (including query parameters) from the identity provider redirect.
+ * @returns An {@link AuthenticationResult} with the token set, ID token claims, and user info.
+ *
+ * @example
+ * ```ts
+ * // Inside your /callback route handler:
+ * const requestUrl = new URL(req.url, "https://my-app.example.com");
+ * const result = await callback(config, session.codeVerifier, session.state, requestUrl);
+ *
+ * console.log(result.claims.sub); // unique user identifier
+ * console.log(result.claims.customer_no); // application-specific customer number
+ * console.log(result.userInfo.email); // email from UserInfo endpoint
+ * ```
+ */
+export function callback(config, codeVerifier, state, requestUrl) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const openId = yield import("openid-client");
+ const tokenSet = yield openId.authorizationCodeGrant(config, requestUrl, {
+ pkceCodeVerifier: codeVerifier,
+ expectedState: state
+ });
+ const claims = tokenSet.claims();
+ const userInfo = yield openId.fetchUserInfo(config, tokenSet.access_token, claims.sub);
+ return { tokenSet, claims, userInfo };
+ });
+}
+/**
+ * Validates an OpenID Connect
+ * [Back-Channel Logout Token](https://openid.net/specs/openid-connect-backchannel-1_0.html#Validation)
+ * received at the relying party's back-channel logout endpoint.
+ *
+ * Verifies the `logout_token` JWT signature against the provider's JWKS (discovered via {@link getConfig}),
+ * enforces `iss` and `aud` match the configured issuer and client, and validates the
+ * logout-specific claim rules:
+ *
+ * - `iat`, `jti`, and `events` are required.
+ * - `events` must contain the `http://schemas.openid.net/event/backchannel-logout` key.
+ * - At least one of `sub` or `sid` must be present.
+ * - `nonce` must NOT be present.
+ *
+ * Replay protection is the caller's responsibility: persist the returned `jti` and reject any
+ * logout_token whose `jti` has already been seen within a reasonable window.
+ *
+ * @param config - The OpenID Connect configuration obtained from {@link getConfig}.
+ * @param logoutToken - The raw `logout_token` JWT posted by the identity provider.
+ * @returns The validated {@link LogoutTokenClaims} (including `sub` and/or `sid`).
+ * @throws If the signature is invalid, issuer/audience do not match, required claims are missing,
+ * the `events` claim lacks the back-channel logout event, or a `nonce` claim is present.
+ *
+ * @example
+ * ```ts
+ * // POST /backchannel-logout
+ * const logoutToken = req.body.logout_token;
+ * const claims = await validateLogoutToken(config, logoutToken);
+ *
+ * if (await seenJti(claims.jti)) return res.status(400).end();
+ * await rememberJti(claims.jti);
+ *
+ * if (claims.sid) await terminateSessionsBySid(claims.sid);
+ * else if (claims.sub) await terminateAllSessionsForUser(claims.sub);
+ *
+ * res.status(200).end();
+ * ```
+ */
+export function validateLogoutToken(config, logoutToken) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const jose = yield import("jose");
+ const serverMetadata = config.serverMetadata();
+ if (!serverMetadata.jwks_uri) {
+ throw new Error("Issuer metadata is missing jwks_uri; cannot verify logout_token");
+ }
+ const jwks = jose.createRemoteJWKSet(new URL(serverMetadata.jwks_uri));
+ const { payload } = yield jose.jwtVerify(logoutToken, jwks, {
+ issuer: serverMetadata.issuer,
+ audience: config.clientMetadata().client_id,
+ requiredClaims: ["iat", "jti", "events"]
+ });
+ if ("nonce" in payload) {
+ throw new Error("logout_token MUST NOT contain a nonce claim");
+ }
+ const events = payload.events;
+ if (typeof events !== "object" || events === null || Array.isArray(events) ||
+ !(BACKCHANNEL_LOGOUT_EVENT in events)) {
+ throw new Error(`logout_token events claim must contain "${BACKCHANNEL_LOGOUT_EVENT}"`);
+ }
+ const sub = typeof payload.sub === "string" ? payload.sub : undefined;
+ const sid = typeof payload.sid === "string" ? payload.sid : undefined;
+ if (!sub && !sid) {
+ throw new Error("logout_token must contain at least one of sub or sid");
+ }
+ return {
+ iss: payload.iss,
+ aud: payload.aud,
+ iat: payload.iat,
+ jti: payload.jti,
+ events: events,
+ sub,
+ sid
+ };
+ });
+}
--
Gitblit v1.9.3