Skip to content

Commit

Permalink
#3
Browse files Browse the repository at this point in the history
  • Loading branch information
garronej committed Oct 24, 2023
1 parent 06838da commit e0a009c
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 16 deletions.
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -145,8 +150,16 @@ function App() {
return (
<>
You're not logged in.
<button onClick={() => oidc.login({ doesCurrentHrefRequiresAuth: false })}>
Login now
<button
onClick={() =>
oidc.login({
doesCurrentHrefRequiresAuth: false
//Optionally you can add some extra parameter to be added on the login url.
//extraQueryParams: { kc_idp_hint: "google" }
})
}
>
Login
</button>
</>
);
Expand Down
42 changes: 36 additions & 6 deletions src/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export declare namespace Oidc {

export type NotLoggedIn = Common & {
isUserLoggedIn: false;
login: (params: { doesCurrentHrefRequiresAuth: boolean }) => Promise<never>;
login: (params: {
doesCurrentHrefRequiresAuth: boolean;
extraQueryParams?: Record<string, string>;
}) => Promise<never>;
};

export type LoggedIn = Common & {
Expand All @@ -45,6 +48,7 @@ export async function createOidc(params: {
issuerUri: string;
clientId: string;
transformUrlBeforeRedirect?: (url: string) => string;
getExtraQueryParams?: () => Record<string, string>;
/**
* 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`
Expand All @@ -60,7 +64,13 @@ export async function createOidc(params: {
*/
publicUrl?: string;
}): Promise<Oidc> {
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";
Expand All @@ -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;

Expand All @@ -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
Expand Down

0 comments on commit e0a009c

Please sign in to comment.