Adding working board
This commit is contained in:
+12
-8
@@ -10,6 +10,7 @@ import pg from 'pg'
|
||||
import type { CaseState } from '../src/types.js'
|
||||
import { authenticateJwt, createDevelopmentAdminToken, hasAdminClaim, requireAdmin } from './auth.js'
|
||||
import { createLevelRepository } from './levelRepository.js'
|
||||
import { createObjectStorageFromEnv } from './objectStorage.js'
|
||||
|
||||
const { Pool } = pg
|
||||
const databaseUrl = process.env.DATABASE_URL
|
||||
@@ -20,7 +21,9 @@ if (!databaseUrl) {
|
||||
|
||||
export const pool = new Pool({ connectionString: databaseUrl })
|
||||
const editingEnabled = process.env.LEVEL_EDITING_ENABLED === 'true'
|
||||
const levels = createLevelRepository(pool, editingEnabled)
|
||||
const objectStorage = createObjectStorageFromEnv()
|
||||
await objectStorage.initialize()
|
||||
const levels = createLevelRepository(pool, editingEnabled, objectStorage)
|
||||
|
||||
function wantsEdit(req: express.Request) {
|
||||
return editingEnabled && req.query.edit === '1' && hasAdminClaim(req)
|
||||
@@ -41,7 +44,7 @@ const upload = multer({
|
||||
})
|
||||
|
||||
app.get('/api/health', async (_req, res) => {
|
||||
try { await pool.query('SELECT 1'); res.json({ ok: true, database: 'connected', schema: 'osint', editingEnabled }) }
|
||||
try { await pool.query('SELECT 1'); res.json({ ok: true, database: 'connected', objectStorage: objectStorage.provider, schema: 'osint', editingEnabled }) }
|
||||
catch { res.status(503).json({ ok: false, database: 'unavailable' }) }
|
||||
})
|
||||
app.get('/api/session', (req, res) => res.json({ authenticated: Boolean(req.authClaims), isAdmin: hasAdminClaim(req) }))
|
||||
@@ -89,12 +92,13 @@ app.get('/api/assets/:id', async (req, res, next) => {
|
||||
try {
|
||||
const asset = await levels.getAsset(req.params.id)
|
||||
if (!asset) return res.status(404).json({ error: 'Asset not found' })
|
||||
const inline = asset.mime_type === 'application/pdf' || asset.mime_type.startsWith('image/') || asset.mime_type.startsWith('text/')
|
||||
res.setHeader('Content-Type', asset.mime_type || 'application/octet-stream')
|
||||
res.setHeader('Content-Length', asset.byte_size)
|
||||
res.setHeader('Content-Disposition', `${inline ? 'inline' : 'attachment'}; filename*=UTF-8''${encodeURIComponent(asset.original_name)}`)
|
||||
const inline = asset.mimeType === 'application/pdf' || asset.mimeType.startsWith('image/') || asset.mimeType.startsWith('text/')
|
||||
res.setHeader('Content-Type', asset.mimeType || 'application/octet-stream')
|
||||
res.setHeader('Content-Length', asset.byteSize)
|
||||
res.setHeader('Content-Disposition', `${inline ? 'inline' : 'attachment'}; filename*=UTF-8''${encodeURIComponent(asset.originalName)}`)
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff')
|
||||
res.send(asset.content)
|
||||
asset.stream.on('error', next)
|
||||
asset.stream.pipe(res)
|
||||
} catch (error) { next(error) }
|
||||
})
|
||||
app.post('/api/levels/:id/documents', requireAdmin, upload.single('file'), async (req, res, next) => {
|
||||
@@ -113,7 +117,7 @@ app.get('/api/levels/:id', async (req, res, next) => {
|
||||
})
|
||||
app.put('/api/levels/:id', async (req, res, next) => {
|
||||
const state = req.body as CaseState
|
||||
if (!state || state.id !== req.params.id || !Array.isArray(state.evidence) || !Array.isArray(state.connections)) return res.status(400).json({ error: 'Invalid level state' })
|
||||
if (!state || state.id !== req.params.id || !Array.isArray(state.exhibits) || !Array.isArray(state.views) || !Array.isArray(state.connections)) return res.status(400).json({ error: 'Invalid level state' })
|
||||
try {
|
||||
const authorMode = wantsEdit(req)
|
||||
await levels.saveLevel(state, authorMode)
|
||||
|
||||
Reference in New Issue
Block a user