import type { AppAuthOAuthStrategy, AppAuthSchema } from "auth/auth-schema"; import clsx from "clsx"; 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, Password, Label } from "ui/components/form/Formy/components"; import { SocialLink } from "./SocialLink"; import type { Validator } from "json-schema-form-react"; import { s } from "bknd/core"; import type { ErrorDetail } from "jsonv-ts"; class JsonvTsValidator implements Validator { async validate(schema: s.Schema, data: any) { return schema.validate(data).errors; } } export type LoginFormProps = Omit, "onSubmit" | "action"> & { className?: string; formData?: any; action: "login" | "register"; method?: "POST" | "GET"; auth?: Partial>; buttonLabel?: string; }; const validator = new JsonvTsValidator(); const schema = s.strictObject({ email: s.string({ pattern: "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", }), password: s.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
);