diff --git a/docker-compose.yml b/docker-compose.yml index d0d73db..08e94ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,7 +35,7 @@ services: # environment: # - LOG_LEVEL=info - network_mode: bridge + # Resource limits (optional) deploy: diff --git a/pkg/handlers/static.go b/pkg/handlers/static.go index eeab97a..e287b3f 100644 --- a/pkg/handlers/static.go +++ b/pkg/handlers/static.go @@ -31,6 +31,20 @@ func (h *Handlers) ServeIndex(w http.ResponseWriter, r *http.Request) { writeBytes(w, content) } +// ServePrivacyPolicy serves the privacy policy page +func (h *Handlers) ServePrivacyPolicy(w http.ResponseWriter, r *http.Request) { + content, err := staticFiles.ReadFile("static/privacy-policy.html") + if err != nil { + logging.Error("Failed to read privacy-policy.html", "error", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + writeBytes(w, content) +} + // ServeStatic serves static files (logo, etc.) func (h *Handlers) ServeStatic(w http.ResponseWriter, r *http.Request) { // Get the file path from URL @@ -53,6 +67,8 @@ func (h *Handlers) ServeStatic(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "image/jpeg") case ".svg": w.Header().Set("Content-Type", "image/svg+xml") + case ".html": + w.Header().Set("Content-Type", "text/html; charset=utf-8") case ".css": w.Header().Set("Content-Type", "text/css") case ".js": diff --git a/pkg/handlers/static/index.html b/pkg/handlers/static/index.html index 934adf4..12fe3bc 100644 --- a/pkg/handlers/static/index.html +++ b/pkg/handlers/static/index.html @@ -564,7 +564,7 @@ diff --git a/pkg/handlers/static/privacy-policy.html b/pkg/handlers/static/privacy-policy.html new file mode 100644 index 0000000..e3db877 --- /dev/null +++ b/pkg/handlers/static/privacy-policy.html @@ -0,0 +1,184 @@ + + + + + + Privacy Policy - WhatsHooked + + + +
+
+

WhatsHooked

+

Privacy Policy

+
+ +
+

No customer data is collected, stored, or saved by WhatsHooked. Messages are forwarded in real time and are not retained on our servers.

+

Our use of the Meta API is limited exclusively to WhatsApp Business messaging.

+
+ +
+

What We Do Not Collect

+

WhatsHooked does not save, log, or persist any customer data. This includes, but is not limited to:

+ +
+ +
+

How WhatsApp Messages Are Handled

+

WhatsHooked acts as a bridge between WhatsApp and your configured webhook endpoints. Incoming messages are received and forwarded to your endpoints in real time. No message content is stored or cached beyond what is necessary for the immediate delivery.

+
+ +
+

Use of the Meta API

+

WhatsHooked integrates with the Meta (WhatsApp Business) API solely for the purpose of sending and receiving WhatsApp Business messages. The API access is not used for any other purpose, including but not limited to:

+ +
+ +
+

Your Responsibilities

+

As the operator of a WhatsHooked instance, you are responsible for ensuring that your use of the platform complies with applicable privacy laws and Meta's terms of service. WhatsHooked provides the infrastructure; the data handling obligations rest with you as the account owner.

+
+ +
+

Changes to This Policy

+

This privacy policy may be updated at any time. Changes will be reflected on this page. Continued use of WhatsHooked after an update constitutes acceptance of the revised policy.

+
+ + +
+ + diff --git a/pkg/whatshooked/server.go b/pkg/whatshooked/server.go index 86f6298..742ce4e 100644 --- a/pkg/whatshooked/server.go +++ b/pkg/whatshooked/server.go @@ -207,6 +207,9 @@ func (s *Server) setupRoutes() *http.ServeMux { // Landing page (no auth required) mux.HandleFunc("/", h.ServeIndex) + // Privacy policy (no auth required) + mux.HandleFunc("/privacy-policy", h.ServePrivacyPolicy) + // Static files (no auth required) mux.HandleFunc("/static/", h.ServeStatic)