Something went wrong. Try again.
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
Something went wrong. Try again.
5.1 kB · 167 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168import { Elysia } from 'elysia'import type { Context } from 'elysia'import { cors } from '@elysiajs/cors'import { staticPlugin } from '@elysiajs/static'
import type { Config } from './lib/types'import { BASE_HOST } from './lib/constants'import { createClientMetadata, getOAuthClient, getCurrentKeys, cleanupExpiredSessions, rotateKeysIfNeeded} from './lib/oauth-client'import { authRoutes } from './routes/auth'import { wispRoutes } from './routes/wisp'import { domainRoutes } from './routes/domain'import { userRoutes } from './routes/user'import { siteRoutes } from './routes/site'import { csrfProtection } from './lib/csrf'import { DNSVerificationWorker } from './lib/dns-verification-worker'import { logger, logCollector, observabilityMiddleware } from './lib/observability'import { promptAdminSetup } from './lib/admin-auth'import { adminRoutes } from './routes/admin'
const config: Config = { domain: (Bun.env.DOMAIN ?? `https://${BASE_HOST}`) as Config['domain'], clientName: Bun.env.CLIENT_NAME ?? 'PDS-View'}
// Initialize admin setup (prompt if no admin exists)await promptAdminSetup()
const client = await getOAuthClient(config)
// Periodic maintenance: cleanup expired sessions and rotate keys// Run every hourconst runMaintenance = async () => { console.log('[Maintenance] Running periodic maintenance...') await cleanupExpiredSessions() await rotateKeysIfNeeded()}
// Run maintenance on startuprunMaintenance()
// Schedule maintenance to run every hoursetInterval(runMaintenance, 60 * 60 * 1000)
// Start DNS verification worker (runs every 10 minutes)const dnsVerifier = new DNSVerificationWorker( 10 * 60 * 1000, // 10 minutes (msg, data) => { logCollector.info(`[DNS Verifier] ${msg}`, 'main-app', data ? { data } : undefined) })
dnsVerifier.start()logger.info('DNS Verifier Started - checking custom domains every 10 minutes')
export const app = new Elysia({ serve: { maxPayloadLength: 1024 * 1024 * 128 * 3, development: Bun.env.NODE_ENV !== 'production' ? true : false, id: Bun.env.NODE_ENV !== 'production' ? undefined : null, } }) // Observability middleware .onBeforeHandle(observabilityMiddleware('main-app').beforeHandle) .onAfterHandle((ctx: Context) => { observabilityMiddleware('main-app').afterHandle(ctx) // Security headers middleware const { set } = ctx // Prevent clickjacking attacks set.headers['X-Frame-Options'] = 'DENY' // Prevent MIME type sniffing set.headers['X-Content-Type-Options'] = 'nosniff' // Strict Transport Security (HSTS) - enforce HTTPS set.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains' // Referrer policy - limit referrer information set.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin' // Content Security Policy set.headers['Content-Security-Policy'] = "default-src 'self'; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " + "style-src 'self' 'unsafe-inline'; " + "img-src 'self' data: https:; " + "font-src 'self' data:; " + "connect-src 'self' https:; " + "frame-ancestors 'none'; " + "base-uri 'self'; " + "form-action 'self'" // Additional security headers set.headers['X-XSS-Protection'] = '1; mode=block' set.headers['Permissions-Policy'] = 'geolocation=(), microphone=(), camera=()' }) .onError(observabilityMiddleware('main-app').onError) .use(csrfProtection()) .use(authRoutes(client)) .use(wispRoutes(client)) .use(domainRoutes(client)) .use(userRoutes(client)) .use(siteRoutes(client)) .use(adminRoutes()) .use( await staticPlugin({ prefix: '/' }) ) .get('/client-metadata.json', () => { return createClientMetadata(config) }) .get('/jwks.json', async () => { const keys = await getCurrentKeys() if (!keys.length) return { keys: [] }
return { keys: keys.map((k) => { const jwk = k.publicJwk ?? k const { ...pub } = jwk return pub }) } }) .get('/api/health', () => { const dnsVerifierHealth = dnsVerifier.getHealth() return { status: 'ok', timestamp: new Date().toISOString(), dnsVerifier: dnsVerifierHealth } }) .get('/api/admin/test', () => { return { message: 'Admin routes test works!' } }) .post('/api/admin/verify-dns', async () => { try { await dnsVerifier.trigger() return { success: true, message: 'DNS verification triggered' } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) } } }) .get('/.well-known/atproto-did', ({ set }) => { // Return plain text DID for AT Protocol domain verification set.headers['Content-Type'] = 'text/plain' return 'did:plc:7puq73yz2hkvbcpdhnsze2qw' }) .use(cors({ origin: config.domain, credentials: true, methods: ['GET', 'POST', 'DELETE', 'PUT', 'PATCH', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'Origin', 'X-Forwarded-Host'], exposeHeaders: ['Content-Type'], maxAge: 86400 // 24 hours })) .listen(8000)
console.log( `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`)