Merge pull request #7 from orus-dev/supabase

Supabase
This commit is contained in:
Klesti Selimaj
2026-02-05 18:05:53 +01:00
committed by GitHub
7 changed files with 103 additions and 12 deletions
+22
View File
@@ -0,0 +1,22 @@
// app/auth/callback/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
export async function GET(req: NextRequest) {
const code = req.nextUrl.searchParams.get("code");
if (!code) {
return NextResponse.json({ error: "code param required" }, { status: 400 });
}
const supabase = await createClient();
const { error } = await supabase.auth.exchangeCodeForSession(code);
if (error) {
console.error(error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
return NextResponse.redirect(new URL("/runs", req.url));
}
+1 -1
View File
@@ -6,7 +6,7 @@ import { signInWithGitHub } from "@/modules/account/actions";
export default function ContinueWith() { export default function ContinueWith() {
const continueWithGithub = () => { const continueWithGithub = () => {
signInWithGitHub(); signInWithGitHub(window.location.origin);
}; };
const continueWithGoogle = () => {}; const continueWithGoogle = () => {};
@@ -24,3 +24,25 @@ export async function createClient() {
}, },
); );
} }
export async function createClientApi() {
const cookieStore = await cookies();
return createServerClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SECRET_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set(name, value, options);
},
remove(name: string, options: CookieOptions) {
cookieStore.set(name, "", options);
},
},
},
);
}
+15 -2
View File
@@ -1,14 +1,17 @@
"use server"; "use server";
import * as Core from "./core"; import * as Core from "./core";
import { createClient } from "@/lib/supabase"; import { createClient } from "@/lib/supabase/server";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
export async function signInWithGitHub() { export async function signInWithGitHub(origin: string) {
const supabase = await createClient(); const supabase = await createClient();
const { data, error } = await supabase.auth.signInWithOAuth({ const { data, error } = await supabase.auth.signInWithOAuth({
provider: "github", provider: "github",
options: {
redirectTo: `${origin}/api/auth/callback`,
},
}); });
if (error) { if (error) {
@@ -19,6 +22,16 @@ export async function signInWithGitHub() {
return redirect(data.url); return redirect(data.url);
} }
export async function getSession() {
const supabase = await createClient();
try {
return await Core.getSession(supabase);
} catch {
return redirect("/login");
}
}
export async function signOut() { export async function signOut() {
const supabase = await createClient(); const supabase = await createClient();
+34 -8
View File
@@ -4,6 +4,22 @@ import { SupabaseClient, User } from "@supabase/supabase-js";
import "server-only"; import "server-only";
import { UserProfile } from "../user/types"; import { UserProfile } from "../user/types";
export async function signInWithGitHub(supabase: SupabaseClient) {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "github",
options: {
redirectTo: `/auth/callback`,
},
});
if (error) {
console.error(error);
throw error;
}
return data.url;
}
export async function getProfile( export async function getProfile(
supabase: SupabaseClient, supabase: SupabaseClient,
user: User, user: User,
@@ -36,10 +52,11 @@ export async function getGithubProfile(
.from("profiles") .from("profiles")
.insert({ .insert({
id: user.id, id: user.id,
username: user.user_metadata.login || null, username: user.user_metadata.user_name || `user_${user.id.slice(0, 6)}`,
full_name: user.user_metadata.name || null,
avatar_url: user.user_metadata.avatar_url || null, avatar_url: user.user_metadata.avatar_url || null,
}) bio: "",
created_at: new Date(),
} satisfies UserProfile)
.select() .select()
.single(); .single();
@@ -52,17 +69,26 @@ export async function getSession(
supabase: SupabaseClient, supabase: SupabaseClient,
): Promise<[User, UserProfile]> { ): Promise<[User, UserProfile]> {
const { const {
data: { session }, data: { user },
error: sessionError, error: sessionError,
} = await supabase.auth.getSession(); } = await supabase.auth.getUser();
if (sessionError || !session?.user) { if (sessionError || !user) {
throw new Error("No authenticated user found"); throw new Error("No authenticated user found");
} }
const user = session.user;
const profile = await getProfile(supabase, user); const profile = await getProfile(supabase, user);
return [user, profile]; return [user, profile];
} }
export async function getSessionRedirect(
supabase: SupabaseClient,
redirect: (s: string) => void,
): Promise<[User, UserProfile] | undefined> {
try {
return await getSession(supabase);
} catch {
redirect("/login");
}
}
+7
View File
@@ -1,9 +1,16 @@
"use server"; "use server";
import { createClient } from "@/lib/supabase/server";
import { getSession, getSessionRedirect } from "../account/core";
import * as Core from "./core"; import * as Core from "./core";
import { Run } from "./types"; import { Run } from "./types";
import { redirect } from "next/navigation";
export async function getLiveRuns(): Promise<Run[]> { export async function getLiveRuns(): Promise<Run[]> {
const supabase = await createClient();
const _ = await getSession(supabase);
return [ return [
{ {
id: 1, id: 1,
+2 -1
View File
@@ -1,6 +1,7 @@
export interface UserProfile { export interface UserProfile {
id: string; id: string;
username: string; username: string;
full_name: string;
avatar_url: string; avatar_url: string;
bio: string;
created_at: Date;
} }