RJBULK-APP/actions/auth.ts

86 lines
2.8 KiB
TypeScript
Raw Normal View History

"use server";
import { redirect } from "next/navigation";
import PocketBase from "pocketbase";
import { z } from "zod";
import { PB_URL } from "@/lib/pocketbase";
import { clearAuthCookie, setAuthCookie } from "@/lib/auth";
const loginSchema = z.object({
identity: z.string().min(1, "Username or email is required"),
password: z.string().min(1, "Password is required"),
});
export type LoginResult = { ok: true } | { ok: false; error: string };
export async function loginAction(_: unknown, formData: FormData): Promise<LoginResult> {
const parsed = loginSchema.safeParse({
identity: formData.get("identity"),
password: formData.get("password"),
});
if (!parsed.success) {
return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
}
const pb = new PocketBase(PB_URL);
try {
const auth = await pb.collection("users").authWithPassword(parsed.data.identity, parsed.data.password);
if (!auth?.token) {
return { ok: false, error: "Invalid username or password" };
}
await setAuthCookie(auth.token);
} catch (err: any) {
return { ok: false, error: "Invalid username or password" };
}
redirect("/dashboard");
}
const registerSchema = z
.object({
name: z.string().min(1, "Name is required"),
username: z.string().min(3, "Username must be at least 3 characters"),
email: z.string().email("Valid email required"),
password: z.string().min(8, "Password must be at least 8 characters"),
confirm: z.string().min(1, "Please confirm your password"),
})
.refine((d) => d.password === d.confirm, { message: "Passwords do not match", path: ["confirm"] });
export type RegisterResult = { ok: true } | { ok: false; error: string };
export async function registerAction(_: unknown, formData: FormData): Promise<RegisterResult> {
const parsed = registerSchema.safeParse({
name: formData.get("name"),
username: formData.get("username"),
email: formData.get("email"),
password: formData.get("password"),
confirm: formData.get("confirm"),
});
if (!parsed.success) {
return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
}
const pb = new PocketBase(PB_URL);
try {
await pb.collection("users").create({
email: parsed.data.email,
username: parsed.data.username,
password: parsed.data.password,
passwordConfirm: parsed.data.confirm,
name: parsed.data.name,
emailVisibility: true,
verified: true,
});
// Auto-login
const auth = await pb.collection("users").authWithPassword(parsed.data.email, parsed.data.password);
await setAuthCookie(auth.token);
} catch (err: any) {
return { ok: false, error: err?.response?.message ?? "Could not create account" };
}
redirect("/dashboard");
}
export async function logoutAction() {
await clearAuthCookie();
redirect("/login");
}