-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #936 from InseeFrLab/oidc_next
OIDC next
- Loading branch information
Showing
43 changed files
with
414 additions
and
380 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,99 @@ | ||
import type { Oidc } from "core/ports/Oidc"; | ||
import { createOidc as createOidcSpa } from "oidc-spa"; | ||
import { assert } from "tsafe/assert"; | ||
import { parseKeycloakIssuerUri } from "oidc-spa/tools/parseKeycloakIssuerUri"; | ||
import type { OidcParams, OidcParams_Partial } from "core/ports/OnyxiaApi"; | ||
import { objectKeys } from "tsafe/objectKeys"; | ||
|
||
export async function createOidc(params: { | ||
issuerUri: string; | ||
clientId: string; | ||
transformUrlBeforeRedirect: (url: string) => string; | ||
}): Promise<Oidc> { | ||
const { issuerUri, clientId, transformUrlBeforeRedirect } = params; | ||
export async function createOidc<AutoLogin extends boolean>( | ||
params: OidcParams & { | ||
transformUrlBeforeRedirect_ui: (params: { | ||
isKeycloak: boolean; | ||
authorizationUrl: string; | ||
}) => string; | ||
autoLogin: AutoLogin; | ||
} | ||
): Promise<AutoLogin extends true ? Oidc.LoggedIn : Oidc> { | ||
const { | ||
issuerUri, | ||
clientId, | ||
scope_spaceSeparated, | ||
audience, | ||
transformUrlBeforeRedirect_ui, | ||
extraQueryParams_raw, | ||
idleSessionLifetimeInSeconds, | ||
autoLogin | ||
} = params; | ||
|
||
const oidc = await createOidcSpa({ | ||
issuerUri, | ||
clientId, | ||
transformUrlBeforeRedirect, | ||
homeUrl: import.meta.env.BASE_URL, | ||
debugLogs: false | ||
}); | ||
scopes: scope_spaceSeparated?.split(" "), | ||
transformUrlBeforeRedirect_next: ({ authorizationUrl, isSilent }) => { | ||
if (!isSilent) { | ||
authorizationUrl = transformUrlBeforeRedirect_ui({ | ||
isKeycloak: | ||
parseKeycloakIssuerUri(oidc.params.issuerUri) !== undefined, | ||
authorizationUrl | ||
}); | ||
} | ||
|
||
if (!oidc.isUserLoggedIn) { | ||
return oidc; | ||
} | ||
if (audience !== undefined) { | ||
const url_obj = new URL(authorizationUrl); | ||
|
||
function getTokens_patched() { | ||
assert(oidc.isUserLoggedIn); | ||
url_obj.searchParams.set("audience", audience); | ||
|
||
const tokens_real = oidc.getTokens(); | ||
authorizationUrl = url_obj.href; | ||
} | ||
|
||
if (!oidc_patched.isAccessTokenSubstitutedWithIdToken) { | ||
return tokens_real; | ||
} | ||
if (extraQueryParams_raw !== undefined) { | ||
const url_obj = new URL(authorizationUrl); | ||
const extraUrlSearchParams = new URLSearchParams(extraQueryParams_raw); | ||
|
||
for (const [key, value] of extraUrlSearchParams) { | ||
url_obj.searchParams.set(key, value); | ||
} | ||
|
||
const tokens: ReturnType<Oidc.LoggedIn["getTokens"]> = { | ||
...tokens_real, | ||
accessToken: tokens_real.idToken | ||
}; | ||
authorizationUrl = url_obj.href; | ||
} | ||
|
||
return authorizationUrl; | ||
}, | ||
idleSessionLifetimeInSeconds, | ||
homeUrl: import.meta.env.BASE_URL | ||
}); | ||
|
||
return tokens; | ||
if (!oidc.isUserLoggedIn) { | ||
if (autoLogin) { | ||
await oidc.login({ doesCurrentHrefRequiresAuth: true }); | ||
// NOTE: Never | ||
} | ||
|
||
//@ts-expect-error: We know what we are doing | ||
return oidc; | ||
} | ||
|
||
const oidc_patched: Oidc.LoggedIn = { | ||
return { | ||
...oidc, | ||
getTokens: getTokens_patched, | ||
isAccessTokenSubstitutedWithIdToken: false | ||
getTokens: () => oidc.getTokens_next() | ||
}; | ||
} | ||
|
||
export function mergeOidcParams(params: { | ||
oidcParams: OidcParams; | ||
oidcParams_partial: OidcParams_Partial; | ||
}) { | ||
const { oidcParams, oidcParams_partial } = params; | ||
|
||
const oidcParams_merged = { ...oidcParams }; | ||
|
||
for (const key of objectKeys(oidcParams_partial)) { | ||
const value = oidcParams_partial[key]; | ||
if (value === undefined) { | ||
continue; | ||
} | ||
// @ts-expect-error | ||
oidcParams_merged[key] = value; | ||
} | ||
|
||
return oidc_patched; | ||
return oidcParams_merged; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.