diff options
| author | Fuwn <[email protected]> | 2026-02-07 01:42:57 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-07 01:42:57 -0800 |
| commit | 5c5b1993edd890a80870ee05607ac5f088191d4e (patch) | |
| tree | a721b76bcd49ba10826c53efc87302c7a689512f /apps/web/app/auth | |
| download | asa.news-5c5b1993edd890a80870ee05607ac5f088191d4e.tar.xz asa.news-5c5b1993edd890a80870ee05607ac5f088191d4e.zip | |
feat: asa.news RSS reader with developer tier, REST API, and webhooks
Full-stack RSS reader SaaS: Supabase + Next.js + Go worker.
Includes three subscription tiers (free/pro/developer), API key auth,
read-only REST API, webhook push notifications, Stripe billing with
proration, and PWA support.
Diffstat (limited to 'apps/web/app/auth')
| -rw-r--r-- | apps/web/app/auth/callback/route.ts | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/apps/web/app/auth/callback/route.ts b/apps/web/app/auth/callback/route.ts new file mode 100644 index 0000000..a912da3 --- /dev/null +++ b/apps/web/app/auth/callback/route.ts @@ -0,0 +1,43 @@ +import { NextResponse } from "next/server" +import { createSupabaseServerClient } from "@/lib/supabase/server" +import type { EmailOtpType } from "@supabase/supabase-js" + +function sanitizeRedirectPath(rawPath: string | null): string { + if (!rawPath) return "/reader" + if (!rawPath.startsWith("/")) return "/reader" + if (rawPath.startsWith("//")) return "/reader" + if (rawPath.includes("\\")) return "/reader" + + return rawPath +} + +export async function GET(request: Request) { + const { searchParams, origin } = new URL(request.url) + const code = searchParams.get("code") + const tokenHash = searchParams.get("token_hash") + const type = searchParams.get("type") as EmailOtpType | null + const next = sanitizeRedirectPath(searchParams.get("next")) + + const supabaseClient = await createSupabaseServerClient() + + if (tokenHash && type) { + const { error } = await supabaseClient.auth.verifyOtp({ + token_hash: tokenHash, + type, + }) + + if (!error) { + return NextResponse.redirect(`${origin}${next}`) + } + } + + if (code) { + const { error } = await supabaseClient.auth.exchangeCodeForSession(code) + + if (!error) { + return NextResponse.redirect(`${origin}${next}`) + } + } + + return NextResponse.redirect(`${origin}/sign-in?error=auth`) +} |