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