diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 7fdf85f..7a1cecd 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -19,7 +19,13 @@ const { title, description = 'CC24-Guide - A comprehensive directory of digital {title} - CC24-Guide + + + + + + \ No newline at end of file diff --git a/src/scripts/auth-utils.js b/src/scripts/auth-utils.js deleted file mode 100644 index fb53e59..0000000 --- a/src/scripts/auth-utils.js +++ /dev/null @@ -1,30 +0,0 @@ -// src/scripts/auth-utils.js -export async function checkAuthAndRedirect(targetUrl) { - try { - const response = await fetch('/api/auth/status'); - const data = await response.json(); - - if (data.authRequired && !data.authenticated) { - const returnUrl = encodeURIComponent(targetUrl); - window.location.href = `/api/auth/login?returnTo=${returnUrl}`; - return false; - } else { - window.location.href = targetUrl; - return true; - } - } catch (error) { - console.error('Auth check failed:', error); - window.location.href = targetUrl; // Fallback - return true; - } -} - -export function setupAuthButtons(selector = '[data-contribute-button]') { - document.addEventListener('click', async (e) => { - const button = e.target.closest(selector); - if (!button) return; - - e.preventDefault(); - await checkAuthAndRedirect(button.href); - }); -} \ No newline at end of file diff --git a/src/utils/client-auth.ts b/src/scripts/client-auth.js similarity index 57% rename from src/utils/client-auth.ts rename to src/scripts/client-auth.js index 143b0bd..2f900eb 100644 --- a/src/utils/client-auth.ts +++ b/src/scripts/client-auth.js @@ -1,7 +1,8 @@ -// src/scripts/client-auth.js - Client-side auth utilities +// src/scripts/client-auth.js - CONSOLIDATED client-side auth utilities +// This file REPLACES auth-utils.js and any client-side auth functions /** - * Consolidated client-side auth status check + * Check authentication status */ async function checkClientAuth() { try { @@ -30,8 +31,12 @@ async function requireClientAuth(callback, returnUrl) { if (authStatus.authRequired && !authStatus.authenticated) { const targetUrl = returnUrl || window.location.href; window.location.href = `/api/auth/login?returnTo=${encodeURIComponent(targetUrl)}`; + return false; } else { - callback(); + if (typeof callback === 'function') { + callback(); + } + return true; } } @@ -49,7 +54,30 @@ async function showIfAuthenticated(selector) { } } +/** + * Handle contribute button clicks with auth check + */ +function setupAuthButtons(selector = '[data-contribute-button]') { + document.addEventListener('click', async (e) => { + const button = e.target.closest(selector); + if (!button) return; + + e.preventDefault(); + await requireClientAuth(() => { + window.location.href = button.href; + }, button.href); + }); +} + // Make functions available globally window.checkClientAuth = checkClientAuth; window.requireClientAuth = requireClientAuth; -window.showIfAuthenticated = showIfAuthenticated; \ No newline at end of file +window.showIfAuthenticated = showIfAuthenticated; +window.setupAuthButtons = setupAuthButtons; + +// Auto-setup contribute buttons when DOM is ready +document.addEventListener('DOMContentLoaded', () => { + setupAuthButtons('[data-contribute-button]'); +}); + +console.log('Client auth utilities loaded'); \ No newline at end of file diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 43d18d5..0e6aea4 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,9 +1,8 @@ -// src/utils/auth.ts - Enhanced with Email Support +// src/utils/auth.ts - SERVER-SIDE ONLY (remove client-side functions) import { SignJWT, jwtVerify, type JWTPayload } from 'jose'; import { serialize, parse } from 'cookie'; import { config } from 'dotenv'; -import type { AstroGlobal, APIRoute } from 'astro'; - +import type { AstroGlobal } from 'astro'; // Load environment variables config(); @@ -210,8 +209,9 @@ export interface AuthContext { } /** - * Consolidated auth check for Astro pages - * Replaces repeated auth patterns in contribute pages + * CONSOLIDATED: Replace repeated auth patterns in .astro pages + * Usage: const authResult = await withAuth(Astro); + * if (authResult instanceof Response) return authResult; */ export async function withAuth(Astro: AstroGlobal): Promise { const authRequired = process.env.AUTHENTICATION_NECESSARY !== 'false'; @@ -254,10 +254,15 @@ export async function withAuth(Astro: AstroGlobal): Promise { +export async function withAPIAuth(request: Request): Promise<{ + authenticated: boolean; + userId: string; + session?: SessionData +}> { const authRequired = process.env.AUTHENTICATION_NECESSARY !== 'false'; if (!authRequired) { @@ -292,50 +297,4 @@ export function createAuthErrorResponse(message: string = 'Authentication requir status: 401, headers: { 'Content-Type': 'application/json' } }); -} - -async function checkClientAuth() { - try { - const response = await fetch('/api/auth/status'); - const data = await response.json(); - return { - authenticated: data.authenticated, - authRequired: data.authRequired, - expires: data.expires - }; - } catch (error) { - console.error('Auth check failed:', error); - return { - authenticated: false, - authRequired: true - }; - } -} - -/** - * Redirect to login if not authenticated, otherwise execute callback - */ -export async function requireClientAuth(callback, returnUrl) { - const authStatus = await checkClientAuth(); - - if (authStatus.authRequired && !authStatus.authenticated) { - const targetUrl = returnUrl || window.location.href; - window.location.href = `/api/auth/login?returnTo=${encodeURIComponent(targetUrl)}`; - } else { - callback(); - } -} - -/** - * Show/hide element based on authentication - */ -export async function showIfAuthenticated(selector) { - const authStatus = await checkClientAuth(); - const element = document.querySelector(selector); - - if (element) { - element.style.display = (!authStatus.authRequired || authStatus.authenticated) - ? 'inline-flex' - : 'none'; - } } \ No newline at end of file