import type { AppAuthOAuthStrategy, AppAuthSchema } from "auth/auth-schema"; import clsx from "clsx"; import { Type } from "core/utils"; import { Form } from "json-schema-form-react"; import { transform } from "lodash-es"; import type { ComponentPropsWithoutRef } from "react"; import { Button } from "ui/components/buttons/Button"; import { Group, Input, Label } from "ui/components/form/Formy/components"; import { SocialLink } from "./SocialLink"; import type { ValueError } from "@sinclair/typebox/value"; import { type TSchema, Value } from "core/utils"; import type { Validator } from "json-schema-form-react"; class TypeboxValidator implements Validator { async validate(schema: TSchema, data: any) { return Value.Check(schema, data) ? [] : [...Value.Errors(schema, data)]; } } export type LoginFormProps = Omit, "onSubmit" | "action"> & { className?: string; formData?: any; action: "login" | "register"; method?: "POST" | "GET"; auth?: Partial>; buttonLabel?: string; }; const validator = new TypeboxValidator(); const schema = Type.Object({ email: Type.String({ pattern: "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$" }), password: Type.String({ minLength: 8 // @todo: this should be configurable }) }); export function AuthForm({ formData, className, method = "POST", action, auth, buttonLabel = action === "login" ? "Sign in" : "Sign up", ...props }: LoginFormProps) { const basepath = auth?.basepath ?? "/api/auth"; const password = { action: `${basepath}/password/${action}`, strategy: auth?.strategies?.password ?? ({ type: "password" } as const) }; const oauth = transform( auth?.strategies ?? {}, (result, value, key) => { if (value.type !== "password") { result[key] = value.config; } }, {} ) as Record; const has_oauth = Object.keys(oauth).length > 0; return (
{has_oauth && ( <>
{Object.entries(oauth)?.map(([name, oauth], key) => ( ))}
)}
{({ errors, submitting }) => ( <> )}
); } const Or = () => (
or
);