From a84373642e34d743a8b4ab105925e07b36b8661c Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Sun, 24 May 2026 20:24:47 -0500 Subject: [PATCH] fix(security): drop wildcard CORS + redundant OPTIONS from 24 API routes (P0 #5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes P0 #5 (CORS) from PARTIAL → RESOLVED. fix-auth-bypass Brief 4 (commit 297afca) cleaned login + register; this brief sweeps the remaining 24 pages/api/** handlers that carried the identical scaffolded wildcard-CORS + redundant-OPTIONS pattern, plus adds a blocking forbidden-cors-headers CI job to lock in the cleanup against future regression. Per architect Decision 1 — Option B (sweep all 24 in one PR) chosen over Option A (narrow verify.js-only + queue separate sweep). Pattern-drift audit (14 of 24 files spot-checked across parent + architect) found zero drift; mechanical safety confirmed. Per Decision 2 — OPTIONS handler deleted entirely (matches Brief 4 precedent). Same-origin Vercel deployment doesn't preflight; method check at top of handler returns 405 if any client ever sends OPTIONS again. Per Decision 3 — verify.js's overly-permissive Allow-Methods: 'GET, POST, PUT, DELETE, OPTIONS' is moot (deleted under D2); the handler's existing `if (req.method !== 'GET') return 405` guard at line 17 (now line ~5) is the remaining gate. Per Decision 4 — no new per-route tests this convoy. None of the 24 routes have vitest coverage today; adding handler-level tests is the queued fill-vitest-handler-coverage convoy. Per Decision 5 — new `forbidden-cors-headers` CI job added, modeled verbatim on `forbidden-endpoints`. Blocking (no `|| true`, no `continue-on-error`). Greps pages/api/ for any `Access-Control-Allow-(Origin|Methods|Headers)` reappearance and exits 1 on hit. Verification: - npm run lint: 128 problems (baseline match) - npm run test:run: 21/21 vitest pass (no regression) - git grep -nE "Access-Control-Allow-..." -- 'pages/api/**': zero matches - git grep -nE "OPTIONS" -- 'pages/api/**': zero matches (post-sweep) - new forbidden-cors-headers grep exits 0 against swept tree No code paths in lib/**, components/**, scripts/**, or test/** touched. No package.json / lockfile churn. No workflow YAML beyond the single ci.yml job addition. No AGENTS.md edits (doc-writer pass at convoy close). Co-authored-by: Cursor --- .github/workflows/ci.yml | 29 +++++++++++++++++++ pages/api/admin/index.js | 11 ------- pages/api/auth/verify.js | 11 ------- pages/api/cards/[id]/ownership.js | 10 ------- pages/api/cards/owned.js | 11 ------- pages/api/cards/search.js | 11 ------- pages/api/collections.js | 11 ------- pages/api/collections/[identifier].js | 11 ------- .../api/collections/[identifier]/activity.js | 11 ------- pages/api/collections/[identifier]/cards.js | 11 ------- .../collections/[identifier]/permissions.js | 11 ------- .../collections/[identifier]/thumbnails.js | 11 ------- pages/api/community/collections.js | 11 ------- pages/api/favorites.js | 10 ------- pages/api/invite/accept.js | 11 ------- pages/api/invite/decline.js | 11 ------- pages/api/public/collections.js | 11 ------- pages/api/user/avatar.js | 11 ------- pages/api/user/avatar/generate.js | 11 ------- pages/api/user/delete.js | 11 ------- pages/api/user/password.js | 11 ------- pages/api/user/profile.js | 11 ------- pages/api/user/settings.js | 11 ------- pages/api/user/stats.js | 11 ------- pages/api/users/search.js | 10 ------- 25 files changed, 29 insertions(+), 261 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaa1aa5..a3e3534 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,6 +113,35 @@ jobs: fi echo "OK: no forbidden dev endpoints under pages/api/." + forbidden-cors-headers: + name: No wildcard CORS in pages/api + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Fail if any pages/api/ handler carries Access-Control-Allow-Origin + run: | + # The tcg-vault frontend and API are served from the same Vercel + # deployment (same origin), so CORS headers serve no purpose and + # are a documented attack surface (see .convoys/cors-tighten.md + # and AGENTS.md Gotcha #5). Brief 4 of fix-auth-bypass cleaned + # login.js + register.js; the cors-tighten convoy swept the + # remaining 24 files. This job locks the cleanup in. + # + # If a future cross-origin caller is legitimately needed, design + # a proper CORS layer (probably via middleware) rather than + # scaffolding wildcards into individual handlers. + MATCHES=$(grep -rEn 'Access-Control-Allow-(Origin|Methods|Headers)' pages/api/ 2>/dev/null || true) + if [ -n "$MATCHES" ]; then + echo "::error::Forbidden CORS headers present under pages/api/. Remove them — same-origin Vercel deployment does not need CORS." + echo "$MATCHES" | while IFS= read -r line; do + file=$(echo "$line" | cut -d: -f1) + lineno=$(echo "$line" | cut -d: -f2) + echo "::error file=${file},line=${lineno}::Forbidden CORS header — delete this line." + done + exit 1 + fi + echo "OK: no Access-Control-Allow-* headers under pages/api/." + test: name: Unit tests (vitest) runs-on: ubuntu-latest diff --git a/pages/api/admin/index.js b/pages/api/admin/index.js index 8b36fab..28e1305 100644 --- a/pages/api/admin/index.js +++ b/pages/api/admin/index.js @@ -242,17 +242,6 @@ async function loadLorcanaCards() { } export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET' && req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/auth/verify.js b/pages/api/auth/verify.js index e97bb95..4f34209 100644 --- a/pages/api/auth/verify.js +++ b/pages/api/auth/verify.js @@ -3,17 +3,6 @@ import jwt from 'jsonwebtoken'; import { JWT_SECRET } from '../../../lib/auth-secret.js'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/cards/[id]/ownership.js b/pages/api/cards/[id]/ownership.js index 0dff046..1324468 100644 --- a/pages/api/cards/[id]/ownership.js +++ b/pages/api/cards/[id]/ownership.js @@ -2,16 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/cards/owned.js b/pages/api/cards/owned.js index 1c8db08..c1ea65d 100644 --- a/pages/api/cards/owned.js +++ b/pages/api/cards/owned.js @@ -2,17 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/cards/search.js b/pages/api/cards/search.js index 3cddbd1..541a17e 100644 --- a/pages/api/cards/search.js +++ b/pages/api/cards/search.js @@ -1,17 +1,6 @@ import { sql } from '@vercel/postgres'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/collections.js b/pages/api/collections.js index 2a5f7a6..0bfb9a2 100644 --- a/pages/api/collections.js +++ b/pages/api/collections.js @@ -3,17 +3,6 @@ import { getUserFromRequest, logCollectionActivity } from '../../lib/permission- import { generateUniqueSlug } from '../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method === 'GET') { try { // Get authenticated user diff --git a/pages/api/collections/[identifier].js b/pages/api/collections/[identifier].js index 5997d47..377094c 100644 --- a/pages/api/collections/[identifier].js +++ b/pages/api/collections/[identifier].js @@ -3,17 +3,6 @@ import { getUserFromRequest } from '../../../lib/permission-middleware'; import { isValidSlug } from '../../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Try to get authenticated user (optional for public collections) const user = await getUserFromRequest(req); diff --git a/pages/api/collections/[identifier]/activity.js b/pages/api/collections/[identifier]/activity.js index 98e8fe2..2f22a2c 100644 --- a/pages/api/collections/[identifier]/activity.js +++ b/pages/api/collections/[identifier]/activity.js @@ -3,17 +3,6 @@ import { getUserFromRequest } from '../../../../lib/permission-middleware'; import { isValidSlug } from '../../../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/collections/[identifier]/cards.js b/pages/api/collections/[identifier]/cards.js index a6373b3..6766b36 100644 --- a/pages/api/collections/[identifier]/cards.js +++ b/pages/api/collections/[identifier]/cards.js @@ -3,17 +3,6 @@ import { getUserFromRequest } from '../../../../lib/permission-middleware'; import { isValidSlug } from '../../../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Try to get authenticated user (optional for public collections) const user = await getUserFromRequest(req); diff --git a/pages/api/collections/[identifier]/permissions.js b/pages/api/collections/[identifier]/permissions.js index fbb355d..2051949 100644 --- a/pages/api/collections/[identifier]/permissions.js +++ b/pages/api/collections/[identifier]/permissions.js @@ -3,17 +3,6 @@ import { getUserFromRequest } from '../../../../lib/permission-middleware'; import { isValidSlug } from '../../../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Get authenticated user const user = await getUserFromRequest(req); diff --git a/pages/api/collections/[identifier]/thumbnails.js b/pages/api/collections/[identifier]/thumbnails.js index 0956d56..6307011 100644 --- a/pages/api/collections/[identifier]/thumbnails.js +++ b/pages/api/collections/[identifier]/thumbnails.js @@ -3,17 +3,6 @@ import { getUserFromRequest } from '../../../../lib/permission-middleware'; import { isValidSlug } from '../../../../lib/slug-utils'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/community/collections.js b/pages/api/community/collections.js index d3869f4..d8bf422 100644 --- a/pages/api/community/collections.js +++ b/pages/api/community/collections.js @@ -2,17 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/favorites.js b/pages/api/favorites.js index f6db406..36db095 100644 --- a/pages/api/favorites.js +++ b/pages/api/favorites.js @@ -3,16 +3,6 @@ import jwt from 'jsonwebtoken'; import { JWT_SECRET } from '../../lib/auth-secret.js'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - // Verify authentication const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { diff --git a/pages/api/invite/accept.js b/pages/api/invite/accept.js index 940577b..a3710d2 100644 --- a/pages/api/invite/accept.js +++ b/pages/api/invite/accept.js @@ -1,17 +1,6 @@ import { sql } from '@vercel/postgres'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/invite/decline.js b/pages/api/invite/decline.js index 15eeb05..5910b73 100644 --- a/pages/api/invite/decline.js +++ b/pages/api/invite/decline.js @@ -1,17 +1,6 @@ import { sql } from '@vercel/postgres'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/public/collections.js b/pages/api/public/collections.js index db32e9e..5f07408 100644 --- a/pages/api/public/collections.js +++ b/pages/api/public/collections.js @@ -1,17 +1,6 @@ import { sql } from '@vercel/postgres'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/user/avatar.js b/pages/api/user/avatar.js index f5d653c..8608873 100644 --- a/pages/api/user/avatar.js +++ b/pages/api/user/avatar.js @@ -11,17 +11,6 @@ export const config = { }; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'POST, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Get authenticated user const user = await getUserFromRequest(req); diff --git a/pages/api/user/avatar/generate.js b/pages/api/user/avatar/generate.js index 8d8b6b8..5e389db 100644 --- a/pages/api/user/avatar/generate.js +++ b/pages/api/user/avatar/generate.js @@ -3,17 +3,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/user/delete.js b/pages/api/user/delete.js index 414992e..a682717 100644 --- a/pages/api/user/delete.js +++ b/pages/api/user/delete.js @@ -3,17 +3,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'DELETE') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/user/password.js b/pages/api/user/password.js index a4c64b0..e434a8b 100644 --- a/pages/api/user/password.js +++ b/pages/api/user/password.js @@ -3,17 +3,6 @@ import bcrypt from 'bcryptjs'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'PUT, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'PUT') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/user/profile.js b/pages/api/user/profile.js index d519f4e..c61a5f6 100644 --- a/pages/api/user/profile.js +++ b/pages/api/user/profile.js @@ -2,17 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Get authenticated user const user = await getUserFromRequest(req); diff --git a/pages/api/user/settings.js b/pages/api/user/settings.js index 40683d4..48b1daf 100644 --- a/pages/api/user/settings.js +++ b/pages/api/user/settings.js @@ -2,17 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - try { // Get authenticated user const user = await getUserFromRequest(req); diff --git a/pages/api/user/stats.js b/pages/api/user/stats.js index b490c76..b592c27 100644 --- a/pages/api/user/stats.js +++ b/pages/api/user/stats.js @@ -2,17 +2,6 @@ import { sql } from '@vercel/postgres'; import { getUserFromRequest } from '../../../lib/permission-middleware'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } diff --git a/pages/api/users/search.js b/pages/api/users/search.js index d80d6be..9c2c72f 100644 --- a/pages/api/users/search.js +++ b/pages/api/users/search.js @@ -3,16 +3,6 @@ import jwt from 'jsonwebtoken'; import { JWT_SECRET } from '../../../lib/auth-secret.js'; export default async function handler(req, res) { - // Set CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); }