fix(api): CORS через isReturnToAllowed, мягкая проверка JWT_SECRET, 404 для /assets, better-sqlite3 в api, healthcheck на /ready

This commit is contained in:
Denozordec committed 2026-10-23 17:13:16 +07:00
1 parent 5cbf4d29d7
commit 08be310e6b
12 files changed
+93 -91

No files matched your search

+40 -5
View File
@@ -35,11 +35,11 @@ describe('статика', () => {
expect(spa.headers['cache-control']).toBe('no-cache')
})
it('отсутствующий ассет → не отдаёт index.html как JS (404 JSON или html, но не 200 js)', async () => {
it('отсутствующий ассет → 404, а не index.html (иначе после деплоя чанк-JS = HTML)', async () => {
app = await buildTestApp({ STATIC_DIR: staticDir() })
const res = await app.inject({ method: 'GET', url: '/assets/missing.js' })
// SPA-fallback допустим только как html; кэшироваться как immutable он не должен
expect(res.headers['cache-control']).not.toContain('immutable')
expect(res.statusCode).toBe(404)
expect(res.body).not.toContain('<html>')
})
it('отдаёт предсжатый .br по Accept-Encoding', async () => {
@@ -57,10 +57,10 @@ describe('статика', () => {
})
describe('кэш-заголовки API', () => {
it('app-switcher и auth/config кэшируются коротко', async () => {
it('auth/config кэшируется, app-switcher — нет (админка должна видеть правки сразу)', async () => {
app = await buildTestApp()
const sw = await app.inject({ method: 'GET', url: '/api/v1/app-switcher' })
expect(sw.headers['cache-control']).toBe('public, max-age=30')
expect(sw.headers['cache-control']).toBeUndefined()
const cfg = await app.inject({ method: 'GET', url: '/api/v1/auth/config' })
expect(cfg.headers['cache-control']).toBe('public, max-age=60')
})
@@ -122,6 +122,41 @@ describe('CORS', () => {
expect(none.statusCode).toBe(200)
})
it('боевой RETURN_TO_ALLOWLIST из env.traefik.example не теряет клиентов', () => {
const list =
'.shnt.top,https://vps.shnt.top,https://cfdm.shnt.top,https://bgp.shnt.top,https://fw.shnt.top,https://dns.shnt.top,https://cdn.shnt.top'
const check = createOriginChecker(
loadConfig({
JWT_SECRET: 'test-secret-at-least-8',
ISSUER: 'https://auth.shnt.top',
RETURN_TO_ALLOWLIST: list,
}),
() => [],
)
for (const o of [
'https://vps.shnt.top',
'https://dns.shnt.top',
'https://shnt.top',
'https://anything.shnt.top',
]) {
expect(check(o)).toBe(true)
}
expect(check('https://evil.example')).toBe(false)
})
it('private в allowlist пускает LAN-хосты', () => {
const check = createOriginChecker(
loadConfig({
JWT_SECRET: 'test-secret-at-least-8',
RETURN_TO_ALLOWLIST: '.shnt.top,private',
}),
() => [],
)
expect(check('http://192.168.1.10:8080')).toBe(true)
expect(check('http://10.0.0.5')).toBe(true)
expect(check('https://8.8.8.8')).toBe(false)
})
it('createOriginChecker: суффикс, localhost, switcher, *', () => {
const base = {
JWT_SECRET: 'test-secret-at-least-8',