Files
template-app/apps/web/app/auth/sign-in/page.tsx
T

80 lines
3.3 KiB
TypeScript

// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The sign-in page (spec §7): where a visitor lands when they need to be signed in, and where a
// failed sign-in ends (src/server/auth-response.ts). It says what went wrong in the person's
// language -- from a fixed set of codes, never from the provider's text -- and offers the way in the
// deployment has: its identity provider, or, in development with none, any e-mail address.
import { loadAuthConfig } from "@conusai-kit/auth"
import { redirect } from "next/navigation"
import type { ReactElement } from "react"
import { AUTH_ERROR_MESSAGES, parseAuthError, safeReturnTo } from "../../../src/server/auth-errors"
import { betterAuthFormLabels, MIN_PASSWORD_LENGTH } from "../../../src/server/better-auth" // kit:convex-better-auth
import { pageContext } from "../../../src/server/page"
import { BetterAuthForm } from "../../../src/ui/better-auth-form" // kit:convex-better-auth
import { StateView } from "../../../src/ui/state-view"
export const dynamic = "force-dynamic"
export default async function SignIn({
searchParams,
}: {
searchParams: Promise<{ error?: string; return_to?: string }>
}): Promise<ReactElement> {
const { error, return_to: returnToParam } = await searchParams
const { i18n, signedIn } = await pageContext()
const returnTo = safeReturnTo(returnToParam)
// Somebody who is already in has nothing to do here, unless they were sent back with an error.
const code = parseAuthError(error)
if (signedIn && !code) redirect(returnTo)
const config = loadAuthConfig()
const next = returnTo === "/" ? "" : `?return_to=${encodeURIComponent(returnTo)}`
const betterAuth = config.provider === "convex-better-auth" // kit:convex-better-auth
return (
<StateView title={i18n.message("signin.title")}>
{code ? (
<p className="app-error" role="alert">
{i18n.message(AUTH_ERROR_MESSAGES[code])}
</p>
) : (
<p>{i18n.message("signin.intro")}</p>
)}
{config.oidc ? (
<p>
<a href={`/auth/sign-in/start${next}`}>{i18n.message("signin.continue")}</a>
</p>
) : null}
{!config.oidc && config.devLogin ? (
<form method="get" action="/auth/dev-login">
<h2>{i18n.message("signin.devTitle")}</h2>
<p>{i18n.message("signin.devHelp")}</p>
{returnTo === "/" ? null : <input type="hidden" name="return_to" value={returnTo} />}
<label className="kit-field" htmlFor="dev-email">
{i18n.message("app.email")}
<input id="dev-email" name="email" type="email" required autoComplete="email" />
</label>
<button type="submit">{i18n.message("signin.devSubmit")}</button>
</form>
) : null}
{/* kit:convex-better-auth:begin */}
{betterAuth ? (
<>
<BetterAuthForm
mode="sign-in"
returnTo={returnTo}
minPasswordLength={MIN_PASSWORD_LENGTH}
labels={betterAuthFormLabels(i18n, "sign-in")}
/>
<p>
<a href={`/auth/sign-up${next}`}>{i18n.message("signin.account.toSignUp")}</a>
</p>
</>
) : null}
{/* kit:convex-better-auth:end */}
{!config.oidc && !config.devLogin && config.provider === "oidc" ? (
<p role="status">{i18n.message("signin.notConfigured")}</p>
) : null}
</StateView>
)
}