add next auth & login with github

This commit is contained in:
Michi 2025-04-27 18:31:17 +02:00
parent 78afa6be22
commit 9a9110e58c
10 changed files with 226 additions and 22 deletions

View file

@ -0,0 +1,2 @@
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers

12
src/app/login/page.tsx Normal file
View file

@ -0,0 +1,12 @@
import LoginForm from "@/components/login/login-form";
import { Suspense } from "react";
export default function LoginPage(){
return (
<main className="h-screen flex justify-center items-center">
<Suspense>
<LoginForm />
</Suspense>
</main>
);
}

View file

@ -1,5 +1,6 @@
import { Button } from "@/components/ui/button";
import { Rss } from "lucide-react";
import Link from "next/link";
export default function Page() {
return (
@ -12,7 +13,11 @@ export default function Page() {
</div>
<div>
<Button>Log in</Button>
<Link
href="/login"
key="Login">
<Button>Log in</Button>
</Link>
</div>
</div>
);

9
src/auth.ts Normal file
View file

@ -0,0 +1,9 @@
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [GitHub],
pages: {
signIn: "/login",
}
})

View file

@ -1,5 +1,6 @@
import { Home, Rss, LogOut } from "lucide-react";
import { Home, Rss } from "lucide-react";
import Link from 'next/link';
import { SignOut } from "./login/signout-button";
import {
Sidebar,
@ -28,13 +29,6 @@ const items = {
icon: Rss,
},
],
footer: [
{
title: "Log out",
url: "#",
icon: LogOut,
},
]
};
export function AppSidebar() {
@ -74,19 +68,11 @@ export function AppSidebar() {
<SidebarFooter>
<SidebarMenu>
{items.footer.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<Link
key={item.title}
href={item.url}
>
<item.icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
<SidebarMenuItem>
<SidebarMenuButton asChild>
<SignOut />
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>

View file

@ -0,0 +1,41 @@
import { signIn } from "@/auth";
import { Button } from '@/components/ui/button';
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter
} from '@/components/ui/card';
export default function LoginForm(){
return (
<div>
<Card>
<CardHeader className="text-center">
<CardTitle>Nice to meet you!</CardTitle>
<CardDescription>Sign in below with your GitHub account.</CardDescription>
</CardHeader>
<CardContent>
<form action={async () => {
"use server";
await signIn("github", { redirectTo: "/home" });
}}>
<Button type="submit" variant="outline" className="w-full">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<title>GitHub</title>
<path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
</svg>
Login with GitHub
</Button>
</form>
</CardContent>
</Card>
<p className="my-4 text-center text-sm text-muted-foreground">
By clicking continue, you agree to our Terms of Service and Privacy Policy.
</p>
</div>
);
}

View file

@ -0,0 +1,18 @@
import { signOut } from "@/auth";
import { LogOut } from "lucide-react";
export function SignOut() {
return (
<form
action={async () => {
"use server";
await signOut();
}}
>
<button className="flex flex-row items-center gap-2 cursor-pointer w-full" type="submit">
<LogOut size={16} />
<span>Log out</span>
</button>
</form>
)
}

12
src/middleware.ts Normal file
View file

@ -0,0 +1,12 @@
import { auth } from "@/auth"
export default auth((req) => {
if (!req.auth && req.nextUrl.pathname !== "/login") {
const newUrl = new URL("/login", req.nextUrl.origin)
return Response.redirect(newUrl)
}
})
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico|$).*)"],
}