Merged in feat/sas-otp-error-handling (pull request #1272)
Feat/sas otp error handling * Improve error handling for SAS OTP * Remove failing and deprecated test Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -13,12 +13,15 @@ import OneTimePasswordForm from "./OneTimePasswordForm"
|
||||
import type { LangParams, PageArgs, SearchParams } from "@/types/params"
|
||||
import type { Lang } from "@/constants/languages"
|
||||
|
||||
const otpError = z.enum(["invalidCode", "expiredCode"])
|
||||
const searchParamsSchema = z.object({
|
||||
intent: z.enum(["link"]),
|
||||
to: z.string(),
|
||||
error: z.enum(["invalidCode"]).optional(),
|
||||
error: otpError.optional(),
|
||||
})
|
||||
|
||||
export type OtpError = z.infer<typeof otpError>
|
||||
|
||||
export default async function SASxScandicOneTimePasswordPage({
|
||||
searchParams,
|
||||
params,
|
||||
@@ -37,37 +40,48 @@ export default async function SASxScandicOneTimePasswordPage({
|
||||
redirect(`/${params.lang}/sas-x-scandic/login?intent=${intent}`)
|
||||
}
|
||||
|
||||
const errors = {
|
||||
invalidCode: intl.formatMessage({
|
||||
id: "The code you’ve entered is incorrect.",
|
||||
}),
|
||||
}
|
||||
|
||||
async function handleOtpVerified({ otp }: { otp: string }) {
|
||||
"use server"
|
||||
|
||||
const [data, error] = await safeTry(
|
||||
serverClient().partner.sas.verifyOtp({ otp })
|
||||
)
|
||||
|
||||
// TODO correct status?
|
||||
// TODO handle all errors
|
||||
// STATUS === VERIFIED => ok
|
||||
// STATUS === ABUSED => otpRetryCount > otpMaxRetryCount
|
||||
if (error || data?.status !== "VERIFIED") {
|
||||
const search = new URLSearchParams({
|
||||
...searchParams,
|
||||
error: "invalidCode",
|
||||
}).toString()
|
||||
if (error || !data) {
|
||||
throw error || new Error("OTP verification failed")
|
||||
}
|
||||
|
||||
redirect(`/${params.lang}/sas-x-scandic/otp?${search}`)
|
||||
switch (data.status) {
|
||||
case "ABUSED":
|
||||
redirect(
|
||||
`/${params.lang}/sas-x-scandic/error?errorCode=tooManyFailedAttempts`
|
||||
)
|
||||
case "EXPIRED": {
|
||||
const search = new URLSearchParams({
|
||||
...searchParams,
|
||||
error: "expiredCode",
|
||||
}).toString()
|
||||
|
||||
redirect(`/${params.lang}/sas-x-scandic/otp?${search}`)
|
||||
}
|
||||
case "RETRY": {
|
||||
const search = new URLSearchParams({
|
||||
...searchParams,
|
||||
error: "invalidCode",
|
||||
}).toString()
|
||||
|
||||
redirect(`/${params.lang}/sas-x-scandic/otp?${search}`)
|
||||
}
|
||||
case "NOTSENT":
|
||||
case "NULL":
|
||||
case "SENT":
|
||||
case "PENDING":
|
||||
// These errors should never happen for verify, but according to the API spec they can
|
||||
throw new Error("Unhandled OTP status")
|
||||
}
|
||||
|
||||
switch (intent) {
|
||||
case "link":
|
||||
return handleLinkAccount({ lang: params.lang })
|
||||
default:
|
||||
throw new Error("")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +107,7 @@ export default async function SASxScandicOneTimePasswordPage({
|
||||
})}
|
||||
otpLength={6}
|
||||
onSubmit={handleOtpVerified}
|
||||
error={error ? errors[error] : undefined}
|
||||
error={error}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user