Merged in feature/sas-login (pull request #1256)
First steps towards the SAS partnership * otp flow now pretends to do the linking * Update LinkAccountForm header * Update redirect times * Clean up comments * Set maxAge on sas cookies * make all SAS routes protected * Merge remote-tracking branch 'refs/remotes/origin/feature/sas-login' into feature/sas-login * Require auth for sas link flow * Fix resend otp * Add error support to OneTimePasswordForm * Add Sentry to SAS error boundary * Move SAS_REQUEST_OTP_STATE_STORAGE_COOKIE_NAME * Add missing translations * Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/sas-login * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * Add TooManyCodesError component * Refactor GenericError to support new errors * Add FailedAttemptsError * remove removed component <VWOScript/> * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * remove local cookie-bot reference * Fix sas campaign logo scaling * feature toggle the SAS stuff * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * fix: use env vars for SAS endpoints Approved-by: Linus Flood
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import { cookies } from "next/headers"
|
||||
import { redirect } from "next/navigation"
|
||||
import { z } from "zod"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
import { serverClient } from "@/lib/trpc/server"
|
||||
|
||||
import { safeTry } from "@/utils/safeTry"
|
||||
|
||||
import { SAS_TOKEN_STORAGE_KEY, stateSchema } from "../sasUtils"
|
||||
|
||||
import type { NextRequest } from "next/server"
|
||||
|
||||
const searchParamsSchema = z.object({
|
||||
code: z.string(),
|
||||
state: z.string(),
|
||||
})
|
||||
const tokenResponseSchema = z.object({
|
||||
access_token: z.string(),
|
||||
expires_in: z.number(),
|
||||
token_type: z.literal("Bearer"),
|
||||
})
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { lang: string } }
|
||||
) {
|
||||
const { lang } = params
|
||||
|
||||
const result = searchParamsSchema.safeParse({
|
||||
code: request.nextUrl.searchParams.get("code"),
|
||||
state: request.nextUrl.searchParams.get("state"),
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
console.error("[SAS] Invalid search params", result.error)
|
||||
redirect(`/${lang}/sas-x-scandic/error?errorCode=invalid_query`)
|
||||
}
|
||||
const { code, state } = result.data
|
||||
|
||||
const tokenResponse = await fetch(
|
||||
new URL("oauth/token", env.SAS_AUTH_ENDPOINT),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code: code,
|
||||
redirect_uri: new URL(
|
||||
`/${lang}/sas-x-scandic/callback`,
|
||||
new URL(env.PUBLIC_URL)
|
||||
).toString(),
|
||||
client_id: env.SAS_AUTH_CLIENTID,
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
const error = await tokenResponse.text()
|
||||
console.error("[SAS] Failed to get token", error)
|
||||
redirect(`/${lang}/sas-x-scandic/error?errorCode=token_error`)
|
||||
}
|
||||
|
||||
const tokenData = tokenResponseSchema.parse(await tokenResponse.json())
|
||||
|
||||
const stateResult = stateSchema.safeParse(
|
||||
JSON.parse(decodeURIComponent(state))
|
||||
)
|
||||
if (!stateResult.success) {
|
||||
redirect(`/${lang}/sas-x-scandic/error?errorCode=invalid_state`)
|
||||
}
|
||||
|
||||
const cookieStore = cookies()
|
||||
cookieStore.set(SAS_TOKEN_STORAGE_KEY, tokenData.access_token, {
|
||||
maxAge: 3600,
|
||||
httpOnly: true,
|
||||
})
|
||||
|
||||
if (stateResult.data.intent === "link") {
|
||||
const [data, error] = await safeTry(
|
||||
serverClient().partner.sas.requestOtp({})
|
||||
)
|
||||
// status: 'SENT' => OK
|
||||
if (!data || error) {
|
||||
//TODO: Check what error we get
|
||||
console.error("[SAS] Failed to request OTP", error)
|
||||
redirect(`/${lang}/sas-x-scandic/error`)
|
||||
}
|
||||
|
||||
console.log("[SAS] Request OTP response", data)
|
||||
|
||||
const otpUrl = new URL(
|
||||
`/${lang}/sas-x-scandic/otp`,
|
||||
new URL(env.PUBLIC_URL)
|
||||
)
|
||||
otpUrl.searchParams.set("intent", stateResult.data.intent)
|
||||
otpUrl.searchParams.set("to", data.otpReceiver)
|
||||
|
||||
redirect(otpUrl.toString())
|
||||
}
|
||||
|
||||
redirect(`/${lang}/sas-x-scandic/error?errorCode=unknown_intent`)
|
||||
}
|
||||
Reference in New Issue
Block a user