Skip to content

Commit

Permalink
refactor: reduce code complexity by using loginHint from oidc interac…
Browse files Browse the repository at this point in the history
…tion only to trigger a login submission once
  • Loading branch information
rdubigny committed Sep 20, 2024
1 parent 5a1caa3 commit 73005cb
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 23 deletions.
32 changes: 11 additions & 21 deletions src/controllers/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import {
isWithinAuthenticatedSession,
isWithinTwoFactorAuthenticatedSession,
} from "../managers/session/authenticated";
import { setEmailInUnauthenticatedSession } from "../managers/session/unauthenticated";
import { setLoginHintInUnauthenticatedSession } from "../managers/session/unauthenticated";
import epochTime from "../services/epoch-time";
import { mustReturnOneOrganizationInPayload } from "../services/must-return-one-organization-in-payload";
import { shouldTrigger2fa } from "../services/should-trigger-2fa";
import { postStartSignInController } from "./user/signin-signup";

export const interactionStartControllerFactory =
(oidcProvider: any) =>
Expand All @@ -30,30 +29,21 @@ export const interactionStartControllerFactory =
req.session.mustUse2FA = true;
}

if (prompt.name === "login" && prompt.reasons.includes("login_prompt")) {
if (login_hint) {
setEmailInUnauthenticatedSession(req, login_hint);
req.body.login = login_hint;
return postStartSignInController(req, res, next);
}
if (login_hint) {
setLoginHintInUnauthenticatedSession(req, login_hint);
}

if (prompt.name === "login" && prompt.reasons.includes("login_prompt")) {
return res.redirect(`/users/start-sign-in`);
}

if (prompt.name === "login" || prompt.name === "choose_organization") {
if (login_hint) {
const isAuthenticated = isWithinAuthenticatedSession(req.session);
const authenticatedUserEmail = isAuthenticated
? getUserFromAuthenticatedSession(req).email
: null;
const isDifferentEmail = authenticatedUserEmail !== login_hint;

if (!isAuthenticated || (isAuthenticated && isDifferentEmail)) {
setEmailInUnauthenticatedSession(req, login_hint);
req.body.login = login_hint;

return postStartSignInController(req, res, next);
}
if (
login_hint &&
isWithinAuthenticatedSession(req.session) &&
getUserFromAuthenticatedSession(req).email !== login_hint
) {
return res.redirect(`/users/start-sign-in`);
}

return res.redirect(`/interaction/${interactionId}/login`);
Expand Down
14 changes: 12 additions & 2 deletions src/controllers/user/signin-signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "../../config/errors";
import { createAuthenticatedSession } from "../../managers/session/authenticated";
import {
getAndRemoveLoginHintFromUnauthenticatedSession,
getEmailFromUnauthenticatedSession,
setEmailInUnauthenticatedSession,
setPartialUserFromUnauthenticatedSession,
Expand All @@ -33,13 +34,22 @@ export const getStartSignInController = async (
next: NextFunction,
) => {
try {
// Bypass email submission when a login hint is provided in the interaction
const hintFromOidcInteraction =
getAndRemoveLoginHintFromUnauthenticatedSession(req);
if (hintFromOidcInteraction) {
setEmailInUnauthenticatedSession(req, hintFromOidcInteraction);
req.body.login = hintFromOidcInteraction;
return postStartSignInController(req, res, next);
}

const schema = z.object({
did_you_mean: z.string().trim().min(1).optional(),
});

const { did_you_mean: didYouMean } = await schema.parseAsync(req.query);

const loginHint = getEmailFromUnauthenticatedSession(req);
const hintFromSession = getEmailFromUnauthenticatedSession(req);

const hasEmailError =
(await getNotificationLabelFromRequest(req)) === "invalid_email";
Expand All @@ -49,7 +59,7 @@ export const getStartSignInController = async (
notifications: !hasEmailError && (await getNotificationsFromRequest(req)),
hasEmailError,
didYouMean,
loginHint,
loginHint: hintFromSession,
csrfToken: csrfToken(req),
displayTestEnvWarning: DISPLAY_TEST_ENV_WARNING,
});
Expand Down
15 changes: 15 additions & 0 deletions src/managers/session/unauthenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ import { isEmpty } from "lodash-es";
import { NoEmailFoundInUnauthenticatedSessionError } from "../../config/errors";
import { findByEmail, update } from "../../repositories/user";

export const getAndRemoveLoginHintFromUnauthenticatedSession = (
req: Request,
) => {
const loginHint = req.session.loginHint;
delete req.session.loginHint;
return loginHint;
};
export const setLoginHintInUnauthenticatedSession = (
req: Request,
loginHint: string,
) => {
req.session.loginHint = loginHint;

return loginHint;
};
export const getEmailFromUnauthenticatedSession = (req: Request) => {
return req.session.email;
};
Expand Down
1 change: 1 addition & 0 deletions src/types/express-session.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface UnauthenticatedSessionData {
email?: string;
loginHint?: string;
needsInclusionconnectWelcomePage?: boolean;
interactionId?: string;
mustReturnOneOrganizationInPayload?: boolean;
Expand Down

0 comments on commit 73005cb

Please sign in to comment.