diff --git a/apps/waterfall-wiki/scripts/auth-cli.ts b/apps/waterfall-wiki/scripts/auth-cli.ts index 4e0d141..e79ae89 100644 --- a/apps/waterfall-wiki/scripts/auth-cli.ts +++ b/apps/waterfall-wiki/scripts/auth-cli.ts @@ -49,8 +49,11 @@ async function main() { const buildId = readFileSync('.next/BUILD_ID','utf8').trim(); assert.equal((await request('/')).status,200,'Public knowledge homepage'); assert.equal((await request('/account')).status,200,'Public account page'); + const homeData = await request(`/_next/data/${buildId}/index.json`); + assert.ok([200,404].includes(homeData.status),'Public homepage data is readable or absent for static pages'); + assert.ok(!isLoginRedirect(homeData.headers.get('location') || homeData.headers.get('x-nextjs-redirect'),base)); assert.equal((await request('/api/posts',{method:'POST',headers:{Cookie:'wiki_account='+ 'a'.repeat(64)},body:'{}'})).status,401,'Account cookies never grant admin rights'); - for (const path of ['/library/import','/skills/shadow-puppet/egret-example.png','/studio',`/_next/data/${buildId}/index.json`]) { + for (const path of ['/library/import','/skills/shadow-puppet/egret-example.png','/studio',`/_next/data/${buildId}/library/import.json`]) { const response = await request(path); assert.equal(response.status,307,path); const destination = response.headers.get('location') || response.headers.get('x-nextjs-redirect'); assert.ok(isLoginRedirect(destination,base),path+' must redirect to login: '+destination); } for (const path of ['/api/feed','/api/upload','/studio/api/export/test','/api/media/missing']) assert.equal((await request(path)).status,401,path); diff --git a/apps/waterfall-wiki/tests/auth.test.ts b/apps/waterfall-wiki/tests/auth.test.ts index ef5e33d..a2ed75e 100644 --- a/apps/waterfall-wiki/tests/auth.test.ts +++ b/apps/waterfall-wiki/tests/auth.test.ts @@ -34,9 +34,9 @@ test('proxy protects APIs, data routes, static content and Studio; fails closed' const temp=mkdtempSync(join(tmpdir(),'prompt-auth-')); const old=process.env.AUTH_CONFIG_FILE; try{ const config=newAuthConfig(); process.env.AUTH_CONFIG_FILE=join(temp,'config.json'); writeFileSync(process.env.AUTH_CONFIG_FILE,JSON.stringify(config)); - for(const path of ['/library/import','/skills/example.png','/_next/data/build/index.json','/studio']) assert.equal(proxy(new NextRequest('http://wiki.test'+path)).status,307,path); + for(const path of ['/library/import','/skills/example.png','/_next/data/build/library/import.json','/studio']) assert.equal(proxy(new NextRequest('http://wiki.test'+path)).status,307,path); for(const path of ['/api/upload','/studio/api/export','/api/feed']) assert.equal(proxy(new NextRequest('http://wiki.test'+path)).status,401,path); - for(const path of ['/','/write','/documents','/api/documents','/api/documents/preview','/guide/welcome','/protocol','/api/guides/welcome','/account','/api/account/session','/login','/brand-mark.svg','/_next/static/chunk.js','/api/health','/api/ready']) assert.equal(proxy(new NextRequest('http://wiki.test'+path)).status,200,path); + for(const path of ['/','/_next/data/build/index.json','/write','/documents','/api/documents','/api/documents/preview','/guide/welcome','/protocol','/api/guides/welcome','/account','/api/account/session','/login','/brand-mark.svg','/_next/static/chunk.js','/api/health','/api/ready']) assert.equal(proxy(new NextRequest('http://wiki.test'+path)).status,200,path); const headers={cookie:'prompt_session='+signSession(config),host:'wiki.test'}; assert.equal(proxy(new NextRequest('http://wiki.test/api/feed',{headers})).status,200); assert.equal(proxy(new NextRequest('http://wiki.test/api/posts',{method:'POST',headers:{...headers,origin:'http://evil.test'}})).status,403);