Make DELETE endpoint, add different UI description
parent
eb220544a3
commit
58992fc795
|
@ -490,6 +490,10 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
||||||
return s.ensureUser(s.ensureCallsEnabled(s.withAccountSync(s.handleAccountPhoneNumberAdd)))(w, r, v)
|
return s.ensureUser(s.ensureCallsEnabled(s.withAccountSync(s.handleAccountPhoneNumberAdd)))(w, r, v)
|
||||||
} else if r.Method == http.MethodDelete && r.URL.Path == apiAccountPhonePath {
|
} else if r.Method == http.MethodDelete && r.URL.Path == apiAccountPhonePath {
|
||||||
return s.ensureUser(s.ensureCallsEnabled(s.withAccountSync(s.handleAccountPhoneNumberDelete)))(w, r, v)
|
return s.ensureUser(s.ensureCallsEnabled(s.withAccountSync(s.handleAccountPhoneNumberDelete)))(w, r, v)
|
||||||
|
} else if r.Method == http.MethodPost && apiAccountWebPushPath == r.URL.Path {
|
||||||
|
return s.ensureWebPushEnabled(s.limitRequests(s.handleWebPushUpdate))(w, r, v)
|
||||||
|
} else if r.Method == http.MethodDelete && apiAccountWebPushPath == r.URL.Path {
|
||||||
|
return s.ensureWebPushEnabled(s.limitRequests(s.handleWebPushDelete))(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && r.URL.Path == apiStatsPath {
|
} else if r.Method == http.MethodGet && r.URL.Path == apiStatsPath {
|
||||||
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 {
|
||||||
|
@ -524,8 +528,6 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
||||||
return s.limitRequests(s.authorizeTopicRead(s.handleSubscribeWS))(w, r, v)
|
return s.limitRequests(s.authorizeTopicRead(s.handleSubscribeWS))(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && authPathRegex.MatchString(r.URL.Path) {
|
} else if r.Method == http.MethodGet && authPathRegex.MatchString(r.URL.Path) {
|
||||||
return s.limitRequests(s.authorizeTopicRead(s.handleTopicAuth))(w, r, v)
|
return s.limitRequests(s.authorizeTopicRead(s.handleTopicAuth))(w, r, v)
|
||||||
} else if r.Method == http.MethodPut && apiAccountWebPushPath == r.URL.Path {
|
|
||||||
return s.ensureWebPushEnabled(s.limitRequests(s.handleWebPushUpdate))(w, r, v)
|
|
||||||
} else if r.Method == http.MethodGet && (topicPathRegex.MatchString(r.URL.Path) || externalTopicPathRegex.MatchString(r.URL.Path)) {
|
} else if r.Method == http.MethodGet && (topicPathRegex.MatchString(r.URL.Path) || externalTopicPathRegex.MatchString(r.URL.Path)) {
|
||||||
return s.ensureWebEnabled(s.handleTopic)(w, r, v)
|
return s.ensureWebEnabled(s.handleTopic)(w, r, v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,17 @@ func (s *Server) handleWebPushUpdate(w http.ResponseWriter, r *http.Request, v *
|
||||||
return s.writeJSON(w, newSuccessResponse())
|
return s.writeJSON(w, newSuccessResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) handleWebPushDelete(w http.ResponseWriter, r *http.Request, _ *visitor) error {
|
||||||
|
req, err := readJSONWithLimit[apiWebPushUpdateSubscriptionRequest](r.Body, jsonBodyBytesLimit, false)
|
||||||
|
if err != nil || req.Endpoint == "" {
|
||||||
|
return errHTTPBadRequestWebPushSubscriptionInvalid
|
||||||
|
}
|
||||||
|
if err := s.webPush.RemoveSubscriptionsByEndpoint(req.Endpoint); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.writeJSON(w, newSuccessResponse())
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) publishToWebPushEndpoints(v *visitor, m *message) {
|
func (s *Server) publishToWebPushEndpoints(v *visitor, m *message) {
|
||||||
subscriptions, err := s.webPush.SubscriptionsForTopic(m.Topic)
|
subscriptions, err := s.webPush.SubscriptionsForTopic(m.Topic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,7 +22,7 @@ const (
|
||||||
func TestServer_WebPush_TopicAdd(t *testing.T) {
|
func TestServer_WebPush_TopicAdd(t *testing.T) {
|
||||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), nil)
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), nil)
|
||||||
require.Equal(t, 200, response.Code)
|
require.Equal(t, 200, response.Code)
|
||||||
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func TestServer_WebPush_TopicAdd(t *testing.T) {
|
||||||
func TestServer_WebPush_TopicAdd_InvalidEndpoint(t *testing.T) {
|
func TestServer_WebPush_TopicAdd_InvalidEndpoint(t *testing.T) {
|
||||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, "https://ddos-target.example.com/webpush"), nil)
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, "https://ddos-target.example.com/webpush"), nil)
|
||||||
require.Equal(t, 400, response.Code)
|
require.Equal(t, 400, response.Code)
|
||||||
require.Equal(t, `{"code":40039,"http":400,"error":"invalid request: web push endpoint unknown"}`+"\n", response.Body.String())
|
require.Equal(t, `{"code":40039,"http":400,"error":"invalid request: web push endpoint unknown"}`+"\n", response.Body.String())
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func TestServer_WebPush_TopicAdd_TooManyTopics(t *testing.T) {
|
||||||
topicList[i] = util.RandomString(5)
|
topicList[i] = util.RandomString(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, topicList, testWebPushEndpoint), nil)
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, topicList, testWebPushEndpoint), nil)
|
||||||
require.Equal(t, 400, response.Code)
|
require.Equal(t, 400, response.Code)
|
||||||
require.Equal(t, `{"code":40040,"http":400,"error":"invalid request: too many web push topic subscriptions"}`+"\n", response.Body.String())
|
require.Equal(t, `{"code":40040,"http":400,"error":"invalid request: too many web push topic subscriptions"}`+"\n", response.Body.String())
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func TestServer_WebPush_TopicUnsubscribe(t *testing.T) {
|
||||||
addSubscription(t, s, testWebPushEndpoint, "test-topic")
|
addSubscription(t, s, testWebPushEndpoint, "test-topic")
|
||||||
requireSubscriptionCount(t, s, "test-topic", 1)
|
requireSubscriptionCount(t, s, "test-topic", 1)
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{}, testWebPushEndpoint), nil)
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{}, testWebPushEndpoint), nil)
|
||||||
require.Equal(t, 200, response.Code)
|
require.Equal(t, 200, response.Code)
|
||||||
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ func TestServer_WebPush_TopicSubscribeProtected_Allowed(t *testing.T) {
|
||||||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||||
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), map[string]string{
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), map[string]string{
|
||||||
"Authorization": util.BasicAuth("ben", "ben"),
|
"Authorization": util.BasicAuth("ben", "ben"),
|
||||||
})
|
})
|
||||||
require.Equal(t, 200, response.Code)
|
require.Equal(t, 200, response.Code)
|
||||||
|
@ -95,7 +95,7 @@ func TestServer_WebPush_TopicSubscribeProtected_Denied(t *testing.T) {
|
||||||
config.AuthDefault = user.PermissionDenyAll
|
config.AuthDefault = user.PermissionDenyAll
|
||||||
s := newTestServer(t, config)
|
s := newTestServer(t, config)
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), nil)
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), nil)
|
||||||
require.Equal(t, 403, response.Code)
|
require.Equal(t, 403, response.Code)
|
||||||
|
|
||||||
requireSubscriptionCount(t, s, "test-topic", 0)
|
requireSubscriptionCount(t, s, "test-topic", 0)
|
||||||
|
@ -108,7 +108,7 @@ func TestServer_WebPush_DeleteAccountUnsubscribe(t *testing.T) {
|
||||||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||||
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
||||||
|
|
||||||
response := request(t, s, "PUT", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), map[string]string{
|
response := request(t, s, "POST", "/v1/account/webpush", payloadForTopics(t, []string{"test-topic"}, testWebPushEndpoint), map[string]string{
|
||||||
"Authorization": util.BasicAuth("ben", "ben"),
|
"Authorization": util.BasicAuth("ben", "ben"),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ func TestServer_WebPush_Publish(t *testing.T) {
|
||||||
defer pushService.Close()
|
defer pushService.Close()
|
||||||
|
|
||||||
addSubscription(t, s, pushService.URL+"/push-receive", "test-topic")
|
addSubscription(t, s, pushService.URL+"/push-receive", "test-topic")
|
||||||
request(t, s, "PUT", "/test-topic", "web push test", nil)
|
request(t, s, "POST", "/test-topic", "web push test", nil)
|
||||||
|
|
||||||
waitFor(t, func() bool {
|
waitFor(t, func() bool {
|
||||||
return received.Load()
|
return received.Load()
|
||||||
|
@ -162,7 +162,7 @@ func TestServer_WebPush_Publish_RemoveOnError(t *testing.T) {
|
||||||
requireSubscriptionCount(t, s, "test-topic", 1)
|
requireSubscriptionCount(t, s, "test-topic", 1)
|
||||||
requireSubscriptionCount(t, s, "test-topic-abc", 1)
|
requireSubscriptionCount(t, s, "test-topic-abc", 1)
|
||||||
|
|
||||||
request(t, s, "PUT", "/test-topic", "web push test", nil)
|
request(t, s, "POST", "/test-topic", "web push test", nil)
|
||||||
|
|
||||||
waitFor(t, func() bool {
|
waitFor(t, func() bool {
|
||||||
return received.Load()
|
return received.Load()
|
||||||
|
|
|
@ -115,14 +115,13 @@ class Api {
|
||||||
throw new Error(`Unexpected server response ${response.status}`);
|
throw new Error(`Unexpected server response ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateWebPushSubscriptions(topics, pushSubscription) {
|
async updateWebPush(pushSubscription, topics) {
|
||||||
const user = await userManager.get(config.base_url);
|
const user = await userManager.get(config.base_url);
|
||||||
const url = accountWebPushUrl(config.base_url);
|
const url = accountWebPushUrl(config.base_url);
|
||||||
console.log(`[Api] Sending Web Push Subscriptions`, { url, topics, endpoint: pushSubscription.endpoint });
|
console.log(`[Api] Updating Web Push subscription`, { url, topics, endpoint: pushSubscription.endpoint });
|
||||||
console.log(`[Api] Sending Web Push Subscriptions`, { pushSubscription });
|
|
||||||
const serializedSubscription = JSON.parse(JSON.stringify(pushSubscription)); // Ugh ... https://stackoverflow.com/a/40525434/1440785
|
const serializedSubscription = JSON.parse(JSON.stringify(pushSubscription)); // Ugh ... https://stackoverflow.com/a/40525434/1440785
|
||||||
await fetchOrThrow(url, {
|
await fetchOrThrow(url, {
|
||||||
method: "PUT",
|
method: "POST",
|
||||||
headers: maybeWithAuth({}, user),
|
headers: maybeWithAuth({}, user),
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
endpoint: serializedSubscription.endpoint,
|
endpoint: serializedSubscription.endpoint,
|
||||||
|
@ -132,6 +131,20 @@ class Api {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async deleteWebPush(pushSubscription) {
|
||||||
|
const user = await userManager.get(config.base_url);
|
||||||
|
const url = accountWebPushUrl(config.base_url);
|
||||||
|
console.log(`[Api] Deleting Web Push subscription`, { url, endpoint: pushSubscription.endpoint });
|
||||||
|
await fetchOrThrow(url, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: maybeWithAuth({}, user),
|
||||||
|
body: JSON.stringify({
|
||||||
|
endpoint: pushSubscription.endpoint
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = new Api();
|
const api = new Api();
|
||||||
|
|
|
@ -119,7 +119,12 @@ class SubscriptionManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.updateWebPushSubscriptions(topics, browserSubscription);
|
if (topics.length > 0) {
|
||||||
|
await api.updateWebPush(browserSubscription, topics);
|
||||||
|
} else {
|
||||||
|
await api.deleteWebPush(browserSubscription);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateState(subscriptionId, state) {
|
async updateState(subscriptionId, state) {
|
||||||
|
|
Loading…
Reference in New Issue