Skip to content

Commit

Permalink
#2
Browse files Browse the repository at this point in the history
  • Loading branch information
garronej committed Oct 24, 2023
1 parent a9ac476 commit 27d0556
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,17 @@ import { createOidc, decodeJwt } from "oidc-spa";
clientId: "myclient",
// Optional, you can modify the url before redirection to the identity server
transformUrlBeforeRedirect: url => `${url}&ui_locales=fr`
/** Optional: Provide only if your app is not hosted at the origin */
//silentSsoUrl: `${window.location.origin}/foo/bar/baz/silent-sso.html`,
/*
* This is to 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`
* you don't have to provide this parameter.
* On the other end if your site is hosted by navigating to `https://www.example.com/my-app`
* Then you want to set website root to `${${window.location.origin}/my-app`
*
* Be mindful that `${websiteRootUrl}/silent-sso.html` must return the `silent-sso.html` that
* you are supposed to have created in your `public/` directory.
*/
//websiteRootUrl: `${window.location.origin}/my-app`
});

if (oidc.isUserLoggedIn) {
Expand Down Expand Up @@ -98,7 +107,8 @@ import { createOidc, decodeJwt } from "oidc-spa";
console.log(`Hello ${user.preferred_username}`);

// To call when the user click on logout.
oidc.logout();
// You can also redirect to a custom url with { redirectTo: "specific url", url: `${location.origin}/bye` }
oidc.logout({ redirectTo: "home" });
}
})();
```
Expand Down Expand Up @@ -139,7 +149,12 @@ function App() {
);
}

return <AppLoggedIn logout={oidc.logout} />;
return (
<AppLoggedIn
// You can also redirect to a custom url with { redirectTo: "specific url", url: `${location.origin}/bye` }
logout={() => oidc.logout({ redirectTo: "home" })}
/>
);
}

function AppLoggedIn(props: { logout: () => Promise<never> }) {
Expand Down
40 changes: 26 additions & 14 deletions src/oidc.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { UserManager, type User } from "oidc-client-ts";
import { id } from "tsafe/id";
import { readExpirationTimeInJwt } from "./tools/readExpirationTimeInJwt";
import { assert } from "tsafe/assert";
import { assert, type Equals } from "tsafe/assert";
import { addQueryParamToUrl, retrieveQueryParamFromUrl } from "./tools/urlQueryParams";
import { fnv1aHashToHex } from "./tools/fnv1aHashToHex";
import { Deferred } from "./tools/Deferred";
Expand All @@ -25,7 +25,9 @@ export declare namespace Oidc {
isUserLoggedIn: true;
renewTokens(): Promise<void>;
getTokens: () => Tokens;
logout: (params: { redirectTo: "home" | "current page" }) => Promise<never>;
logout: (
params: { redirectTo: "home" | "current page" } | { redirectTo: "specific url"; url: string }
) => Promise<never>;
};

export type Tokens = {
Expand All @@ -43,15 +45,22 @@ export async function createOidc(params: {
issuerUri: string;
clientId: string;
transformUrlBeforeRedirect?: (url: string) => string;
/** Default `${window.location.origin}/silent-sso.html` */
silentSsoUrl?: string;
/**
* This is to 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`
* you don't have to provide this parameter.
* On the other end if your site is hosted by navigating to `https://www.example.com/my-app`
* Then you want to set publicUrl to `/my-app`
*
* Be mindful that `${window.location.origin}${publicUrl}/silent-sso.html` must return the `silent-sso.html` that
* you are supposed to have created in your `public/` directory.
*
* If your are still using `create-react-app` you can just set
* publicUrl to `process.env.PUBLIC_URL` and don't have to think about it further.
*/
publicUrl?: string;
}): Promise<Oidc> {
const {
issuerUri,
clientId,
silentSsoUrl = `${window.location.origin}/silent-sso.html`,
transformUrlBeforeRedirect = url => url
} = params;
const { issuerUri, clientId, transformUrlBeforeRedirect = url => url, publicUrl = "" } = params;

const configHash = fnv1aHashToHex(`${issuerUri} ${clientId}`);
const configHashKey = "configHash";
Expand All @@ -63,7 +72,7 @@ export async function createOidc(params: {
"response_type": "code",
"scope": "openid profile",
"automaticSilentRenew": false,
"silent_redirect_uri": `${silentSsoUrl}?${configHashKey}=${configHash}`
"silent_redirect_uri": `${window.location.origin}${publicUrl}/silent-sso.html?${configHashKey}=${configHash}`
});

const login: Oidc.NotLoggedIn["login"] = async ({ doesCurrentHrefRequiresAuth }) => {
Expand Down Expand Up @@ -298,15 +307,18 @@ export async function createOidc(params: {
"refreshTokenExpirationTime": currentTokens.refreshTokenExpirationTime,
"accessTokenExpirationTime": currentTokens.accessTokenExpirationTime
}),
"logout": async ({ redirectTo }) => {
"logout": async params => {
await userManager.signoutRedirect({
"post_logout_redirect_uri": (() => {
switch (redirectTo) {
switch (params.redirectTo) {
case "current page":
return window.location.href;
case "home":
return window.location.origin;
return `${window.location.origin}${publicUrl}`;
case "specific url":
return params.url;
}
assert<Equals<typeof params, never>>(false);
})()
});
return new Promise<never>(() => {});
Expand Down

0 comments on commit 27d0556

Please sign in to comment.