/** * Configure the UI that's used by the Code provider. * * ```ts {1,7-12} * import { CodeUI } from "@openauthjs/openauth/ui/code" * import { CodeProvider } from "@openauthjs/openauth/provider/code" * * export default issuer({ * providers: { * code: CodeAdapter( * CodeUI({ * copy: { * code_info: "We'll send a pin code to your email" * }, * sendCode: (claims, code) => console.log(claims.email, code) * }) * ) * }, * // ... * }) * ``` * * @packageDocumentation */ /** @jsxImportSource hono/jsx */ import { CodeProviderOptions } from "../provider/code.js" import { UnknownStateError } from "../error.js" import { Layout } from "./base.js" import { FormAlert } from "./form.js" const DEFAULT_COPY = { /** * Copy for the email input. */ email_placeholder: "Email", /** * Error message when the email is invalid. */ email_invalid: "Email address is not valid", /** * Copy for the continue button. */ button_continue: "Continue", /** * Copy informing that the pin code will be emailed. */ code_info: "We'll send a pin code to your email.", /** * Copy for the pin code input. */ code_placeholder: "Code", /** * Error message when the code is invalid. */ code_invalid: "Invalid code", /** * Copy for when the code was sent. */ code_sent: "Code sent to ", /** * Copy for when the code was resent. */ code_resent: "Code resent to ", /** * Copy for the link to resend the code. */ code_didnt_get: "Didn't get code?", /** * Copy for the resend button. */ code_resend: "Resend", } export type CodeUICopy = typeof DEFAULT_COPY /** * Configure the password UI. */ export interface CodeUIOptions { /** * Callback to send the pin code to the user. * * The `claims` object contains the email or phone number of the user. You can send the code * using this. * * @example * ```ts * async (claims, code) => { * // Send the code via the claim * } * ``` */ sendCode: (claims: Record, code: string) => Promise /** * Custom copy for the UI. */ copy?: Partial /** * The mode to use for the input. * @default "email" */ mode?: "email" | "phone" } /** * Creates a UI for the Code provider flow. * @param props - Configure the UI. */ export function CodeUI(props: CodeUIOptions): CodeProviderOptions { const copy = { ...DEFAULT_COPY, ...props.copy, } const mode = props.mode ?? "email" return { sendCode: props.sendCode, length: 6, request: async (_req, state, _form, error): Promise => { if (state.type === "start") { const jsx = (
{error?.type === "invalid_claim" && ( )}

{copy.code_info}

) return new Response(jsx.toString(), { headers: { "Content-Type": "text/html", }, }) } if (state.type === "code") { const jsx = (
{error?.type === "invalid_code" && ( )} {state.type === "code" && ( )}
{Object.entries(state.claims).map(([key, value]) => ( ))}
{copy.code_didnt_get}{" "}
) return new Response(jsx.toString(), { headers: { "Content-Type": "text/html", }, }) } throw new UnknownStateError() }, } }