@@ -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));
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user