From 6aab01e56c9408216511bbcd68bf416fef768406 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 6 Mar 2023 10:08:57 +0800 Subject: [PATCH] feat(ui): add interactionMode OIDC param (#3280) --- .changeset-staged/gorgeous-berries-smoke.md | 8 ++++++++ packages/core/src/oidc/init.ts | 11 ++++++++++- packages/core/src/oidc/type.ts | 8 ++++++++ packages/core/src/routes/consts.ts | 2 ++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset-staged/gorgeous-berries-smoke.md create mode 100644 packages/core/src/oidc/type.ts diff --git a/.changeset-staged/gorgeous-berries-smoke.md b/.changeset-staged/gorgeous-berries-smoke.md new file mode 100644 index 000000000..98ab1cad3 --- /dev/null +++ b/.changeset-staged/gorgeous-berries-smoke.md @@ -0,0 +1,8 @@ +--- +"@logto/core": patch +--- + +Add interactionMode extra OIDC params to specify the desired use interaction experience + +- signUp: Deliver a sign-up first interaction experience +- signIn & undefined: Deliver a default sign-in first interaction experience diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts index 37bfdbeb0..9de5e3612 100644 --- a/packages/core/src/oidc/init.ts +++ b/packages/core/src/oidc/init.ts @@ -20,6 +20,7 @@ import type Libraries from '#src/tenants/Libraries.js'; import type Queries from '#src/tenants/Queries.js'; import { getUserClaimData, getUserClaims } from './scope.js'; +import { OIDCExtraParametersKey, InteractionMode } from './type.js'; // Temporarily removed 'EdDSA' since it's not supported by browser yet const supportedSigningAlgs = Object.freeze(['RS256', 'PS256', 'ES256', 'ES384', 'ES512'] as const); @@ -139,7 +140,7 @@ export default function initOidc(envSet: EnvSet, queries: Queries, libraries: Li }, }, interactions: { - url: (_, interaction) => { + url: (ctx, interaction) => { const appendParameters = (path: string) => { // `notification` is for showing a text banner on the homepage return interaction.params.client_id === demoAppApplicationId @@ -149,6 +150,13 @@ export default function initOidc(envSet: EnvSet, queries: Queries, libraries: Li switch (interaction.prompt.name) { case 'login': { + if ( + // Register user experience first + ctx.oidc.params?.[OIDCExtraParametersKey.InteractionMode] === InteractionMode.signUp + ) { + return appendParameters(routes.signUp); + } + return appendParameters(routes.signIn.credentials); } @@ -162,6 +170,7 @@ export default function initOidc(envSet: EnvSet, queries: Queries, libraries: Li } }, }, + extraParams: [OIDCExtraParametersKey.InteractionMode], extraClientMetadata: { properties: Object.values(CustomClientMetadataKey), validator: (_, key, value) => { diff --git a/packages/core/src/oidc/type.ts b/packages/core/src/oidc/type.ts new file mode 100644 index 000000000..a8db5a1f2 --- /dev/null +++ b/packages/core/src/oidc/type.ts @@ -0,0 +1,8 @@ +export enum OIDCExtraParametersKey { + InteractionMode = 'interaction_mode', +} + +export enum InteractionMode { + signIn = 'signIn', + signUp = 'signUp', +} diff --git a/packages/core/src/routes/consts.ts b/packages/core/src/routes/consts.ts index 9d91d1c3b..b8de39015 100644 --- a/packages/core/src/routes/consts.ts +++ b/packages/core/src/routes/consts.ts @@ -1,10 +1,12 @@ const signIn = '/sign-in'; +const signUp = '/register'; export const routes = Object.freeze({ signIn: { credentials: signIn, consent: `${signIn}/consent`, }, + signUp, } as const); export const verificationTimeout = 10 * 60; // 10 mins.