feat: email+password auth with db-backed sessions

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
ahmed mohammed
2026-09-22 07:32:07 +03:00
co-authored by Claude Opus 4.7
parent 692ffa97c5
commit 5f8746cfae
13 changed files with 199 additions and 13 deletions
+6
View File
@@ -0,0 +1,6 @@
export default function Auth({ children }: { children: React.ReactNode }) {
return <div style={{ maxWidth: 420, margin: "0 auto", padding: "var(--qai-space-3xl) var(--qai-space-l)" }}>
<p className="label">SQL Server qAI</p>{children}
<p className="colophon">ShowPlan XML in · Jev-ranked remediation out · self-hosted</p>
</div>;
}
+11
View File
@@ -0,0 +1,11 @@
import { signIn } from "@/lib/actions";
import { AuthForm } from "@/components/auth-form";
export default function Login() {
return <>
<h1 style={{ fontFamily: "var(--qai-font-display)", fontSize: "var(--qai-text-2xl)" }}>Sign in</h1>
<AuthForm action={signIn} submit="Sign in" fields={[
{ name: "email", label: "Email", type: "email", autoComplete: "email" },
{ name: "password", label: "Password", type: "password", autoComplete: "current-password" }]} />
<p><a href="/signup">Create an account</a></p>
</>;
}
+12
View File
@@ -0,0 +1,12 @@
import { signUp } from "@/lib/actions";
import { AuthForm } from "@/components/auth-form";
export default function Signup() {
return <>
<h1 style={{ fontFamily: "var(--qai-font-display)", fontSize: "var(--qai-text-2xl)" }}>Create account</h1>
<AuthForm action={signUp} submit="Create account" fields={[
{ name: "email", label: "Email", type: "email", autoComplete: "email" },
{ name: "password", label: "Password", type: "password", autoComplete: "new-password",
help: "10 characters minimum." }]} />
<p><a href="/login">Sign in instead</a></p>
</>;
}
+4 -1
View File
@@ -1,4 +1,7 @@
export default function Console({ children }: { children: React.ReactNode }) {
import { requireUser } from "@/lib/auth";
export default async function Console({ children }: { children: React.ReactNode }) {
await requireUser();
return <div className="shell">
<aside className="rail" aria-label="Previous analyses">qAI</aside>
<main className="main">{children}</main>
+2 -1
View File
@@ -1,2 +1,3 @@
import { redirect } from "next/navigation";
export default function Home() { redirect("/login"); }
import { sessionUser } from "@/lib/auth";
export default async function Home() { redirect((await sessionUser()) ? "/app" : "/login"); }