feat: update auth setup
This commit is contained in:
@@ -17,10 +17,6 @@ export class NavUserController extends Controller<{
|
||||
}
|
||||
}
|
||||
|
||||
authorize() {
|
||||
zitadel.authorize();
|
||||
}
|
||||
|
||||
signout() {
|
||||
zitadel.signout();
|
||||
}
|
||||
|
||||
@@ -18,62 +18,11 @@ import { useController } from "@/libraries/controller.ts";
|
||||
import { NavUserController } from "./nav-user.controller.ts";
|
||||
|
||||
export function NavUser() {
|
||||
const [{ user }, loading, { authorize, signout }] = useController(NavUserController);
|
||||
const [{ user }, loading, { signout }] = useController(NavUserController);
|
||||
const { isMobile } = useSidebar();
|
||||
|
||||
console.log({authorize})
|
||||
|
||||
if (loading === true || user === undefined) {
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size="lg"
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<Avatar className="h-8 w-8 rounded-lg grayscale">
|
||||
<AvatarImage src="" alt="" />
|
||||
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">Guest</span>
|
||||
<span className="text-muted-foreground truncate text-xs">guest@fixture.none</span>
|
||||
</div>
|
||||
<IconDotsVertical className="ml-auto size-4" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
|
||||
side={isMobile ? "bottom" : "right"}
|
||||
align="end"
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className="p-0 font-normal">
|
||||
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||
<Avatar className="h-8 w-8 rounded-lg">
|
||||
<AvatarImage src="" alt="Guest" />
|
||||
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">Guest</span>
|
||||
<span className="text-muted-foreground truncate text-xs">guest@fixture.none</span>
|
||||
</div>
|
||||
</div>
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={() => authorize()}>
|
||||
<IconLogout />
|
||||
Sign in
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createRootRoute, createRoute, createRouter } from "@tanstack/react-router";
|
||||
import { createRootRoute, createRoute, createRouter, redirect } from "@tanstack/react-router";
|
||||
|
||||
import { zitadel } from "./services/zitadel.ts";
|
||||
import { AppView } from "./views/app.view.tsx";
|
||||
import { CallbackView } from "./views/auth/callback.view.tsx";
|
||||
import { LoginView } from "./views/auth/login.view.tsx";
|
||||
@@ -22,6 +23,15 @@ const login = createRoute({
|
||||
const app = createRoute({
|
||||
id: "app",
|
||||
getParentRoute: () => root,
|
||||
beforeLoad: async () => {
|
||||
const user = await zitadel.userManager.getUser();
|
||||
if (user === null) {
|
||||
throw redirect({ to: "/login" });
|
||||
}
|
||||
if (user.expired === true) {
|
||||
throw redirect({ to: "/login" });
|
||||
}
|
||||
},
|
||||
component: AppView,
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createZitadelAuth, type ZitadelConfig } from "@zitadel/react";
|
||||
|
||||
const config: ZitadelConfig = {
|
||||
authority: "https://auth.valkyrjs.com",
|
||||
client_id: "347982179092987909",
|
||||
client_id: "348172463709945862",
|
||||
redirect_uri: "http://localhost:5173/callback",
|
||||
post_logout_redirect_uri: "http://localhost:5173",
|
||||
response_type: "code",
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Controller } from "../libraries/controller.ts";
|
||||
import { router } from "../router.tsx";
|
||||
import { zitadel } from "../services/zitadel.ts";
|
||||
|
||||
export class AppController extends Controller<{
|
||||
authenticated: boolean;
|
||||
}> {
|
||||
async onInit() {
|
||||
return {
|
||||
authenticated: await this.#getAuthenticatedState(),
|
||||
};
|
||||
}
|
||||
|
||||
async #getAuthenticatedState(): Promise<boolean> {
|
||||
const user = await zitadel.userManager.getUser();
|
||||
if (user === null) {
|
||||
router.navigate({ to: "/login" });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
signout() {
|
||||
zitadel.signout();
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,8 @@ import { Outlet } from "@tanstack/react-router";
|
||||
import { AppSidebar } from "@/components/app-sidebar.tsx";
|
||||
import { SiteHeader } from "@/components/site-header.tsx";
|
||||
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar.tsx";
|
||||
import { useController } from "@/libraries/controller.ts";
|
||||
|
||||
import { AppController } from "./app.controller.ts";
|
||||
|
||||
export function AppView() {
|
||||
const [{ authenticated }, loading] = useController(AppController);
|
||||
if (loading === true) {
|
||||
return <div>Loading ...</div>;
|
||||
}
|
||||
if (authenticated === false) {
|
||||
return <div>Unauthenticated</div>;
|
||||
}
|
||||
return (
|
||||
<SidebarProvider
|
||||
style={
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
import { GalleryVerticalEnd } from "lucide-react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Field, FieldDescription, FieldGroup, FieldLabel, FieldSeparator } from "@/components/ui/field";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Field, FieldDescription, FieldGroup, FieldSeparator } from "@/components/ui/field";
|
||||
import { cn } from "@/libraries/utils";
|
||||
import { zitadel } from "@/services/zitadel.ts";
|
||||
|
||||
export function LoginForm({
|
||||
className,
|
||||
passkey,
|
||||
...props
|
||||
}: { passkey: (email: string) => Promise<void> } & React.ComponentProps<"div">) {
|
||||
export function LoginForm({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-6", className)} {...props}>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
const email = e.currentTarget.elements.namedItem("email");
|
||||
if (email instanceof HTMLInputElement) {
|
||||
passkey(email.value);
|
||||
}
|
||||
zitadel.authorize();
|
||||
}}
|
||||
>
|
||||
<FieldGroup>
|
||||
@@ -35,11 +28,7 @@ export function LoginForm({
|
||||
</FieldDescription>
|
||||
</div>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="email">Email</FieldLabel>
|
||||
<Input id="email" type="email" placeholder="m@example.com" required />
|
||||
</Field>
|
||||
<Field>
|
||||
<Button type="submit">Login</Button>
|
||||
<Button type="submit">Login with Zitadel</Button>
|
||||
</Field>
|
||||
<FieldSeparator>Or</FieldSeparator>
|
||||
<Field className="grid gap-4 sm:grid-cols-2">
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Controller } from "../../libraries/controller.ts";
|
||||
|
||||
export class LoginController extends Controller {
|
||||
async passkey(email: string) {
|
||||
const result = await fetch("https://auth.valkyrjs.com/v2/sessions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
checks: {
|
||||
user: {
|
||||
loginName: email,
|
||||
},
|
||||
},
|
||||
challenges: {
|
||||
webAuthN: {
|
||||
domain: "auth.valkyrjs.com",
|
||||
userVerificationRequirement: "USER_VERIFICATION_REQUIREMENT_REQUIRED",
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
console.log(await result.text());
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
import { useController } from "../../libraries/controller.ts";
|
||||
import { LoginForm } from "./components/login-form.tsx";
|
||||
import { LoginController } from "./login.controller.ts";
|
||||
|
||||
export function LoginView() {
|
||||
const [, , { passkey }] = useController(LoginController);
|
||||
return (
|
||||
<div className="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
|
||||
<div className="w-full max-w-sm">
|
||||
<LoginForm passkey={passkey} />
|
||||
<LoginForm />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user