From 231e9d57c8feebc5e3ac6a649accf71b91e53a1e Mon Sep 17 00:00:00 2001 From: Leo dev Date: Thu, 5 Feb 2026 15:29:16 +0100 Subject: [PATCH] Sign in with github implementation --- src/modules/account/actions.ts | 23 ++++++++++++ src/modules/account/core.ts | 65 ++++++++++++++++++++++++++++++++++ src/modules/account/types.ts | 3 -- src/modules/user/types.ts | 6 ++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/modules/account/actions.ts b/src/modules/account/actions.ts index 59d1635..a2e7820 100644 --- a/src/modules/account/actions.ts +++ b/src/modules/account/actions.ts @@ -1,3 +1,26 @@ "use server"; import * as Core from "./core"; +import { createClient } from "@/lib/supabase"; +import { redirect } from "next/navigation"; + +export async function signInWithGitHub() { + const supabase = await createClient(); + + const { data, error } = await supabase.auth.signInWithOAuth({ + provider: "github", + }); + + if (error) { + console.error(error); + return redirect("/login?msg=Trouble"); + } + + return redirect(data.url); +} + +export async function signOut() { + const supabase = await createClient(); + + const { error } = await supabase.auth.signOut(); +} diff --git a/src/modules/account/core.ts b/src/modules/account/core.ts index a59f71d..7edcfc7 100644 --- a/src/modules/account/core.ts +++ b/src/modules/account/core.ts @@ -1,3 +1,68 @@ "use server"; +import { SupabaseClient, User } from "@supabase/supabase-js"; import "server-only"; +import { UserProfile } from "../user/types"; + +export async function getProfile( + supabase: SupabaseClient, + user: User, +): Promise { + // Try to fetch existing profile + const { data: profile, error } = await supabase + .from("profiles") + .select("*") + .eq("id", user.id) + .single(); + + if (error && error.code !== "PGRST116") { + // PGRST116 = "No rows found" is fine + throw error; + } + + // If no profile, create one + if (!profile) { + return getGithubProfile(supabase, user); + } + + return profile; +} + +export async function getGithubProfile( + supabase: SupabaseClient, + user: User, +): Promise { + const { data: newProfile, error: insertError } = await supabase + .from("profiles") + .insert({ + id: user.id, + username: user.user_metadata.login || null, + full_name: user.user_metadata.name || null, + avatar_url: user.user_metadata.avatar_url || null, + }) + .select() + .single(); + + if (insertError) throw insertError; + + return newProfile; +} + +export async function getSession( + supabase: SupabaseClient, +): Promise<[User, UserProfile]> { + const { + data: { session }, + error: sessionError, + } = await supabase.auth.getSession(); + + if (sessionError || !session?.user) { + throw new Error("No authenticated user found"); + } + + const user = session.user; + + const profile = await getProfile(supabase, user); + + return [user, profile]; +} diff --git a/src/modules/account/types.ts b/src/modules/account/types.ts index b914e3e..e69de29 100644 --- a/src/modules/account/types.ts +++ b/src/modules/account/types.ts @@ -1,3 +0,0 @@ -export interface Account { - -} diff --git a/src/modules/user/types.ts b/src/modules/user/types.ts index e69de29..4e35545 100644 --- a/src/modules/user/types.ts +++ b/src/modules/user/types.ts @@ -0,0 +1,6 @@ +export interface UserProfile { + id: string; + username: string; + full_name: string; + avatar_url: string; +}