diff --git a/README.md b/README.md index 4a523de..ab17dce 100644 --- a/README.md +++ b/README.md @@ -205,14 +205,14 @@ curl -X POST http://localhost:8080/my-app \ ### WebPush/Webhook Management -#### POST /webpush/app +#### POST /api/v1/webpush/app Register or update a WebPush subscription or plain webhook. Encrypted WebPush (all crypto fields required): ```bash -curl -X POST http://localhost:8080/webpush/app \ +curl -X POST http://localhost:8080/api/v1/webpush/app \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ @@ -227,7 +227,7 @@ curl -X POST http://localhost:8080/webpush/app \ Plain HTTP webhook (no encryption): ```bash -curl -X POST http://localhost:8080/webpush/app \ +curl -X POST http://localhost:8080/api/v1/webpush/app \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ @@ -236,12 +236,12 @@ curl -X POST http://localhost:8080/webpush/app \ }' ``` -#### DELETE /webpush/app/{appName} +#### DELETE /api/v1/webpush/app/{appName} Unregister a WebPush subscription (clears WebPush settings, reverts to Signal). ```bash -curl -X DELETE http://localhost:8080/webpush/app/my-app \ +curl -X DELETE http://localhost:8080/api/v1/webpush/app/my-app \ -H "Authorization: Bearer YOUR_API_KEY" ``` @@ -257,12 +257,12 @@ Public health check endpoint (no authentication required). Returns `200 OK` when curl http://localhost:8080/health ``` -#### GET /api/health +#### GET /api/v1/health Detailed health endpoint (requires authentication). Returns JSON with uptime and integration status: ```bash -curl http://localhost:8080/api/health \ +curl http://localhost:8080/api/v1/health \ -H "Authorization: Bearer YOUR_API_KEY" ``` diff --git a/VERSION b/VERSION index 72f9fa8..9325c3c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.4 \ No newline at end of file +0.3.0 \ No newline at end of file diff --git a/public/integration.js b/public/integration.js index a74d59b..9af2649 100644 --- a/public/integration.js +++ b/public/integration.js @@ -54,7 +54,7 @@ async function handleAuthForm(form, endpoint, statusId, getPayload) { async function submitTelegramAuth(e) { await handleAuthForm( e.target, - '/api/telegram/auth', + '/api/v1/telegram/auth', 'telegram-auth-status', (fd) => ({ bot_token: fd.get('bot_token'), @@ -66,7 +66,7 @@ async function submitTelegramAuth(e) { async function submitTelegramChatId(e) { await handleAuthForm( e.target, - '/api/telegram/auth', + '/api/v1/telegram/auth', 'telegram-chatid-status', (fd, form) => ({ bot_token: form.dataset.botToken, @@ -78,7 +78,7 @@ async function submitTelegramChatId(e) { async function submitProtonAuth(e) { await handleAuthForm( e.target, - '/api/proton/auth', + '/api/v1/proton/auth', 'proton-auth-status', (fd) => ({ email: fd.get('email'), @@ -103,7 +103,7 @@ async function linkSignal(btn) { qrContainer.style.display = 'none'; try { - const response = await fetch('/api/signal/link', { + const response = await fetch('/api/v1/signal/link', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ device_name: 'Prism' }), @@ -122,7 +122,7 @@ async function linkSignal(btn) { signalLinkingPoll = setInterval(async () => { try { - const statusResp = await fetch('/api/signal/status'); + const statusResp = await fetch('/api/v1/signal/status'); const statusData = await statusResp.json(); if (statusData.linked) { @@ -146,7 +146,7 @@ async function deleteTelegram(btn) { btn.disabled = true; try { - const response = await fetch('/api/telegram/auth', { method: 'DELETE' }); + const response = await fetch('/api/v1/telegram/auth', { method: 'DELETE' }); if (response.ok) { location.reload(); @@ -167,7 +167,7 @@ async function deleteProton(btn) { btn.disabled = true; try { - const response = await fetch('/api/proton/auth', { method: 'DELETE' }); + const response = await fetch('/api/v1/proton/auth', { method: 'DELETE' }); if (response.ok) { location.reload(); diff --git a/service/integration/proton/messages.go b/service/integration/proton/messages.go index f52f1a4..2ccc780 100644 --- a/service/integration/proton/messages.go +++ b/service/integration/proton/messages.go @@ -83,7 +83,7 @@ func (m *Monitor) sendNotification(msg *protonmail.Message) { { ID: "archive", Label: "Archive", - Endpoint: "/api/proton/archive", + Endpoint: "/api/v1/proton/archive", Method: "POST", Data: map[string]any{ "uid": msg.ID, @@ -92,7 +92,7 @@ func (m *Monitor) sendNotification(msg *protonmail.Message) { { ID: "mark-read", Label: "Mark as Read", - Endpoint: "/api/proton/mark-read", + Endpoint: "/api/v1/proton/mark-read", Method: "POST", Data: map[string]any{ "uid": msg.ID, diff --git a/service/integration/proton/routes.go b/service/integration/proton/routes.go index 499537d..fedeee9 100644 --- a/service/integration/proton/routes.go +++ b/service/integration/proton/routes.go @@ -175,7 +175,7 @@ func RegisterRoutes(router *chi.Mux, handlers *Handlers, auth func(http.Handler) router.With(auth).Get("/fragment/proton", handlers.HandleFragment) - router.Route("/api/proton", func(r chi.Router) { + router.Route("/api/v1/proton", func(r chi.Router) { r.Use(auth) r.Post("/mark-read", handlers.HandleMarkRead) r.Post("/archive", handlers.HandleArchive) diff --git a/service/integration/signal/routes.go b/service/integration/signal/routes.go index 45a7efa..1da006c 100644 --- a/service/integration/signal/routes.go +++ b/service/integration/signal/routes.go @@ -22,8 +22,8 @@ func RegisterRoutes(router *chi.Mux, cfg *config.Config, authMiddleware func(htt handlers := NewHandlers(client, tmpl, logger) router.With(authMiddleware).Get("/fragment/signal", handlers.HandleFragment) - router.With(authMiddleware).Post("/api/signal/link", handlers.HandleLinkDevice) - router.With(authMiddleware).Get("/api/signal/status", handlers.HandleLinkStatus) + router.With(authMiddleware).Post("/api/v1/signal/link", handlers.HandleLinkDevice) + router.With(authMiddleware).Get("/api/v1/signal/status", handlers.HandleLinkStatus) return handlers } diff --git a/service/integration/telegram/routes.go b/service/integration/telegram/routes.go index 7dfd064..9703f34 100644 --- a/service/integration/telegram/routes.go +++ b/service/integration/telegram/routes.go @@ -89,6 +89,6 @@ func RegisterRoutes(router *chi.Mux, handlers *Handlers, auth func(http.Handler) authH := &authHandler{db: db, apiKey: apiKey, logger: logger} router.With(auth).Get("/fragment/telegram", handlers.HandleFragment) - router.With(auth).Post("/api/telegram/auth", authH.handleAuth) - router.With(auth).Delete("/api/telegram/auth", authH.handleDelete) + router.With(auth).Post("/api/v1/telegram/auth", authH.handleAuth) + router.With(auth).Delete("/api/v1/telegram/auth", authH.handleDelete) } diff --git a/service/integration/webpush/routes.go b/service/integration/webpush/routes.go index 72b268d..aa648d9 100644 --- a/service/integration/webpush/routes.go +++ b/service/integration/webpush/routes.go @@ -12,7 +12,7 @@ import ( func RegisterRoutes(router *chi.Mux, store *notification.Store, logger *slog.Logger, authMiddleware func(http.Handler) http.Handler) { handlers := NewHandlers(store, logger) - router.Route("/webpush/app", func(r chi.Router) { + router.Route("/api/v1/webpush/app", func(r chi.Router) { r.Use(authMiddleware) r.Post("/", handlers.HandleRegister) r.Delete("/{appName}", handlers.HandleUnregister) diff --git a/service/server/server.go b/service/server/server.go index 7fd58de..168e623 100644 --- a/service/server/server.go +++ b/service/server/server.go @@ -121,7 +121,7 @@ func (s *Server) setupRoutes() { r.Post("/toggle-channel", s.handleToggleChannelAction) }) - r.Route("/api/admin", func(r chi.Router) { + r.Route("/api/v1/admin", func(r chi.Router) { r.Use(authMiddleware(s.cfg.APIKey)) r.Get("/mappings", s.handleGetMappings) r.Post("/mappings", s.handleCreateMapping) @@ -130,7 +130,7 @@ func (s *Server) setupRoutes() { r.Get("/stats", s.handleGetStats) }) - r.With(authMiddleware(s.cfg.APIKey)).Get("/api/health", s.handleHealth) + r.With(authMiddleware(s.cfg.APIKey)).Get("/api/v1/health", s.handleHealth) r.With(authMiddleware(s.cfg.APIKey)).Post("/{appName}", s.handleNtfyPublish)