Move web-push-config endpoint to config.js
parent
9e0687e142
commit
e8139ad655
|
@ -104,7 +104,6 @@ var (
|
||||||
apiAccountBillingSubscriptionCheckoutSuccessTemplate = "/v1/account/billing/subscription/success/{CHECKOUT_SESSION_ID}"
|
apiAccountBillingSubscriptionCheckoutSuccessTemplate = "/v1/account/billing/subscription/success/{CHECKOUT_SESSION_ID}"
|
||||||
apiAccountBillingSubscriptionCheckoutSuccessRegex = regexp.MustCompile(`/v1/account/billing/subscription/success/(.+)$`)
|
apiAccountBillingSubscriptionCheckoutSuccessRegex = regexp.MustCompile(`/v1/account/billing/subscription/success/(.+)$`)
|
||||||
apiAccountReservationSingleRegex = regexp.MustCompile(`/v1/account/reservation/([-_A-Za-z0-9]{1,64})$`)
|
apiAccountReservationSingleRegex = regexp.MustCompile(`/v1/account/reservation/([-_A-Za-z0-9]{1,64})$`)
|
||||||
apiWebPushConfig = "/v1/web-push-config"
|
|
||||||
staticRegex = regexp.MustCompile(`^/static/.+`)
|
staticRegex = regexp.MustCompile(`^/static/.+`)
|
||||||
docsRegex = regexp.MustCompile(`^/docs(|/.*)$`)
|
docsRegex = regexp.MustCompile(`^/docs(|/.*)$`)
|
||||||
fileRegex = regexp.MustCompile(`^/file/([-_A-Za-z0-9]{1,64})(?:\.[A-Za-z0-9]{1,16})?$`)
|
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)
|
return s.handleStats(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && r.URL.Path == apiTiersPath {
|
} else if r.Method == http.MethodGet && r.URL.Path == apiTiersPath {
|
||||||
return s.ensurePaymentsEnabled(s.handleBillingTiersGet)(w, r, v)
|
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 {
|
} else if r.Method == http.MethodGet && r.URL.Path == matrixPushPath {
|
||||||
return s.handleMatrixDiscovery(w)
|
return s.handleMatrixDiscovery(w)
|
||||||
} else if r.Method == http.MethodGet && r.URL.Path == metricsPath && s.metricsHandler != nil {
|
} 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())
|
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 {
|
func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
||||||
response := &apiHealthResponse{
|
response := &apiHealthResponse{
|
||||||
Healthy: true,
|
Healthy: true,
|
||||||
|
@ -588,7 +577,9 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visi
|
||||||
EnableCalls: s.config.TwilioAccount != "",
|
EnableCalls: s.config.TwilioAccount != "",
|
||||||
EnableEmails: s.config.SMTPSenderFrom != "",
|
EnableEmails: s.config.SMTPSenderFrom != "",
|
||||||
EnableReservations: s.config.EnableReservations,
|
EnableReservations: s.config.EnableReservations,
|
||||||
|
EnableWebPush: s.config.WebPushEnabled,
|
||||||
BillingContact: s.config.BillingContact,
|
BillingContact: s.config.BillingContact,
|
||||||
|
WebPushPublicKey: s.config.WebPushPublicKey,
|
||||||
DisallowedTopics: s.config.DisallowedTopics,
|
DisallowedTopics: s.config.DisallowedTopics,
|
||||||
}
|
}
|
||||||
b, err := json.MarshalIndent(response, "", " ")
|
b, err := json.MarshalIndent(response, "", " ")
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"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) {
|
func TestServer_WebPush_TopicSubscribe(t *testing.T) {
|
||||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||||
|
|
||||||
|
|
|
@ -398,14 +398,12 @@ type apiConfigResponse struct {
|
||||||
EnableCalls bool `json:"enable_calls"`
|
EnableCalls bool `json:"enable_calls"`
|
||||||
EnableEmails bool `json:"enable_emails"`
|
EnableEmails bool `json:"enable_emails"`
|
||||||
EnableReservations bool `json:"enable_reservations"`
|
EnableReservations bool `json:"enable_reservations"`
|
||||||
|
EnableWebPush bool `json:"enable_web_push"`
|
||||||
BillingContact string `json:"billing_contact"`
|
BillingContact string `json:"billing_contact"`
|
||||||
|
WebPushPublicKey string `json:"web_push_public_key"`
|
||||||
DisallowedTopics []string `json:"disallowed_topics"`
|
DisallowedTopics []string `json:"disallowed_topics"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiWebPushConfigResponse struct {
|
|
||||||
PublicKey string `json:"public_key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiAccountBillingPrices struct {
|
type apiAccountBillingPrices struct {
|
||||||
Month int64 `json:"month"`
|
Month int64 `json:"month"`
|
||||||
Year int64 `json:"year"`
|
Year int64 `json:"year"`
|
||||||
|
|
|
@ -14,6 +14,8 @@ var config = {
|
||||||
enable_reservations: true,
|
enable_reservations: true,
|
||||||
enable_emails: true,
|
enable_emails: true,
|
||||||
enable_calls: true,
|
enable_calls: true,
|
||||||
|
enable_web_push: true,
|
||||||
billing_contact: "",
|
billing_contact: "",
|
||||||
|
web_push_public_key: "",
|
||||||
disallowed_topics: ["docs", "static", "file", "app", "account", "settings", "signup", "login", "v1"],
|
disallowed_topics: ["docs", "static", "file", "app", "account", "settings", "signup", "login", "v1"],
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
topicUrlJsonPollWithSince,
|
topicUrlJsonPollWithSince,
|
||||||
topicUrlWebPushSubscribe,
|
topicUrlWebPushSubscribe,
|
||||||
topicUrlWebPushUnsubscribe,
|
topicUrlWebPushUnsubscribe,
|
||||||
webPushConfigUrl,
|
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
import userManager from "./UserManager";
|
import userManager from "./UserManager";
|
||||||
import { fetchOrThrow } from "./errors";
|
import { fetchOrThrow } from "./errors";
|
||||||
|
@ -117,27 +116,8 @@ class Api {
|
||||||
throw new Error(`Unexpected server response ${response.status}`);
|
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) {
|
async subscribeWebPush(baseUrl, topic, browserSubscription) {
|
||||||
const user = await userManager.get(baseUrl);
|
const user = await userManager.get(baseUrl);
|
||||||
|
|
||||||
const url = topicUrlWebPushSubscribe(baseUrl, topic);
|
const url = topicUrlWebPushSubscribe(baseUrl, topic);
|
||||||
console.log(`[Api] Sending Web Push Subscription ${url}`);
|
console.log(`[Api] Sending Web Push Subscription ${url}`);
|
||||||
|
|
||||||
|
@ -163,7 +143,9 @@ class Api {
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: maybeWithAuth({}, user),
|
headers: maybeWithAuth({}, user),
|
||||||
body: JSON.stringify({ endpoint: subscription.webPushEndpoint }),
|
body: JSON.stringify({
|
||||||
|
endpoint: subscription.webPushEndpoint
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Notifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
async subscribeWebPush(baseUrl, topic) {
|
async subscribeWebPush(baseUrl, topic) {
|
||||||
if (!this.supported() || !this.pushSupported()) {
|
if (!this.supported() || !this.pushSupported() || !config.enable_web_push) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,21 +71,12 @@ class Notifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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({
|
const browserSubscription = await registration.pushManager.subscribe({
|
||||||
userVisibleOnly: true,
|
userVisibleOnly: true,
|
||||||
applicationServerKey: urlB64ToUint8Array(webPushConfig.public_key),
|
applicationServerKey: urlB64ToUint8Array(config.web_push_public_key),
|
||||||
});
|
});
|
||||||
|
|
||||||
await api.subscribeWebPush(baseUrl, topic, browserSubscription);
|
await api.subscribeWebPush(baseUrl, topic, browserSubscription);
|
||||||
|
|
||||||
console.log("[Notifier.subscribeWebPush] Successfully subscribed to web push");
|
console.log("[Notifier.subscribeWebPush] Successfully subscribed to web push");
|
||||||
|
|
||||||
return browserSubscription;
|
return browserSubscription;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[Notifier.subscribeWebPush] Error subscribing to web push", e);
|
console.error("[Notifier.subscribeWebPush] Error subscribing to web push", e);
|
||||||
|
|
|
@ -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 topicUrlWebPushSubscribe = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/web-push/subscribe`;
|
||||||
export const topicUrlWebPushUnsubscribe = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/web-push/unsubscribe`;
|
export const topicUrlWebPushUnsubscribe = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/web-push/unsubscribe`;
|
||||||
export const topicShortUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic));
|
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 accountUrl = (baseUrl) => `${baseUrl}/v1/account`;
|
||||||
export const accountPasswordUrl = (baseUrl) => `${baseUrl}/v1/account/password`;
|
export const accountPasswordUrl = (baseUrl) => `${baseUrl}/v1/account/password`;
|
||||||
export const accountTokenUrl = (baseUrl) => `${baseUrl}/v1/account/token`;
|
export const accountTokenUrl = (baseUrl) => `${baseUrl}/v1/account/token`;
|
||||||
|
|
Loading…
Reference in New Issue