Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion apps/editor/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { afterEach, expect, test } from 'bun:test'
import { unstable_doesMiddlewareMatch } from 'next/experimental/testing/server'
import { issueSession, SESSION_COOKIE } from './lib/self-host-auth'
import { gateRequest } from './proxy'
import { config, gateRequest } from './proxy'

const OLD_ENV = { ...process.env }

Expand Down Expand Up @@ -66,6 +67,46 @@ test('login, setup, health and the scene API are never gated here', () => {
}
})

test('the proxy runs on every page and API path, including dotted and locale-prefixed ones', () => {
process.env.PASCAL_ADMIN_PASSWORD = 'secret'
for (const path of [
'/',
'/project/abc',
'/project/a.json',
'/project/abc.d.e',
'/api/x.json',
'/api/plugins/mint/session',
'/api/plugins/mint/api/x.json',
'/fr/admin',
'/en/api/x',
'/en/project/a.json',
'/fr/items/x.glb',
'/settings',
]) {
expect([path, unstable_doesMiddlewareMatch({ config, url: path })]).toEqual([path, true])
expect([path, gateRequest(request(path))?.status]).not.toEqual([path, undefined])
}
})

test('Next and public/ static assets skip the proxy', () => {
for (const path of [
'/_next/static/chunks/main.js',
'/_next/static/media/font.woff2',
'/_next/image?url=%2Fpascal.svg&w=64&q=75',
'/favicon.ico',
'/pascal-logo-shape.svg',
'/audios/sfx/snapshot_capture.mp3',
'/demos/demo_1.json',
'/fonts/PlusJakartaSans-SemiBold.ttf',
'/hdri/venice_sunset_1k.hdr',
'/icons/column.webp',
'/items/round-carpet/model.glb',
'/material/concrete/prepared_drywall/prepared_drywall_normal_512.ktx2',
]) {
expect([path, unstable_doesMiddlewareMatch({ config, url: path })]).toEqual([path, false])
}
})

test('loopback and an upstream proxy are open', () => {
delete process.env.PASCAL_ADMIN_PASSWORD
const loopback = new Request('http://localhost:3002/', {
Expand Down
9 changes: 7 additions & 2 deletions apps/editor/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export function gateRequest(request: Request): NextResponse | null {
}

export const config = {
// Everything except Next's own assets and files served from `public/`.
matcher: ['/((?!_next/|.*\\.[a-zA-Z0-9]+$).*)'],
// Everything except Next's own assets and the files served from `public/`
// and `app/favicon.ico`, listed by location. Exclude assets by where they
// live, never by a file extension, since dynamic route segments accept dots.
// Keep this in sync with the folders in `public/`.
matcher: [
'/((?!_next/|favicon\\.ico$|(?:audios|demos|fonts|hdri|icons|items|material)/|[^/]+\\.svg$).*)',
],
}
Loading