Complete WebAuthn backend + push notification mention parsing

Backend:
- internal/auth/webauthn.go: full RegisterBegin/Finish, LoginBegin/Finish implementation
  - In-memory challenge store with eviction
  - Credential storage in webauthn_credentials table
  - Session creation on successful passkey login
  - Cookie-based challenge linking for login flow
- internal/message/mentions.go: @mention parsing and push notification dispatch
  - Parses @user, @everyone, @role mentions
  - Skips DND users
  - Async goroutine dispatch for non-blocking
- internal/message/handlers.go: wired mention handler into Create
- cmd/server/main.go: added push handler initialization, pass to message handler
This commit is contained in:
2026-06-28 19:06:03 -04:00
parent 0f99ee53bc
commit 613d4b8c6e
4 changed files with 576 additions and 227 deletions
+8 -1
View File
@@ -18,6 +18,7 @@ import (
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/invite"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/message"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/middleware"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/push"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/reaction"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/server"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/upload"
@@ -76,6 +77,12 @@ func main() {
logger.Warn("voice client not configured (missing LIVEKIT_API_KEY/SECRET)")
}
// Push notification handler (nil if no VAPID keys)
pushHandler := push.NewHandler(database.DB, cfg.WebPush.PublicKey, cfg.WebPush.PrivateKey, cfg.WebPush.Subject, logger)
if cfg.WebPush.PublicKey == "" {
logger.Warn("push notifications not configured (missing VAPID_PUBLIC_KEY)")
}
// Auth handler
authHandler := auth.NewHandler(database.DB, cfg)
@@ -122,7 +129,7 @@ func main() {
// Messages (under channels)
r.Route("/channels/{channelID}/messages", func(r chi.Router) {
message.NewHandler(database.DB, hub).RegisterRoutes(r)
message.NewHandler(database.DB, hub, pushHandler, logger).RegisterRoutes(r)
})
// Giphy search