From e8139ad655da9d60a263ecb2a1c8cafa46b25a81 Mon Sep 17 00:00:00 2001
From: binwiederhier <philipp.heckel@gmail.com>
Date: Tue, 30 May 2023 14:42:17 -0400
Subject: [PATCH] Move web-push-config endpoint to config.js

---
 server/server.go               | 13 ++-----------
 server/server_web_push_test.go |  9 ---------
 server/types.go                |  6 ++----
 web/public/config.js           |  2 ++
 web/src/app/Api.js             | 24 +++---------------------
 web/src/app/Notifier.js        | 13 ++-----------
 web/src/app/utils.js           |  1 -
 7 files changed, 11 insertions(+), 57 deletions(-)

diff --git a/server/server.go b/server/server.go
index 35d6f47d..12ccee5c 100644
--- a/server/server.go
+++ b/server/server.go
@@ -104,7 +104,6 @@ var (
 	apiAccountBillingSubscriptionCheckoutSuccessTemplate = "/v1/account/billing/subscription/success/{CHECKOUT_SESSION_ID}"
 	apiAccountBillingSubscriptionCheckoutSuccessRegex    = regexp.MustCompile(`/v1/account/billing/subscription/success/(.+)$`)
 	apiAccountReservationSingleRegex                     = regexp.MustCompile(`/v1/account/reservation/([-_A-Za-z0-9]{1,64})$`)
-	apiWebPushConfig                                     = "/v1/web-push-config"
 	staticRegex                                          = regexp.MustCompile(`^/static/.+`)
 	docsRegex                                            = regexp.MustCompile(`^/docs(|/.*)$`)
 	fileRegex                                            = regexp.MustCompile(`^/file/([-_A-Za-z0-9]{1,64})(?:\.[A-Za-z0-9]{1,16})?$`)
@@ -496,8 +495,6 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
 		return s.handleStats(w, r, v)
 	} else if r.Method == http.MethodGet && r.URL.Path == apiTiersPath {
 		return s.ensurePaymentsEnabled(s.handleBillingTiersGet)(w, r, v)
-	} else if r.Method == http.MethodGet && r.URL.Path == apiWebPushConfig {
-		return s.ensureWebPushEnabled(s.handleAPIWebPushConfig)(w, r, v)
 	} else if r.Method == http.MethodGet && r.URL.Path == matrixPushPath {
 		return s.handleMatrixDiscovery(w)
 	} else if r.Method == http.MethodGet && r.URL.Path == metricsPath && s.metricsHandler != nil {
@@ -563,14 +560,6 @@ func (s *Server) handleTopicAuth(w http.ResponseWriter, _ *http.Request, _ *visi
 	return s.writeJSON(w, newSuccessResponse())
 }
 
-func (s *Server) handleAPIWebPushConfig(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
-	response := &apiWebPushConfigResponse{
-		PublicKey: s.config.WebPushPublicKey,
-	}
-
-	return s.writeJSON(w, response)
-}
-
 func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
 	response := &apiHealthResponse{
 		Healthy: true,
@@ -588,7 +577,9 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visi
 		EnableCalls:        s.config.TwilioAccount != "",
 		EnableEmails:       s.config.SMTPSenderFrom != "",
 		EnableReservations: s.config.EnableReservations,
+		EnableWebPush:      s.config.WebPushEnabled,
 		BillingContact:     s.config.BillingContact,
+		WebPushPublicKey:   s.config.WebPushPublicKey,
 		DisallowedTopics:   s.config.DisallowedTopics,
 	}
 	b, err := json.MarshalIndent(response, "", "  ")
diff --git a/server/server_web_push_test.go b/server/server_web_push_test.go
index 56936529..e6dda63e 100644
--- a/server/server_web_push_test.go
+++ b/server/server_web_push_test.go
@@ -1,7 +1,6 @@
 package server
 
 import (
-	"fmt"
 	"io"
 	"net/http"
 	"net/http/httptest"
@@ -27,14 +26,6 @@ var (
 	}`
 )
 
-func TestServer_WebPush_GetConfig(t *testing.T) {
-	s := newTestServer(t, newTestConfigWithWebPush(t))
-
-	response := request(t, s, "GET", "/v1/web-push-config", "", nil)
-	require.Equal(t, 200, response.Code)
-	require.Equal(t, fmt.Sprintf(`{"public_key":"%s"}`, s.config.WebPushPublicKey)+"\n", response.Body.String())
-}
-
 func TestServer_WebPush_TopicSubscribe(t *testing.T) {
 	s := newTestServer(t, newTestConfigWithWebPush(t))
 
diff --git a/server/types.go b/server/types.go
index bac4a478..9f436152 100644
--- a/server/types.go
+++ b/server/types.go
@@ -398,14 +398,12 @@ type apiConfigResponse struct {
 	EnableCalls        bool     `json:"enable_calls"`
 	EnableEmails       bool     `json:"enable_emails"`
 	EnableReservations bool     `json:"enable_reservations"`
+	EnableWebPush      bool     `json:"enable_web_push"`
 	BillingContact     string   `json:"billing_contact"`
+	WebPushPublicKey   string   `json:"web_push_public_key"`
 	DisallowedTopics   []string `json:"disallowed_topics"`
 }
 
-type apiWebPushConfigResponse struct {
-	PublicKey string `json:"public_key"`
-}
-
 type apiAccountBillingPrices struct {
 	Month int64 `json:"month"`
 	Year  int64 `json:"year"`
diff --git a/web/public/config.js b/web/public/config.js
index 7bcad73f..63bc97bd 100644
--- a/web/public/config.js
+++ b/web/public/config.js
@@ -14,6 +14,8 @@ var config = {
   enable_reservations: true,
   enable_emails: true,
   enable_calls: true,
+  enable_web_push: true,
   billing_contact: "",
+  web_push_public_key: "",
   disallowed_topics: ["docs", "static", "file", "app", "account", "settings", "signup", "login", "v1"],
 };
diff --git a/web/src/app/Api.js b/web/src/app/Api.js
index f731e61f..c3effb92 100644
--- a/web/src/app/Api.js
+++ b/web/src/app/Api.js
@@ -8,7 +8,6 @@ import {
   topicUrlJsonPollWithSince,
   topicUrlWebPushSubscribe,
   topicUrlWebPushUnsubscribe,
-  webPushConfigUrl,
 } from "./utils";
 import userManager from "./UserManager";
 import { fetchOrThrow } from "./errors";
@@ -117,27 +116,8 @@ class Api {
     throw new Error(`Unexpected server response ${response.status}`);
   }
 
-  /**
-   * @returns {Promise<{ public_key: string } | undefined>}
-   */
-  async getWebPushConfig(baseUrl) {
-    const response = await fetch(webPushConfigUrl(baseUrl));
-
-    if (response.ok) {
-      return response.json();
-    }
-
-    if (response.status === 404) {
-      // web push is not enabled
-      return undefined;
-    }
-
-    throw new Error(`Unexpected server response ${response.status}`);
-  }
-
   async subscribeWebPush(baseUrl, topic, browserSubscription) {
     const user = await userManager.get(baseUrl);
-
     const url = topicUrlWebPushSubscribe(baseUrl, topic);
     console.log(`[Api] Sending Web Push Subscription ${url}`);
 
@@ -163,7 +143,9 @@ class Api {
     const response = await fetch(url, {
       method: "POST",
       headers: maybeWithAuth({}, user),
-      body: JSON.stringify({ endpoint: subscription.webPushEndpoint }),
+      body: JSON.stringify({
+        endpoint: subscription.webPushEndpoint
+      }),
     });
 
     if (response.ok) {
diff --git a/web/src/app/Notifier.js b/web/src/app/Notifier.js
index a005f460..c9e3c182 100644
--- a/web/src/app/Notifier.js
+++ b/web/src/app/Notifier.js
@@ -53,7 +53,7 @@ class Notifier {
   }
 
   async subscribeWebPush(baseUrl, topic) {
-    if (!this.supported() || !this.pushSupported()) {
+    if (!this.supported() || !this.pushSupported() || !config.enable_web_push) {
       return {};
     }
 
@@ -71,21 +71,12 @@ class Notifier {
     }
 
     try {
-      const webPushConfig = await api.getWebPushConfig(baseUrl);
-
-      if (!webPushConfig) {
-        console.log("[Notifier.subscribeWebPush] Web push not configured on server");
-      }
-
       const browserSubscription = await registration.pushManager.subscribe({
         userVisibleOnly: true,
-        applicationServerKey: urlB64ToUint8Array(webPushConfig.public_key),
+        applicationServerKey: urlB64ToUint8Array(config.web_push_public_key),
       });
-
       await api.subscribeWebPush(baseUrl, topic, browserSubscription);
-
       console.log("[Notifier.subscribeWebPush] Successfully subscribed to web push");
-
       return browserSubscription;
     } catch (e) {
       console.error("[Notifier.subscribeWebPush] Error subscribing to web push", e);
diff --git a/web/src/app/utils.js b/web/src/app/utils.js
index bf09bef3..69132b2e 100644
--- a/web/src/app/utils.js
+++ b/web/src/app/utils.js
@@ -23,7 +23,6 @@ export const topicUrlAuth = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/aut
 export const topicUrlWebPushSubscribe = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/web-push/subscribe`;
 export const topicUrlWebPushUnsubscribe = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/web-push/unsubscribe`;
 export const topicShortUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic));
-export const webPushConfigUrl = (baseUrl) => `${baseUrl}/v1/web-push-config`;
 export const accountUrl = (baseUrl) => `${baseUrl}/v1/account`;
 export const accountPasswordUrl = (baseUrl) => `${baseUrl}/v1/account/password`;
 export const accountTokenUrl = (baseUrl) => `${baseUrl}/v1/account/token`;