- Add permissions logic for status options in corrective actions. - Create tests for permissions functionality. - Implement queries for user authentication and actions management. - Develop Actions page to display and manage corrective actions. - Create authentication pages for login, setup, and password reset. - Add IncidentDetail page to view incident details and associated actions. - Implement Settings page for user management and password changes.
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { Hono } from 'hono'
|
|
import { csrf } from 'hono/csrf'
|
|
import { HTTPException } from 'hono/http-exception'
|
|
import { secureHeaders } from 'hono/secure-headers'
|
|
import { loadSession } from './auth/middleware.ts'
|
|
import type { Config } from './config.ts'
|
|
import type { Db } from './db/client.ts'
|
|
import type { AppEnv } from './lib/http.ts'
|
|
import type { Notifier } from './notifications.ts'
|
|
import { actionRoutes } from './routes/actions.ts'
|
|
import { attachmentRoutes } from './routes/attachments.ts'
|
|
import { authRoutes } from './routes/auth.ts'
|
|
import { incidentRoutes } from './routes/incidents.ts'
|
|
import { rootCauseRoutes } from './routes/root-causes.ts'
|
|
import { setupRoutes } from './routes/setup.ts'
|
|
import { areaRoutes, siteRoutes } from './routes/sites.ts'
|
|
import { statsRoutes } from './routes/stats.ts'
|
|
import { userRoutes } from './routes/users.ts'
|
|
import type { FileStorage } from './storage.ts'
|
|
|
|
export interface AppDeps {
|
|
db: Db
|
|
config: Config
|
|
notifier: Notifier
|
|
storage: FileStorage
|
|
}
|
|
|
|
export function createApp({ db, config, notifier, storage }: AppDeps) {
|
|
const app = new Hono<AppEnv>()
|
|
|
|
app.use('*', secureHeaders())
|
|
const publicOrigin = new URL(config.publicUrl).origin
|
|
// Form/multipart posts must come from our own pages. JSON requests are already protected by CORS preflight.
|
|
const sameSite = csrf({ origin: (origin, c) => origin === publicOrigin || origin === new URL(c.req.url).origin })
|
|
|
|
app.use('/api/*', sameSite, async (c, next) => {
|
|
c.set('db', db)
|
|
c.set('config', config)
|
|
c.set('notifier', notifier)
|
|
c.set('storage', storage)
|
|
c.header('Cache-Control', 'no-store')
|
|
await next()
|
|
})
|
|
app.use('/api/*', loadSession)
|
|
|
|
app.get('/api/health', (c) => c.json({ ok: true }))
|
|
app.route('/api/setup', setupRoutes)
|
|
app.route('/api/auth', authRoutes())
|
|
app.route('/api/users', userRoutes)
|
|
app.route('/api/sites', siteRoutes)
|
|
app.route('/api/areas', areaRoutes)
|
|
app.route('/api/incidents', incidentRoutes)
|
|
app.route('/api/root-causes', rootCauseRoutes)
|
|
app.route('/api/actions', actionRoutes)
|
|
app.route('/api/attachments', attachmentRoutes)
|
|
app.route('/api/stats', statsRoutes)
|
|
app.all('/api/*', (c) => c.json({ error: 'Not found' }, 404))
|
|
|
|
app.onError((error, c) => {
|
|
if (error instanceof HTTPException) return c.json({ error: error.message }, error.status)
|
|
console.error(error)
|
|
return c.json({ error: 'Internal server error' }, 500)
|
|
})
|
|
|
|
return app
|
|
}
|
|
|
|
export type App = ReturnType<typeof createApp>
|