From bae2a3ff70b2d594a26042590b1c6cf41be63575 Mon Sep 17 00:00:00 2001 From: dbes-gds Date: Mon, 16 Sep 2024 17:57:37 +0100 Subject: [PATCH] DFC-663: Read 'channel' claim if support multi-channel is switched-on Add a configurable default channel, which defaults to 'web'. To support rendering the UI differently per channel. --- ci/terraform/ecs.tf | 8 +++ ci/terraform/variables.tf | 12 ++++ cloudformation/deploy/template.yaml | 4 ++ scripts/_create_env_file.py | 1 + src/app.constants.ts | 5 ++ .../authorize/authorize-controller.ts | 8 +++ src/components/authorize/claims-config.ts | 1 + .../tests/authorize-controller.test.ts | 71 +++++++++++++++++++ src/config.ts | 19 +++++ src/types.ts | 1 + 10 files changed, 130 insertions(+) diff --git a/ci/terraform/ecs.tf b/ci/terraform/ecs.tf index f34596623..1384667a0 100644 --- a/ci/terraform/ecs.tf +++ b/ci/terraform/ecs.tf @@ -164,6 +164,14 @@ locals { name = "SUPPORT_CHECK_EMAIL_FRAUD" value = var.support_check_email_fraud }, + { + name = "SUPPORT_MULTI_CHANNEL" + value = var.support_multi_channel + }, + { + name = "DEFAULT_CHANNEL" + value = var.default_channel + }, { name = "LANGUAGE_TOGGLE_ENABLED" value = var.language_toggle_enabled diff --git a/ci/terraform/variables.tf b/ci/terraform/variables.tf index 848566ba9..1566422c8 100644 --- a/ci/terraform/variables.tf +++ b/ci/terraform/variables.tf @@ -272,6 +272,18 @@ variable "support_check_email_fraud" { default = "1" } +variable "support_multi_channel" { + description = "Enables different UI rendering per channel" + type = string + default = "0" +} + +variable "default_channel" { + description = "To set the default channel." + type = string + default = "web" +} + variable "prove_identity_welcome_enabled" { description = "Do not show the prove identity welcome screen when disabled" type = string diff --git a/cloudformation/deploy/template.yaml b/cloudformation/deploy/template.yaml index fed80c398..bd5b0ec6e 100644 --- a/cloudformation/deploy/template.yaml +++ b/cloudformation/deploy/template.yaml @@ -568,6 +568,10 @@ Resources: Value: 1 - Name: SUPPORT_CHECK_EMAIL_FRAUD Value: 1 + - Name: SUPPORT_MULTI_CHANNEL + Value: 0 + - Name: DEFAULT_CHANNEL + Value: web - Name: LANGUAGE_TOGGLE_ENABLED Value: 1 - Name: PROVE_IDENTITY_WELCOME_ENABLED diff --git a/scripts/_create_env_file.py b/scripts/_create_env_file.py index c25670f3a..3a86ea02c 100755 --- a/scripts/_create_env_file.py +++ b/scripts/_create_env_file.py @@ -92,6 +92,7 @@ class EnvFileSection(TypedDict): "SUPPORT_REAUTHENTICATION": 1, "SUPPORT_2HR_LOCKOUT": 1, "SUPPORT_CHECK_EMAIL_FRAUD": 1, + "SUPPORT_MULTI_CHANNEL": 0, "NO_PHOTO_ID_CONTACT_FORMS": 1, "LANGUAGE_TOGGLE_ENABLED": 1, "SUPPORT_NEW_IPV_SPINNER": 1, diff --git a/src/app.constants.ts b/src/app.constants.ts index 86d9efe9b..19bd7f3da 100644 --- a/src/app.constants.ts +++ b/src/app.constants.ts @@ -231,6 +231,11 @@ export enum JOURNEY_TYPE { REAUTHENTICATION = "REAUTHENTICATION", } +export enum CHANNEL { + WEB = "web", + STRATEGIC_APP = "strategic_app", +} + export const ENVIRONMENT_NAME = { PROD: "production", DEV: "development", diff --git a/src/components/authorize/authorize-controller.ts b/src/components/authorize/authorize-controller.ts index 90f613b58..7da2a5e6c 100644 --- a/src/components/authorize/authorize-controller.ts +++ b/src/components/authorize/authorize-controller.ts @@ -26,6 +26,9 @@ import { getOrchToAuthExpectedClientId, supportReauthentication, proveIdentityWelcomeEnabled, + supportMultiChannel, + isValidChannel, + getDefaultChannel, } from "../../config"; import { logger } from "../../utils/logger"; import { Claims } from "./claims-config"; @@ -186,6 +189,11 @@ function setSessionDataFromClaims(req: Request, claims: Claims) { req.session.user.reauthenticate = supportReauthentication() ? claims.reauthenticate : null; + req.session.user.channel = + supportMultiChannel() && isValidChannel(claims.channel) + ? claims.channel + : getDefaultChannel(); + logger.info(`Channel is set to: ${req.session.user.channel}`); } function setSessionDataFromAuthResponse( diff --git a/src/components/authorize/claims-config.ts b/src/components/authorize/claims-config.ts index dcefd567f..87b08ac52 100644 --- a/src/components/authorize/claims-config.ts +++ b/src/components/authorize/claims-config.ts @@ -35,6 +35,7 @@ export type Claims = { claim?: string; previous_session_id?: string; previous_govuk_signin_journey_id: string; + channel?: string; }; export const requiredClaimsKeys = [ diff --git a/src/components/authorize/tests/authorize-controller.test.ts b/src/components/authorize/tests/authorize-controller.test.ts index 07db22533..357d51a81 100644 --- a/src/components/authorize/tests/authorize-controller.test.ts +++ b/src/components/authorize/tests/authorize-controller.test.ts @@ -558,6 +558,77 @@ describe("authorize controller", () => { .to.eventually.be.rejectedWith("Client ID value is incorrect") .and.be.an.instanceOf(BadRequestError); }); + + it("should set session channel session field from jwt claims when claim is present", async () => { + process.env.SUPPORT_MULTI_CHANNEL = "1"; + req.query.request = "JWE"; + mockClaims.channel = "strategic_app"; + + await authorizeGet( + fakeAuthorizeService, + fakeCookieConsentService, + fakeKmsDecryptionService, + fakeJwtService + )(req as Request, res as Response); + expect(req.session.user.channel).to.equal(mockClaims.channel); + }); + + it("should set session channel session field to default when claim is not present", async () => { + process.env.SUPPORT_MULTI_CHANNEL = "1"; + req.query.request = "JWE"; + mockClaims.channel = undefined; + + await authorizeGet( + fakeAuthorizeService, + fakeCookieConsentService, + fakeKmsDecryptionService, + fakeJwtService + )(req as Request, res as Response); + expect(req.session.user.channel).to.eq("web"); + }); + + it("should set session channel session field to default when switch is off", async () => { + process.env.SUPPORT_MULTI_CHANNEL = "0"; + req.query.request = "JWE"; + mockClaims.channel = "strategic_app"; + + await authorizeGet( + fakeAuthorizeService, + fakeCookieConsentService, + fakeKmsDecryptionService, + fakeJwtService + )(req as Request, res as Response); + expect(req.session.user.channel).to.eq("web"); + }); + + it("should set session channel session field to the configured default when switch is off", async () => { + process.env.SUPPORT_MULTI_CHANNEL = "0"; + process.env.DEFAULT_CHANNEL = "strategic_app"; + req.query.request = "JWE"; + mockClaims.channel = "web"; + + await authorizeGet( + fakeAuthorizeService, + fakeCookieConsentService, + fakeKmsDecryptionService, + fakeJwtService + )(req as Request, res as Response); + expect(req.session.user.channel).to.eq("strategic_app"); + }); + }); + + it("should set session channel session field to default when claim is invalid channel", async () => { + process.env.SUPPORT_MULTI_CHANNEL = "1"; + req.query.request = "JWE"; + mockClaims.channel = "invalid_channel"; + + await authorizeGet( + fakeAuthorizeService, + fakeCookieConsentService, + fakeKmsDecryptionService, + fakeJwtService + )(req as Request, res as Response); + expect(req.session.user.channel).to.eq("web"); }); function mockAuthService(authResponseData: any): AuthorizeServiceInterface { diff --git a/src/config.ts b/src/config.ts index a4d95ca39..5bdca559d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,5 @@ +import { CHANNEL } from "./app.constants"; + export function getLogLevel(): string { return process.env.LOGS_LEVEL || "debug"; } @@ -146,6 +148,19 @@ export function supportCheckEmailFraud(): boolean { return process.env.SUPPORT_CHECK_EMAIL_FRAUD === "1"; } +export function supportMultiChannel(): boolean { + return process.env.SUPPORT_MULTI_CHANNEL === "1"; +} + +export function getDefaultChannel(): string { + const configuredChannel = process.env.DEFAULT_CHANNEL; + if (isValidChannel(configuredChannel)) { + return configuredChannel; + } else { + return CHANNEL.WEB; + } +} + export function getLanguageToggleEnabled(): boolean { return process.env.LANGUAGE_TOGGLE_ENABLED === "1"; } @@ -179,3 +194,7 @@ export function supportNewIpvSpinner(): boolean { export function supportHttpKeepAlive(): boolean { return process.env.SUPPORT_HTTP_KEEP_ALIVE === "1"; } + +export function isValidChannel(channel: string): boolean { + return channel === CHANNEL.WEB || channel === CHANNEL.STRATEGIC_APP; +} diff --git a/src/types.ts b/src/types.ts index 07307c726..3f9ae04e4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -84,6 +84,7 @@ export interface UserSession { isPasswordResetJourney?: boolean; isSignInJourney?: boolean; isVerifyEmailCodeResendRequired?: boolean; + channel?: string; } export interface UserSessionClient {