mirror of
https://github.com/tiennm99/llmapikey.git
synced 2026-08-06 00:23:25 +00:00
feat(auth): replace Supabase Auth with app-native GitHub OAuth
Self-contained GitHub OAuth (Arctic) with a stateless HS256 signed-cookie session (jose); Supabase is downgraded to the Postgres host only. - Origin-derived callback (no redirect-uri env); read:user scope; access token read once at callback and discarded (no token storage). - CSRF via single-use state cookie; open-redirect guard on next. - getCurrentGithubIdentity() now reads the session cookie, preserving the numeric provider_id identity contract for admin/dashboard/mint. - Remove @supabase/ssr + @supabase/supabase-js, middleware, and the supabase-dependent rls test; delete lib/supabase clients.
This commit is contained in:
@@ -1,31 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
import { createBrowserSupabaseClient } from "@/lib/supabase/browser-client";
|
||||
import Link from "next/link";
|
||||
|
||||
/**
|
||||
* GitHub sign-in button. Kicks off Supabase OAuth; minimal scope (read:user).
|
||||
* GitHub sign-in button. A plain link to the server-side OAuth start route
|
||||
* (`/auth/login`), which creates the CSRF state and redirects to GitHub. No
|
||||
* client-side auth SDK needed.
|
||||
*
|
||||
* @param {{ next?: string, label?: string }} props
|
||||
*/
|
||||
export function SignInWithGithubButton({ next = "/dashboard", label = "Sign in with GitHub" }) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
async function handleSignIn() {
|
||||
setLoading(true);
|
||||
const supabase = createBrowserSupabaseClient();
|
||||
const redirectTo = `${window.location.origin}/auth/callback?next=${encodeURIComponent(next)}`;
|
||||
const { error } = await supabase.auth.signInWithOAuth({
|
||||
provider: "github",
|
||||
options: { redirectTo, scopes: "read:user" },
|
||||
});
|
||||
if (error) setLoading(false); // on success the browser navigates away
|
||||
}
|
||||
|
||||
const href = `/auth/login?next=${encodeURIComponent(next)}`;
|
||||
return (
|
||||
<button className="btn" onClick={handleSignIn} disabled={loading}>
|
||||
{loading ? "Redirecting…" : label}
|
||||
</button>
|
||||
<Link className="btn" href={href}>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { createServerAuthClient } from "@/lib/supabase/server-client";
|
||||
import { getCurrentGithubIdentity } from "@/lib/auth/current-github-identity";
|
||||
|
||||
/**
|
||||
* Session-aware header (server component). Shows Dashboard + sign-out when
|
||||
* authenticated; just Docs otherwise. Display only — `user_name` is fine here.
|
||||
* authenticated; just Docs otherwise. Display only — the login is fine here.
|
||||
*/
|
||||
export async function SiteHeader() {
|
||||
let username = null;
|
||||
try {
|
||||
const supabase = await createServerAuthClient();
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
username = user?.user_metadata?.user_name ?? null;
|
||||
const identity = await getCurrentGithubIdentity();
|
||||
username = identity?.githubUsername ?? null;
|
||||
} catch {
|
||||
username = null; // auth not configured (no env) — render signed-out header
|
||||
username = null; // auth not configured (no secret) — render signed-out header
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user