mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-03 16:46:00 +00:00
feat: add local auth support if api storage provided
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import type { AppAuthOAuthStrategy, AppAuthSchema } from "auth/auth-schema";
|
||||
import clsx from "clsx";
|
||||
import { NativeForm } from "ui/components/form/native-form/NativeForm";
|
||||
import { transform } from "lodash-es";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import { transformObject } from "bknd/utils";
|
||||
import { useEffect, useState, type ComponentPropsWithoutRef, type FormEvent } 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 { useAuth } from "bknd/client";
|
||||
import { Alert } from "ui/components/display/Alert";
|
||||
import { useLocation } from "wouter";
|
||||
|
||||
export type LoginFormProps = Omit<ComponentPropsWithoutRef<"form">, "onSubmit" | "action"> & {
|
||||
export type LoginFormProps = Omit<ComponentPropsWithoutRef<"form">, "action"> & {
|
||||
className?: string;
|
||||
formData?: any;
|
||||
action: "login" | "register";
|
||||
@@ -23,25 +26,47 @@ export function AuthForm({
|
||||
action,
|
||||
auth,
|
||||
buttonLabel = action === "login" ? "Sign in" : "Sign up",
|
||||
onSubmit: _onSubmit,
|
||||
...props
|
||||
}: LoginFormProps) {
|
||||
const $auth = useAuth();
|
||||
const basepath = auth?.basepath ?? "/api/auth";
|
||||
const [error, setError] = useState<string>();
|
||||
const [, navigate] = useLocation();
|
||||
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<string, AppAuthOAuthStrategy>;
|
||||
const oauth = transformObject(auth?.strategies ?? {}, (value) => {
|
||||
return value.type !== "password" ? value.config : undefined;
|
||||
}) as Record<string, AppAuthOAuthStrategy>;
|
||||
const has_oauth = Object.keys(oauth).length > 0;
|
||||
|
||||
async function onSubmit(data: any, ctx: { event: FormEvent<HTMLFormElement> }) {
|
||||
if ($auth?.local) {
|
||||
ctx.event.preventDefault();
|
||||
|
||||
const res = await $auth.login(data);
|
||||
if ("token" in res) {
|
||||
navigate("/");
|
||||
} else {
|
||||
setError((res as any).error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await _onSubmit?.(ctx.event);
|
||||
// submit form
|
||||
ctx.event.currentTarget.submit();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if ($auth.user) {
|
||||
navigate("/");
|
||||
}
|
||||
}, [$auth.user]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
{has_oauth && (
|
||||
@@ -63,10 +88,12 @@ export function AuthForm({
|
||||
<NativeForm
|
||||
method={method}
|
||||
action={password.action}
|
||||
onSubmit={onSubmit}
|
||||
{...(props as any)}
|
||||
validateOn="change"
|
||||
className={clsx("flex flex-col gap-3 w-full", className)}
|
||||
>
|
||||
{error && <Alert.Exception message={error} className="justify-center" />}
|
||||
<Group>
|
||||
<Label htmlFor="email">Email address</Label>
|
||||
<Input type="email" name="email" required />
|
||||
|
||||
Reference in New Issue
Block a user