feat: add chat
This commit is contained in:
@@ -69,6 +69,7 @@ type Server struct {
|
||||
relationH *handler.RelationshipHandler
|
||||
soketiWebhookH *handler.SoketiWebhookHandler
|
||||
broadcastAuthH *handler.BroadcastingAuthHandler
|
||||
chatH *handler.ChatHandler
|
||||
notificationH *handler.NotificationHandler
|
||||
sadhnaH *handler.SadhnaHandler
|
||||
pushH *handler.PushHandler
|
||||
@@ -112,10 +113,10 @@ func New(cfg *config.Config, logger *zap.Logger) *Server {
|
||||
discipleRepo: discipleRepo,
|
||||
|
||||
// Initialize handlers
|
||||
bookH: handler.NewBookHandler(bookRepo),
|
||||
letterH: handler.NewLetterHandler(letterRepo),
|
||||
essayH: handler.NewEssayHandler(essayRepo),
|
||||
glossaryH: handler.NewGlossaryHandler(glossaryRepo),
|
||||
bookH: handler.NewBookHandler(bookRepo),
|
||||
letterH: handler.NewLetterHandler(letterRepo),
|
||||
essayH: handler.NewEssayHandler(essayRepo),
|
||||
glossaryH: handler.NewGlossaryHandler(glossaryRepo),
|
||||
// userRepo half is attached later in initAuth (Postgres isn't up yet).
|
||||
discipleH: handler.NewDiscipleHandler(discipleRepo, nil),
|
||||
journalH: handler.NewJournalHandler(journalRepo),
|
||||
@@ -258,10 +259,16 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
|
||||
cfg.SoketiAppID, cfg.SoketiAppKey, cfg.SoketiAppSecret,
|
||||
cfg.SoketiHost, cfg.SoketiPort, cfg.SoketiUseTLS, logger,
|
||||
)
|
||||
// Chat — DMs, groups and the (still coming-soon) Kautilya threads.
|
||||
chatRepo := repository.NewChatRepo(s.pg)
|
||||
chatSvc := service.NewChatService(chatRepo, blockRepo, rtClient, r2, s.redis, logger)
|
||||
s.chatH = handler.NewChatHandler(chatSvc)
|
||||
|
||||
// Channel authorization for private-* subscriptions. Rules are explicit
|
||||
// and default-deny; chat conversation channels get added here.
|
||||
// and default-deny — an unlisted channel is refused.
|
||||
s.broadcastAuthH = handler.NewBroadcastingAuthHandler(rtClient, logger,
|
||||
handler.NotificationsRule(),
|
||||
handler.ConversationRule(chatSvc.IsParticipant),
|
||||
)
|
||||
|
||||
pushRepo := repository.NewPushRepo(s.pg)
|
||||
@@ -296,7 +303,7 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
|
||||
// every 15 minutes (no-op when Redis is unavailable).
|
||||
worker.NewLikesWorker(likeRepo, logger).Run(wctx)
|
||||
|
||||
graphSvc := service.NewSocialGraphService(followRepo, blockRepo, reportRepo, postRepo, userRepo, notifSvc, mail, cfg.FeedbackAdminEmails, logger)
|
||||
graphSvc := service.NewSocialGraphService(followRepo, blockRepo, reportRepo, postRepo, userRepo, chatRepo, notifSvc, mail, cfg.FeedbackAdminEmails, logger)
|
||||
s.relationH = handler.NewRelationshipHandler(graphSvc)
|
||||
s.notificationH = handler.NewNotificationHandler(notifSvc)
|
||||
s.postH = handler.NewPostHandler(postSvc, graphSvc)
|
||||
@@ -895,6 +902,46 @@ func (s *Server) setupRouter() {
|
||||
r.Post("/webhooks/soketi", s.soketiWebhookH.Handle)
|
||||
}
|
||||
|
||||
// Chat — inbox, threads, messages. Every route requires a session;
|
||||
// membership is re-checked per request in the service, so a
|
||||
// conversation id on its own grants nothing.
|
||||
if s.chatH != nil {
|
||||
r.Route("/chat", func(r chi.Router) {
|
||||
r.Use(middleware.RequireAuth(s.authIssuer, s.userRepo))
|
||||
r.Get("/conversations", s.chatH.Inbox)
|
||||
r.Post("/conversations/dm", s.chatH.OpenDM)
|
||||
r.Post("/conversations/group", s.chatH.CreateGroup)
|
||||
r.Post("/conversations/kautilya", s.chatH.OpenAIThread)
|
||||
r.Post("/link-preview", s.chatH.LinkPreview)
|
||||
r.Get("/settings", s.chatH.Settings)
|
||||
r.Patch("/settings", s.chatH.UpdateSettings)
|
||||
r.Get("/attachments/{attachmentID}", s.chatH.Attachment)
|
||||
r.Route("/conversations/{id}", func(r chi.Router) {
|
||||
r.Get("/", s.chatH.Detail)
|
||||
r.Patch("/", s.chatH.UpdateGroup)
|
||||
r.Post("/members", s.chatH.AddMembers)
|
||||
r.Delete("/members/{handle}", s.chatH.RemoveMember)
|
||||
r.Patch("/members/{handle}", s.chatH.SetMemberRole)
|
||||
r.Get("/messages", s.chatH.Messages)
|
||||
r.Post("/messages", s.chatH.Send)
|
||||
r.Post("/read", s.chatH.MarkRead)
|
||||
r.Post("/delivered", s.chatH.MarkDelivered)
|
||||
r.Get("/receipts", s.chatH.Receipts)
|
||||
r.Post("/mute", s.chatH.SetMute)
|
||||
r.Post("/attachments/presign", s.chatH.PresignAttachment)
|
||||
r.Post("/avatar/presign", s.chatH.PresignGroupAvatar)
|
||||
r.Get("/avatar", s.chatH.GroupAvatar)
|
||||
r.Get("/gallery", s.chatH.Gallery)
|
||||
r.Get("/starred", s.chatH.Starred)
|
||||
r.Post("/messages/{messageID}/star", s.chatH.Star)
|
||||
r.Delete("/messages/{messageID}/star", s.chatH.Unstar)
|
||||
r.Delete("/messages/{messageID}", s.chatH.DeleteMessage)
|
||||
r.Post("/messages/{messageID}/report", s.chatH.ReportMessage)
|
||||
r.Post("/forward", s.chatH.Forward)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Pusher channel authorization — pusher-js posts here (as its
|
||||
// `authEndpoint`) before subscribing to a private-/presence- channel.
|
||||
// Session-authenticated: the signature is only minted for a caller
|
||||
|
||||
Reference in New Issue
Block a user