diff --git a/src/client/pages/IframedSignIn.tsx b/src/client/pages/IframedSignIn.tsx index 44d9ac63c..50d7a1bc8 100644 --- a/src/client/pages/IframedSignIn.tsx +++ b/src/client/pages/IframedSignIn.tsx @@ -23,6 +23,7 @@ import { MinimalLayout } from '@/client/layouts/MinimalLayout'; import ThemedLink from '@/client/components/ThemedLink'; import IframeThemedEmailInput from '../components/IframeThemedEmailInput'; import { disableAutofillBackground } from '../styles/Shared'; +import NameInputField from '../components/NameInputField'; export type IframedSignInProps = { queryParams: QueryParams; @@ -38,6 +39,7 @@ export type IframedSignInProps = { usePasscodeSignIn?: boolean; hideSocialButtons?: boolean; focusPasswordField?: boolean; + showNameForm?: boolean; }; const socialButtonDivider = css` @@ -138,6 +140,7 @@ export const IframedSignIn = ({ isReauthenticate = false, shortRequestId, hideSocialButtons = false, + showNameForm, }: IframedSignInProps) => { const formTrackingName = 'sign-in'; @@ -202,6 +205,8 @@ export const IframedSignIn = ({ )} + {showNameForm && } + diff --git a/src/client/pages/IframedSignInPage.tsx b/src/client/pages/IframedSignInPage.tsx index 63559710c..9bc175d51 100644 --- a/src/client/pages/IframedSignInPage.tsx +++ b/src/client/pages/IframedSignInPage.tsx @@ -6,6 +6,7 @@ import { IframedSignIn } from './IframedSignIn'; interface Props { isReauthenticate?: boolean; hideSocialButtons?: boolean; + showNameForm?: boolean; } export const IframedSignInPage = ({ @@ -19,7 +20,7 @@ export const IframedSignInPage = ({ queryParams, recaptchaConfig, } = clientState; - const { email, formError } = pageData; + const { email, showNameForm, formError } = pageData; const { error: pageError } = globalMessage; const { recaptchaSiteKey } = recaptchaConfig; @@ -48,6 +49,7 @@ export const IframedSignInPage = ({ isReauthenticate={isReauthenticate} shortRequestId={clientState.shortRequestId} hideSocialButtons={hideSocialButtons} + showNameForm={showNameForm} /> ); }; diff --git a/src/server/controllers/signInControllers.ts b/src/server/controllers/signInControllers.ts index dcb9b2026..c6c476df5 100644 --- a/src/server/controllers/signInControllers.ts +++ b/src/server/controllers/signInControllers.ts @@ -201,7 +201,7 @@ export const oktaIdxApiSignInPasscodeController = async ({ loopDetectionFlag?: boolean; confirmationPagePath?: StartIdxFlowParams['authorizationCodeFlowOptions']['confirmationPagePath']; }): Promise => { - const { email = '' } = req.body; + const { email = '', firstName, secondName } = req.body; const referrerUrl = new URL(req.body.ref); const referrerPath = referrerUrl.pathname; const emailSentPage = referrerPath.includes('/iframed') @@ -249,6 +249,8 @@ export const oktaIdxApiSignInPasscodeController = async ({ extraData: { flow: 'sign-in-passcode', appLabel: res.locals.appLabel, + firstName, + lastName: secondName, }, }, }); diff --git a/src/server/lib/okta/idx/interact.ts b/src/server/lib/okta/idx/interact.ts index da9a48b7e..b3c1c4dac 100644 --- a/src/server/lib/okta/idx/interact.ts +++ b/src/server/lib/okta/idx/interact.ts @@ -95,6 +95,8 @@ export const interact = async ( codeVerifier, flow: extraData?.flow, appLabel: extraData?.appLabel, + firstName: extraData?.firstName, + lastName: extraData?.lastName, }, ); setAuthorizationStateCookie(authState, res); diff --git a/src/server/lib/okta/openid-connect.ts b/src/server/lib/okta/openid-connect.ts index 78a152104..27d4c7d5d 100644 --- a/src/server/lib/okta/openid-connect.ts +++ b/src/server/lib/okta/openid-connect.ts @@ -50,6 +50,8 @@ export interface AuthorizationState { // used to track the flow the user is in for basic metrics/analytics flow?: UserFlow; // password reset, and email verification flows outside of create account appLabel?: string; // used to track the app used to start the flow + firstName?: string; // used to persist the first name during the signin flow, so that we can set it after login + lastName?: string; // used to persist the last name during the signin flow, so that we can set it after login }; } diff --git a/src/server/routes/oauth.ts b/src/server/routes/oauth.ts index dbfda9d95..92afb3f43 100644 --- a/src/server/routes/oauth.ts +++ b/src/server/routes/oauth.ts @@ -426,6 +426,16 @@ const authenticationHandler = async ( } } + // Update the users first and last name if they exist in the authState + if (authState.data?.firstName || authState.data?.lastName) { + await updateUser(sub, { + profile: { + firstName: authState.data.firstName, + lastName: authState.data.lastName, + }, + }); + } + // clear any existing oauth application cookies if they exist checkAndDeleteOAuthTokenCookies(req, res); diff --git a/src/server/routes/register.ts b/src/server/routes/register.ts index 6b8e42a2a..1e9e31e3a 100644 --- a/src/server/routes/register.ts +++ b/src/server/routes/register.ts @@ -368,7 +368,12 @@ const oktaIdxCreateAccountOrSignIn = async ( req: Request, res: ResponseWithRequestState, ) => { - const { email = '', isCombinedSigninAndRegisterFlow = false } = req.body; + const { + email = '', + firstName, + secondName, + isCombinedSigninAndRegisterFlow = false, + } = req.body; const { queryParams: { appClientId, clientId }, @@ -406,6 +411,8 @@ const oktaIdxCreateAccountOrSignIn = async ( extraData: { flow: 'create-account', appLabel: res.locals.appLabel, + firstName, + lastName: secondName, }, }, consents, diff --git a/src/server/routes/signIn.ts b/src/server/routes/signIn.ts index 9f7c831c9..5b8ed1aa6 100644 --- a/src/server/routes/signIn.ts +++ b/src/server/routes/signIn.ts @@ -118,6 +118,7 @@ const handleSigninRender = async ( pageData: { email: overrideEmailAddress || email, focusPasswordField: !!email, + showNameForm: true, }, globalMessage: { error: getErrorMessageFromQueryParams(error, error_description), @@ -148,6 +149,8 @@ router.get( const prepopulatedEmail = prepopulatedEmailParamEncoded ? decodeURIComponent(prepopulatedEmailParamEncoded) : null; + const showNameFormParamEncoded = + params.has('showNameForm') && params.get('showNameForm') !== 'false'; const html = await handleSigninRender(req, res, prepopulatedEmail); return res.type('html').send(html); diff --git a/src/shared/model/ClientState.ts b/src/shared/model/ClientState.ts index 35f70c85a..c4f8fb387 100644 --- a/src/shared/model/ClientState.ts +++ b/src/shared/model/ClientState.ts @@ -87,6 +87,9 @@ export interface PageData { // sign in with password specific focusPasswordField?: boolean; + + // iframe specific + showNameForm?: boolean; } export interface RecaptchaConfig {