From e0a009c13fc204e01bb82dbecb1730d3ba98f4bb Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Tue, 24 Oct 2023 12:23:16 +0200 Subject: [PATCH] #3 --- README.md | 33 +++++++++++++++++++++++---------- src/oidc.ts | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ec5b770..3265566 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ import { createOidc, decodeJwt } from "oidc-spa"; issuerUri: "https://auth.your-domain.net/auth/realms/myrealm", clientId: "myclient", // Optional, you can modify the url before redirection to the identity server + // Alternatively you can use: getExtraQueryParams: ()=> ({ ui_locales: "fr" }) transformUrlBeforeRedirect: url => `${url}&ui_locales=fr` /** * This parameter have to be provided provide if your App is not hosted at the origin of the subdomain. @@ -85,14 +86,18 @@ import { createOidc, decodeJwt } from "oidc-spa"; }); if (oidc.isUserLoggedIn) { - // This return a promise that never resolve. Your user will be redirected to the identity server. - // doesCurrentHrefRequiresAuth determines the behavior when a user gives up on loggin in and navigate back. - // We don't want to send him back to a authenticated route. - // If you are calling login because the user clicked - // on a 'login' button you should set doesCurrentHrefRequiresAuth to false. - // When you are calling login because your user navigated to a path that require authentication - // you should set doesCurrentHrefRequiresAuth to true - oidc.login({ doesCurrentHrefRequiresAuth: false }); + oidc.login({ + // This return a promise that never resolve. Your user will be redirected to the identity server. + // doesCurrentHrefRequiresAuth determines the behavior when a user gives up on loggin in and navigate back. + // We don't want to send him back to a authenticated route. + // If you are calling login because the user clicked + // on a 'login' button you should set doesCurrentHrefRequiresAuth to false. + // When you are calling login because your user navigated to a path that require authentication + // you should set doesCurrentHrefRequiresAuth to true + doesCurrentHrefRequiresAuth: false + //Optionally you can add some extra parameter to be added on the login url. + //extraQueryParams: { kc_idp_hint: "google" } + }); } else { const { // The accessToken is what you'll use as a Bearer token to authenticate to your APIs @@ -145,8 +150,16 @@ function App() { return ( <> You're not logged in. - ); diff --git a/src/oidc.ts b/src/oidc.ts index 4b106f0..5d27745 100644 --- a/src/oidc.ts +++ b/src/oidc.ts @@ -18,7 +18,10 @@ export declare namespace Oidc { export type NotLoggedIn = Common & { isUserLoggedIn: false; - login: (params: { doesCurrentHrefRequiresAuth: boolean }) => Promise; + login: (params: { + doesCurrentHrefRequiresAuth: boolean; + extraQueryParams?: Record; + }) => Promise; }; export type LoggedIn = Common & { @@ -45,6 +48,7 @@ export async function createOidc(params: { issuerUri: string; clientId: string; transformUrlBeforeRedirect?: (url: string) => string; + getExtraQueryParams?: () => Record; /** * This parameter have to be provided provide if your App is not hosted at the origin of the subdomain. * For example if your site is hosted by navigating to `https://www.example.com` @@ -60,7 +64,13 @@ export async function createOidc(params: { */ publicUrl?: string; }): Promise { - const { issuerUri, clientId, transformUrlBeforeRedirect = url => url, publicUrl = "" } = params; + const { + issuerUri, + clientId, + transformUrlBeforeRedirect = url => url, + getExtraQueryParams, + publicUrl = "" + } = params; const configHash = fnv1aHashToHex(`${issuerUri} ${clientId}`); const configHashKey = "configHash"; @@ -75,10 +85,14 @@ export async function createOidc(params: { "silent_redirect_uri": `${window.location.origin}${publicUrl}/silent-sso.html?${configHashKey}=${configHash}` }); - const login: Oidc.NotLoggedIn["login"] = async ({ doesCurrentHrefRequiresAuth }) => { + const login: Oidc.NotLoggedIn["login"] = async ({ + doesCurrentHrefRequiresAuth, + extraQueryParams + }) => { //NOTE: We know there is a extraQueryParameter option but it doesn't allow - // to control the encoding so we have to hack the global URL Class that is - // used internally by oidc-client-ts + // to control the encoding so we have to highjack global URL Class that is + // used internally by oidc-client-ts. It's save to do so since this is the + // last thing that will be done before the redirect. const URL_real = window.URL; @@ -88,7 +102,23 @@ export async function createOidc(params: { return new Proxy(urlInstance, { "get": (target, prop) => { if (prop === "href") { - return transformUrlBeforeRedirect(urlInstance.href); + let url = urlInstance.href; + + Object.entries({ + ...getExtraQueryParams?.(), + ...extraQueryParams + }).forEach( + ([name, value]) => + (url = addQueryParamToUrl({ + url, + name, + value + }).newUrl) + ); + + url = transformUrlBeforeRedirect(url); + + return url; } //@ts-expect-error