Skip to content

Commit 2c930ed

Browse files
AchoArnoldCopilot
andcommitted
refactor(api): send adapter JWT via Authorization header
Send the phone-signed notification JWT via the standard Authorization header, matching webhook requests exactly, instead of a dedicated X-Httpsms-Signature header. Adapter endpoint URLs are no longer expected to carry HTTP basic auth credentials, since Authorization is now always used for the bearer JWT; update the corresponding test to assert basic auth from the URL is ignored. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 41c41b9 commit 2c930ed

2 files changed

Lines changed: 12 additions & 11 deletions

File tree

api/pkg/services/http_notification_sender.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ const (
2626
notificationHTTPRetryDelay = 250 * time.Millisecond
2727
notificationJWTIssuer = "api.httpsms.com"
2828
notificationJWTValidity = 10 * time.Minute
29-
// notificationSignatureHeader carries the phone-signed JWT. It is not sent as Authorization so
30-
// adapters can still use HTTP basic auth embedded in the endpoint URL (see [url.URL.User]).
31-
notificationSignatureHeader = "X-Httpsms-Signature"
3229
)
3330

3431
// HTTPNotificationSender sends FCM-compatible gateway notifications to HTTPS adapters.
@@ -170,7 +167,7 @@ func createHTTPNotificationRequest(
170167
return nil, err
171168
}
172169
request.Header.Set("Content-Type", "application/json")
173-
request.Header.Set(notificationSignatureHeader, fmt.Sprintf("Bearer %s", authToken))
170+
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authToken))
174171
return request, nil
175172
}
176173

api/pkg/services/http_notification_sender_test.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func TestHTTPNotificationSenderSendsFCMCompatiblePayload(t *testing.T) {
6262
assert.Equal(t, "high", payload.Message.Android.Priority)
6363
assert.Equal(t, "600s", payload.Message.Android.TTL)
6464

65-
token, err := jwt.Parse(strings.TrimPrefix(request.Header.Get("X-Httpsms-Signature"), "Bearer "), func(*jwt.Token) (interface{}, error) {
65+
token, err := jwt.Parse(strings.TrimPrefix(request.Header.Get("Authorization"), "Bearer "), func(*jwt.Token) (interface{}, error) {
6666
return []byte(testNotificationPhoneID.String()), nil
6767
})
6868
require.NoError(t, err)
@@ -293,17 +293,21 @@ func TestHTTPNotificationSenderUsesInjectedHTTPClientUnchanged(t *testing.T) {
293293
assert.Equal(t, time.Minute, sender.client.Timeout)
294294
}
295295

296-
func TestHTTPNotificationSenderAllowsEndpointUserInformation(t *testing.T) {
296+
func TestHTTPNotificationSenderIgnoresEndpointUserInformation(t *testing.T) {
297+
// Adapter endpoints must not rely on HTTP basic auth embedded in the URL; the Authorization
298+
// header always carries the phone-signed JWT instead.
297299
sender := newHTTPNotificationSender(t, roundTripFunc(func(request *http.Request) (*http.Response, error) {
298-
username, password, ok := request.BasicAuth()
299-
assert.True(t, ok)
300-
assert.Equal(t, "adapter-user", username)
301-
assert.Equal(t, "adapter-password", password)
300+
_, _, ok := request.BasicAuth()
301+
assert.False(t, ok)
302302

303-
token, err := jwt.Parse(strings.TrimPrefix(request.Header.Get("X-Httpsms-Signature"), "Bearer "), func(*jwt.Token) (interface{}, error) {
303+
authorization := request.Header.Get("Authorization")
304+
assert.True(t, strings.HasPrefix(authorization, "Bearer "))
305+
306+
token, err := jwt.Parse(strings.TrimPrefix(authorization, "Bearer "), func(*jwt.Token) (interface{}, error) {
304307
return []byte(testNotificationPhoneID.String()), nil
305308
})
306309
require.NoError(t, err)
310+
assert.True(t, token.Valid)
307311
claims, ok := token.Claims.(jwt.MapClaims)
308312
require.True(t, ok)
309313
audience, err := claims.GetAudience()

0 commit comments

Comments
 (0)