diff --git a/cookies.txt b/cookies.txt
new file mode 100644
index 0000000..c31d989
--- /dev/null
+++ b/cookies.txt
@@ -0,0 +1,4 @@
+# Netscape HTTP Cookie File
+# https://curl.se/docs/http-cookies.html
+# This file was generated by libcurl! Edit at your own risk.
+
diff --git a/env.example b/env.example
index 9e0ce9f..4fb944a 100644
--- a/env.example
+++ b/env.example
@@ -8,5 +8,8 @@ ORIGIN=https://your-domain.com
# Authentication token (required - generate a secure random token)
MAGIC_LINK_TOKEN=your-secure-token-here
+# Access PIN code (required - set a PIN for site access)
+ACCESS_PIN=1234
+
# Cloudinary URL for photo uploads (optional)
CLOUDINARY_URL=cloudinary://api_key:api_secret@cloud_name
diff --git a/src/app.d.ts b/src/app.d.ts
index 4e61bff..0ce4e60 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -8,6 +8,7 @@ declare global {
// interface Platform {}
interface Locals {
authenticated: boolean;
+ hasAccess: boolean;
}
}
}
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index c7479ac..6cb842d 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -1,12 +1,24 @@
import type { Handle } from '@sveltejs/kit';
+import { redirect } from '@sveltejs/kit';
+import { dev } from '$app/environment';
export const handle: Handle = async ({ event, resolve }) => {
+ // Check if user has access (PIN code authentication)
+ const accessCookie = event.cookies.get('access_granted');
+ const hasAccess = !!accessCookie;
+
+ // If user doesn't have access and is not on the access page, redirect to /access
+ if (!hasAccess && event.url.pathname !== '/access') {
+ throw redirect(302, '/access');
+ }
+
// Check if user is authenticated using the chef token cookie
const chefToken = event.cookies.get('chef_token');
const authenticated = !!chefToken;
// Add authentication status to locals for use in load functions
event.locals.authenticated = authenticated;
+ event.locals.hasAccess = hasAccess;
// Continue with the request
const response = await resolve(event);
diff --git a/src/routes/access/+page.server.ts b/src/routes/access/+page.server.ts
new file mode 100644
index 0000000..7e78daf
--- /dev/null
+++ b/src/routes/access/+page.server.ts
@@ -0,0 +1,38 @@
+import type { PageServerLoad, Actions } from './$types';
+import { fail, redirect } from '@sveltejs/kit';
+import { dev } from '$app/environment';
+
+export const load: PageServerLoad = async ({ locals }) => {
+ // If user already has access, redirect to home
+ if (locals.hasAccess) {
+ throw redirect(302, '/');
+ }
+
+ return {};
+};
+
+export const actions: Actions = {
+ default: async ({ request, cookies }) => {
+ const data = await request.formData();
+ const pin = data.get('pin') as string;
+
+ if (!pin) {
+ return fail(400, { error: 'PIN is required' });
+ }
+
+ if (pin !== process.env.ACCESS_PIN) {
+ return fail(400, { error: 'Invalid PIN' });
+ }
+
+ // Set access cookie
+ cookies.set('access_granted', 'true', {
+ path: '/',
+ httpOnly: true,
+ sameSite: 'lax',
+ secure: !dev,
+ maxAge: 60 * 60 * 24 * 30 // 30 days
+ });
+
+ throw redirect(302, '/');
+ }
+};
diff --git a/src/routes/access/+page.svelte b/src/routes/access/+page.svelte
new file mode 100644
index 0000000..acd1949
--- /dev/null
+++ b/src/routes/access/+page.svelte
@@ -0,0 +1,47 @@
+
+
+
Enter your access code to continue
+