From 7155165360ebf179c1d982de4acc3596734decbe Mon Sep 17 00:00:00 2001 From: Anton Gunnarsson Date: Thu, 20 Feb 2025 08:55:10 +0000 Subject: [PATCH] Merged in feat/SW-1266-implement-sas-link-account-endpoint (pull request #1332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement API call to link SAS account * Add endpoint to actually link SAS account linking * add logging of error * Refactor tocDate to getCurrentDateWithoutTime Approved-by: Joakim Jäderberg --- app/[lang]/(live)/(public)/login/route.ts | 2 +- .../(protected)/sas-x-scandic/otp/page.tsx | 18 +++++- lib/api/endpoints.ts | 1 + server/routers/partners/sas/linkAccount.ts | 56 ++++++++++++++++--- 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/app/[lang]/(live)/(public)/login/route.ts b/app/[lang]/(live)/(public)/login/route.ts index d1f263cbf..bca37a262 100644 --- a/app/[lang]/(live)/(public)/login/route.ts +++ b/app/[lang]/(live)/(public)/login/route.ts @@ -117,7 +117,7 @@ export async function GET( /** Record is next-auth typings */ const params: Record = { ui_locales: context.params.lang, - scope: ["openid", "profile", "booking"], + scope: ["openid", "profile", "booking", "profile_link"], /** * The `acr_values` param is used to make Curity display the proper login * page for Scandic. Without the parameter Curity presents some choices diff --git a/app/[lang]/(partner)/(sas)/(protected)/sas-x-scandic/otp/page.tsx b/app/[lang]/(partner)/(sas)/(protected)/sas-x-scandic/otp/page.tsx index 93c3b05f3..b107577de 100644 --- a/app/[lang]/(partner)/(sas)/(protected)/sas-x-scandic/otp/page.tsx +++ b/app/[lang]/(partner)/(sas)/(protected)/sas-x-scandic/otp/page.tsx @@ -141,16 +141,30 @@ async function handleLinkAccount({ if (!res || error) { console.error("[SAS] link account error", error) return { - url: `/${lang}/sas-x-scandic/error?errorCode=link_error`, + url: `/${lang}/sas-x-scandic/error`, } } - console.log("[SAS] link account response", res) switch (res.linkingState) { + case "alreadyLinked": + return { + url: `/${lang}/sas-x-scandic/error?errorCode=alreadyLinked`, + type: "replace", + } case "linked": return { url: `/${lang}/sas-x-scandic/link/success`, type: "replace", } + case "dateOfBirthMismatch": + return { + url: `/${lang}/sas-x-scandic/error?errorCode=dateOfBirthMismatch`, + type: "replace", + } + case "error": + return { + url: `/${lang}/sas-x-scandic/error`, + type: "replace", + } } } diff --git a/lib/api/endpoints.ts b/lib/api/endpoints.ts index a85f6ccb4..5dc971639 100644 --- a/lib/api/endpoints.ts +++ b/lib/api/endpoints.ts @@ -161,6 +161,7 @@ export namespace endpoints { export const membership = `${base.path.profile}/${version}/${base.enitity.Profile}/membership` export const profile = `${base.path.profile}/${version}/${base.enitity.Profile}` export const subscriberId = `${base.path.profile}/${version}/${base.enitity.Profile}/SubscriberId` + export const link = `${base.path.profile}/${version}/${base.enitity.Profile}/link` // TODO: Remove once new endpoints are out in production. export const reward = `${base.path.profile}/${version}/${base.enitity.Profile}/reward` diff --git a/server/routers/partners/sas/linkAccount.ts b/server/routers/partners/sas/linkAccount.ts index d878a88c5..9e75713f4 100644 --- a/server/routers/partners/sas/linkAccount.ts +++ b/server/routers/partners/sas/linkAccount.ts @@ -1,26 +1,64 @@ import { z } from "zod" +import * as api from "@/lib/api" import { protectedProcedure } from "@/server/trpc" -import { timeout } from "@/utils/timeout" - import { getSasToken } from "./getSasToken" const outputSchema = z.object({ - linkingState: z.enum(["linked"]), + linkingState: z.enum([ + "linked", + "alreadyLinked", + "dateOfBirthMismatch", + "error", + ]), }) export const linkAccount = protectedProcedure .output(outputSchema) - .mutation(async function ({ ctx, input }) { + .mutation(async function ({ ctx }) { const sasAuthToken = getSasToken() console.log("[SAS] link account") - await timeout(1000) - //TODO: Call actual API here - console.log("[SAS] link account done") - return { - linkingState: "linked", + const apiResponse = await api.post(api.endpoints.v1.Profile.link, { + headers: { + Authorization: `Bearer ${ctx.session.token.access_token}`, + }, + body: { + partner: "sas_eb", + tocDate: getCurrentDateWithoutTime(), + partnerSpecific: { + eurobonusAccessToken: sasAuthToken, + }, + }, + }) + + if (apiResponse.status === 204) { + console.log("[SAS] link account done") + return { linkingState: "linked" } } + + if (apiResponse.status === 400) { + const result = await apiResponse.json() + if (result.errors?.some((x: any) => x.detail.includes("birth date"))) { + return { linkingState: "dateOfBirthMismatch" } + } + + console.log("[SAS] link account error with response", result) + return { linkingState: "error" } + } + + if (apiResponse.status === 409) { + return { linkingState: "alreadyLinked" } + } + + console.log( + `[SAS] link account error with status code ${apiResponse.status} and response ${await apiResponse.text()}` + ) + return { linkingState: "error" } }) + +function getCurrentDateWithoutTime() { + return new Date().toISOString().slice(0, 10) +}