diff --git a/Dockerfile b/Dockerfile index 9f23aea..f3de796 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,13 +10,6 @@ WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Inject NEXT_PUBLIC_ vars at build time (required for client-side embedding) -ARG NEXT_PUBLIC_GUEST_EMAIL -ARG NEXT_PUBLIC_GUEST_PASSWORD - -ENV NEXT_PUBLIC_GUEST_EMAIL=$NEXT_PUBLIC_GUEST_EMAIL -ENV NEXT_PUBLIC_GUEST_PASSWORD=$NEXT_PUBLIC_GUEST_PASSWORD - RUN npm run build # 3. Run production image (Node.js server) diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index 5e934dc..232f680 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -8,7 +8,7 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; -import { getGuestCredentials, loginUser } from "@/services/auth.service"; +import { loginAsGuest, loginUser } from "@/services/auth.service"; /** * Renders the login page containing the authentication form, error handling, @@ -65,7 +65,7 @@ export default function LoginPage() { }; /** - * Fetches guest user credentials and triggers guest authentication. + * Triggers secure guest authentication via the backend service. * * @async */ @@ -73,15 +73,15 @@ export default function LoginPage() { setError(null); setLoadingType("guest"); - const result = await getGuestCredentials(); + const result = await loginAsGuest(); - if (result.error || !result.email || !result.password) { - setError(result.error || "Guest login is not configured properly."); + if (result.error) { + setError(result.error); setLoadingType(null); return; } - await handleSignIn(result.email, result.password, "guest"); + router.push("/summary"); }; return ( diff --git a/app/api/auth/guest/route.ts b/app/api/auth/guest/route.ts new file mode 100644 index 0000000..77245b0 --- /dev/null +++ b/app/api/auth/guest/route.ts @@ -0,0 +1,51 @@ +/** + * @file api/auth/guest/route.ts + * @description API route handler for guest authentication utilizing server-side environment variables and auto sign-in. + */ + +import { NextResponse } from "next/server"; +import { signIn } from "@/auth"; + +/** + * Handles POST requests to authenticate as a guest user using environment credentials. + * + * @async + * @returns {Promise} A JSON response confirming successful guest sign-in or an error message. + */ +export async function POST() { + const email = process.env.GUEST_EMAIL; + const password = process.env.GUEST_PASSWORD; + + if (!email || !password) { + return NextResponse.json( + { error: "Guest login is not configured on the server." }, + { status: 500 }, + ); + } + + try { + await signIn("credentials", { + email, + password, + redirect: false, + }); + + return NextResponse.json({ success: true }, { status: 200 }); + } catch (error: any) { + console.error("Guest login error:", error); + if ( + error?.message?.includes("CredentialsSignin") || + error?.type === "CredentialsSignin" + ) { + return NextResponse.json( + { error: "Incorrect guest credentials." }, + { status: 401 }, + ); + } + + return NextResponse.json( + { error: "Internal Server Error" }, + { status: 500 }, + ); + } +} diff --git a/services/auth.service.ts b/services/auth.service.ts index 8435333..8056238 100644 --- a/services/auth.service.ts +++ b/services/auth.service.ts @@ -23,6 +23,31 @@ export async function getGuestCredentials() { return { email, password }; } +/** + * Triggers guest authentication securely via the backend API route. + * + * @async + * @returns {Promise<{ success?: boolean; error?: string }>} An object indicating success or describing the error. + */ +export async function loginAsGuest() { + try { + const response = await fetch("/api/auth/guest", { + method: "POST", + headers: { "Content-Type": "application/json" }, + }); + + const data = await response.json(); + + if (!response.ok) { + return { error: data.error || "Guest login failed." }; + } + + return { success: true }; + } catch (err: any) { + return { error: "Server error: API endpoint not available" }; + } +} + /** * Authenticates a user using email and password credentials, performing client-side validation first. *