feat(05-04): push subscription API + VAPID startup wiring
- Create apps/api/src/routes/push.ts: GET /vapid-public-key, POST /subscription (upsert), DELETE /subscription (user-scoped) - Wire pushRouter at /api/push in index.ts - Call webpush.setVapidDetails() in isMainModule() guard before serve() - Fix broken vi.getMockImplementation scaffold bug in push.test.ts (Rule 1) - push.test.ts: all 4 tests GREEN
This commit is contained in:
@@ -8,10 +8,12 @@ import { meRouter } from './routes/me.js'
|
||||
import { eventsRouter } from './routes/events.js'
|
||||
import { sseRouter } from './routes/sse.js'
|
||||
import { listsRouter, listItemsRouter } from './routes/lists.js'
|
||||
import { pushRouter } from './routes/push.js'
|
||||
import { oidcAuthMiddleware, processOAuthCallback } from './auth/middleware.js'
|
||||
import { devAuthBypass } from './auth/devBypass.js'
|
||||
import { startBrokerPoller } from './broker/poller.js'
|
||||
import { startOutboxWorker } from './broker/outboxWorker.js'
|
||||
import webpush from 'web-push'
|
||||
|
||||
export const app = new Hono()
|
||||
|
||||
@@ -64,6 +66,7 @@ app.route('/api/events', eventsRouter)
|
||||
app.route('/api/sse', sseRouter)
|
||||
app.route('/api/lists', listsRouter)
|
||||
app.route('/api/list-items', listItemsRouter)
|
||||
app.route('/api/push', pushRouter)
|
||||
|
||||
// WR-04: background worker startup (cron schedules) moved into the isMainModule()
|
||||
// guard below. Calling them at top level registered real node-cron schedules whenever
|
||||
@@ -105,6 +108,18 @@ function isMainModule(): boolean {
|
||||
// (not imported in tests). WR-04: gating the cron schedules here keeps them out of the
|
||||
// test process.
|
||||
if (isMainModule()) {
|
||||
// Configure VAPID credentials for web-push before starting background workers.
|
||||
// VAPID_SUBJECT must be a mailto: or https: URL identifying the operator.
|
||||
// The private key is NEVER served to clients; it signs push requests server-side only.
|
||||
const vapidSubject = process.env.VAPID_SUBJECT ?? ''
|
||||
const vapidPublicKey = process.env.VAPID_PUBLIC_KEY ?? ''
|
||||
const vapidPrivateKey = process.env.VAPID_PRIVATE_KEY ?? ''
|
||||
if (vapidSubject && vapidPublicKey && vapidPrivateKey) {
|
||||
webpush.setVapidDetails(vapidSubject, vapidPublicKey, vapidPrivateKey)
|
||||
} else {
|
||||
console.warn('[startup] VAPID env vars not set — push notifications will fail. Set VAPID_SUBJECT, VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY.')
|
||||
}
|
||||
|
||||
// Start the CalDAV broker poller (5-min cron, D-13 ctag change-detection).
|
||||
// Runs in the background — errors are caught and logged per-credential (T-03-04).
|
||||
startBrokerPoller()
|
||||
|
||||
Reference in New Issue
Block a user