feat(storage): MinIO object storage, Neon Auth, Supabase removal
Deploy to route.crispygoat.com / deploy (push) Failing after 3m1s
Deploy to route.crispygoat.com / deploy (push) Failing after 3m1s
- Add MinIO/S3-compatible storage client (src/lib/storage.ts) with uploadObject, deleteObject, presigned URL helpers, and BUCKETS constant - Wire product images, brand logos, and water log photos to MinIO via the new storage client - Migrate forgot-password to Neon Auth (remove Supabase /auth/v1/recover call) - Migrate send-scheduled cron to direct Postgres + Resend (remove Supabase Edge Function proxy) - Add logoUrl to email types (OrderReceipt, Welcome, PasswordReset) and pass brand_settings.logo_url from all call sites - Update email templates to use dynamic logoUrl instead of hardcoded Supabase bucket URLs - Remove hardcoded Supabase URLs from TuxedoVideoHero, TuxedoAboutPage, TimeTrackingFieldClient; use brand_settings props + local public/ fallback - Download brand logos (3) and tuxedo-hero.mp4 (36MB) from Supabase bucket to public/ for local development - Add MinIO env vars to .env.example (endpoint, access key, secret, buckets) - Fix TimeTrackingFieldClient to destructure logoUrl and brandAccent props - Fix admin/users.ts logoUrl type (null → undefined for optional string) - Remove stale sb- cookie from wholesale-auth - Migrate tuxedo/about page to remove supabase import and use pool query for wholesale_settings lookup
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
import { auth, signOut } from "@/lib/auth";
|
||||
import { getSession, signOut } from "@/lib/auth";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
/**
|
||||
* /protected-example
|
||||
*
|
||||
* Smoke-test page that demonstrates the new Auth.js v5 pattern. Calling
|
||||
* `auth()` server-side returns the current session (null if not signed
|
||||
* Smoke-test page that demonstrates the Neon Auth pattern. Calling
|
||||
* `getSession()` server-side returns the current session (null if not signed
|
||||
* in). The middleware in `../middleware.ts` already redirects
|
||||
* unauthenticated visitors to `/login`, so by the time this page renders
|
||||
* we always have a session.
|
||||
*
|
||||
* The page shows:
|
||||
* • The user's name, email, and provider
|
||||
* • The session token (first 8 chars only — never expose the whole thing)
|
||||
* • A "Sign out" form action that calls `signOut()` from `next-auth`
|
||||
* • A "Sign out" form action that calls `signOut()` from Neon Auth
|
||||
*/
|
||||
export default async function ProtectedExamplePage() {
|
||||
const session = await auth();
|
||||
const { data: session } = await getSession();
|
||||
|
||||
// Defensive: middleware should have already redirected. Render a
|
||||
// friendly hint if we ever reach here unauthenticated.
|
||||
@@ -39,12 +39,7 @@ export default async function ProtectedExamplePage() {
|
||||
}
|
||||
|
||||
const user = session.user;
|
||||
const expires = session.expires
|
||||
? new Date(session.expires).toLocaleString()
|
||||
: "(no expiry)";
|
||||
|
||||
// The raw session token isn't on the session object in v5 (only the
|
||||
// csrfToken is exposed client-side). We surface what we do have.
|
||||
return (
|
||||
<main className="min-h-screen flex items-center justify-center bg-stone-50 px-6 py-12">
|
||||
<div className="w-full max-w-xl space-y-6">
|
||||
@@ -56,7 +51,7 @@ export default async function ProtectedExamplePage() {
|
||||
Protected example
|
||||
</h1>
|
||||
<p className="mt-1 text-sm text-stone-500">
|
||||
You are signed in. This page is guarded by the Auth.js
|
||||
You are signed in. This page is guarded by the Neon Auth
|
||||
middleware in <code className="text-xs">middleware.ts</code>.
|
||||
</p>
|
||||
</header>
|
||||
@@ -81,13 +76,9 @@ export default async function ProtectedExamplePage() {
|
||||
<div>
|
||||
<dt className="text-stone-500">User id</dt>
|
||||
<dd className="mt-1 font-mono text-xs text-stone-700 break-all">
|
||||
{(user as { id?: string }).id ?? "(none)"}
|
||||
{user.id ?? "(none)"}
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-stone-500">Session expires</dt>
|
||||
<dd className="mt-1 font-medium text-stone-900">{expires}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
@@ -106,7 +97,8 @@ export default async function ProtectedExamplePage() {
|
||||
<form
|
||||
action={async () => {
|
||||
"use server";
|
||||
await signOut({ redirectTo: "/login" });
|
||||
await signOut();
|
||||
redirect("/login");
|
||||
}}
|
||||
className="mt-4"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user