Skip to content

Commit 63ba221

Browse files
authored
Feature/sns validator (#27)
* WIP commit * Add tests for getCertificate * Wire up certificate fetching and signature verification and round out the test suite * Remove `null` Subject fields in the convertLambdaNotification function * Improve formatting and fix typos
1 parent c82133c commit 63ba221

19 files changed

+1345
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.js
2+
*.js.map
3+
*.d.ts
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {LambdaNotificationMessage} from "../lib/convertLambdaNotification";
2+
import {
3+
NotificationMessage,
4+
SubscriptionConfirmationMessage,
5+
UnsubscribeConfirmationMessage
6+
} from "../lib/Message";
7+
8+
export const HTTP_NOTIFICATION: NotificationMessage = {
9+
Type: "Notification",
10+
MessageId: "9438aee6-d476-5e20-ba25-ff24bf09d6ce",
11+
TopicArn: "arn:aws:sns:us-west-2:604091128280:testing1",
12+
Subject: "A subject",
13+
Message: "A message",
14+
Timestamp: "2017-06-20T00:15:59.380Z",
15+
SignatureVersion: "1",
16+
Signature: "WT7qMHW+jPdj/brSAX7M1jbP5OoPjn9pYmGQqrWeQgbMyVvz3D2sV72ldhCxQLqj/3TLtcTyErVqzT3AfQ8Vk55Rzxd1xnBufJ+0vIyH98b82pKOqRHOqlB72la5nY9/GF/p71BXmIChQpfv/CEZumexgLWnweJsqSMe82I6/eMmrhVZdKpBvz4Sqj+wNQW+0eYEc9bdZmEKuYIvrvTGm1MWkXmqUGuCGj5o3vFFn1GTtM895B3MyMgaSeDHI08CVfs9y1nLcrxwMvqpkHZmIwTi1jzSipYMRD8FVF6Wvq0Scy+FoYSnOWHpEsELI0SGddSqYgli9ROYiqi3DQhvHw==",
17+
SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem",
18+
UnsubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:604091128280:testing1:b061e4fd-c468-458d-9736-91c8c0c18e29",
19+
};
20+
21+
export const LAMBDA_NOTIFICATION: LambdaNotificationMessage = {
22+
Type: 'Notification',
23+
MessageId: '9438aee6-d476-5e20-ba25-ff24bf09d6ce',
24+
TopicArn: 'arn:aws:sns:us-west-2:604091128280:testing1',
25+
Subject: 'A subject',
26+
Message: 'A message',
27+
Timestamp: '2017-06-20T00:15:59.380Z',
28+
SignatureVersion: '1',
29+
Signature: 'WT7qMHW+jPdj/brSAX7M1jbP5OoPjn9pYmGQqrWeQgbMyVvz3D2sV72ldhCxQLqj/3TLtcTyErVqzT3AfQ8Vk55Rzxd1xnBufJ+0vIyH98b82pKOqRHOqlB72la5nY9/GF/p71BXmIChQpfv/CEZumexgLWnweJsqSMe82I6/eMmrhVZdKpBvz4Sqj+wNQW+0eYEc9bdZmEKuYIvrvTGm1MWkXmqUGuCGj5o3vFFn1GTtM895B3MyMgaSeDHI08CVfs9y1nLcrxwMvqpkHZmIwTi1jzSipYMRD8FVF6Wvq0Scy+FoYSnOWHpEsELI0SGddSqYgli9ROYiqi3DQhvHw==',
30+
SigningCertUrl: 'https://sns.us-west-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem',
31+
UnsubscribeUrl: 'https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:604091128280:testing1:7118d01a-202e-4a65-a372-f46b0994bdae',
32+
};
33+
34+
export const HTTP_NOTIFICATION_NO_SUBJECT: NotificationMessage = {
35+
Type: "Notification",
36+
MessageId: "7317aaf2-e97a-5cf3-8123-fb3a48fabd2a",
37+
TopicArn: "arn:aws:sns:us-west-2:604091128280:testing1",
38+
Message: "A subject-less message",
39+
Timestamp: "2017-06-24T17:20:00.581Z",
40+
SignatureVersion: "1",
41+
Signature: "Lvtgxo8P2C3XUKT8fC7sfMRhxoK6dn/ed9B1DClmJ9GNuFF73G27lhKUsKWrLReawa+v7C1UY49qQb+lSMsBiTV0Hx7L2OKJjzll4fx+G09h2P8OK43Jk6/W05+xU0uvch6Ktp3XrBcI6KNyGFio5GAR2rCBHjdh8MsEYAWRtaVCBqJTLqnHscivOJD8u/m807wDbDhh9cQ5WnvjerUjtrDAfQJN5vHLjEPbL1owtu2FzC3rOHUL9j4TGOdZi2jhUYv8jwzNnJ05bhbtKd6HxKcTcv1JCp/4NLPa8LWYnbLRvWooDQdF2hr56EF6EKDzTtAWagoNYztwSvosQXNK+Q==",
42+
SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem",
43+
UnsubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:604091128280:testing1:f0dd49ac-c33d-471e-812d-1f0e5116c711",
44+
};
45+
46+
export const LAMBDA_NOTIFICATION_NO_SUBJECT: LambdaNotificationMessage = {
47+
Type: 'Notification',
48+
MessageId: '7317aaf2-e97a-5cf3-8123-fb3a48fabd2a',
49+
TopicArn: 'arn:aws:sns:us-west-2:604091128280:testing1',
50+
Subject: null,
51+
Message: 'A subject-less message',
52+
Timestamp: '2017-06-24T17:20:00.581Z',
53+
SignatureVersion: '1',
54+
Signature: 'Lvtgxo8P2C3XUKT8fC7sfMRhxoK6dn/ed9B1DClmJ9GNuFF73G27lhKUsKWrLReawa+v7C1UY49qQb+lSMsBiTV0Hx7L2OKJjzll4fx+G09h2P8OK43Jk6/W05+xU0uvch6Ktp3XrBcI6KNyGFio5GAR2rCBHjdh8MsEYAWRtaVCBqJTLqnHscivOJD8u/m807wDbDhh9cQ5WnvjerUjtrDAfQJN5vHLjEPbL1owtu2FzC3rOHUL9j4TGOdZi2jhUYv8jwzNnJ05bhbtKd6HxKcTcv1JCp/4NLPa8LWYnbLRvWooDQdF2hr56EF6EKDzTtAWagoNYztwSvosQXNK+Q==',
55+
SigningCertUrl: 'https://sns.us-west-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem',
56+
UnsubscribeUrl: 'https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:604091128280:testing1:7118d01a-202e-4a65-a372-f46b0994bdae',
57+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEWjCCAkICCQDK848c0wG7ajANBgkqhkiG9w0BAQsFADBvMQswCQYDVQQGEwJV
3+
UzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTElMCMGA1UE
4+
CgwcTWVzc2FnZSBWYWxpZGF0b3IgVW5pdCBUZXN0czESMBAGA1UEAwwJbG9jYWxo
5+
b3N0MB4XDTE3MDYyMzAxMTQzOFoXDTIzMDEzMTAxMTQzOFowbzELMAkGA1UEBhMC
6+
VVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxJTAjBgNV
7+
BAoMHE1lc3NhZ2UgVmFsaWRhdG9yIFVuaXQgVGVzdHMxEjAQBgNVBAMMCWxvY2Fs
8+
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANknobw2ZghFY9yE
9+
Ork5dSlW2giIk2Sb/0GajCXNc1ajVkn1R5e5WNLYWALFRyHmtvWFj6Rut9pQ4WOk
10+
OKYsaWvNlB89CuvKDOZAF02BiTJuXsb5+jHIhg2uuEKS/bEZG27FFZZMLAIeMpdN
11+
Ro+02gKH1DXp6xa3nHkwR00b+0traTwyvvJQsaKHmEHClKwom1i8A60l2Ctm+K2I
12+
io7uLafVX7Xufmqhgxyn+ZSPe/iYgqSrh68gc/OkPuaakMEx72pfqK1wAZz5NWSn
13+
6MFi/mfXmvbL7hfCwThABAQ1I2codGyq7Ax1mMeC/bYYGAIPRoUbsx0jkjzO64gw
14+
NBs+WJECAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAJkb1qMVICfH0cx+loEm8H4vp
15+
v2gt2iinFprYbKuzsYIysc8fVrz7Fcs2mG3Co0uXzddNAzd1ZwPO5vWyU7nu8J0L
16+
LSx2u7prAl4Jflr/kwlFt2f/ParTBgdoVSM4sI2VgL/B89fKcC3C24lEU5dPsntg
17+
cbBhlhDtOpn0BVhEuVVXFMMmqthkrzZjRrsZZ8uwR8tbJWXh6peMPCD/86NFrWgK
18+
givJOrWmraE6MbIo1AUEj7wTK7+viXmzKkYpAj/pJI2Duy4Xbx4t+ry2//rByc4G
19+
rJpsHnQmN7zM+AvMClQyyg+F0BXRBr71cbrbCko59MxWwHdT7+Z7y0fc9sKhVuQO
20+
RkJ2p4+0ll1JLE39i6Q/cGBr65MqeSx6Feo6rlQbW8qD7YLZrFHmxHKHD1kLx9h1
21+
agfawgi2B++qHFdMe5sxZ2cSneWmFIiwTMWbdKIVmhPx+tuYh+QyQScyoFCoy3c4
22+
WpKWjjg+wfwDgf41rfvlO0xyG1VZ1bVKSRkiQjdXZ+/4DFrNeKFDpiexSio7dgJZ
23+
JR+wzPSFzGDlSv96gf+cKNgJA1Yw5r2Y3zGN65tFpMm4qLDR6R6ajy8IRMcCqGUq
24+
BxAexvuxslcc0pj3e9vUWkp3Ky5u+xNQ1EiS6VMbWEcJYjNInEAlTdS+V5uiCDh3
25+
aLzuR8HtZN016piziIU=
26+
-----END CERTIFICATE-----
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpQIBAAKCAQEA2SehvDZmCEVj3IQ6uTl1KVbaCIiTZJv/QZqMJc1zVqNWSfVH
3+
l7lY0thYAsVHIea29YWPpG632lDhY6Q4pixpa82UHz0K68oM5kAXTYGJMm5exvn6
4+
MciGDa64QpL9sRkbbsUVlkwsAh4yl01Gj7TaAofUNenrFreceTBHTRv7S2tpPDK+
5+
8lCxooeYQcKUrCibWLwDrSXYK2b4rYiKju4tp9Vfte5+aqGDHKf5lI97+JiCpKuH
6+
ryBz86Q+5pqQwTHval+orXABnPk1ZKfowWL+Z9ea9svuF8LBOEAEBDUjZyh0bKrs
7+
DHWYx4L9thgYAg9GhRuzHSOSPM7riDA0Gz5YkQIDAQABAoIBAQDPmUjQgvzmOVgv
8+
j6YIP3rXa3WDpPWrwEq1sAb9eL0j/YDXsYqg7QuSfksdUvYe3c7ZR7c8DrDrIFlp
9+
Ba02h8y8x8ssVhIjuoS8dlcQvJ6pvMQU2xQqFba6S+dRle68KPGF4xoxFl8YI0Bg
10+
Tvr/FXk55Bqm9BrQG/aWEOaJPA/wV1tq4d/Sv+pLJozM7ejzl0/QRV1p2dnvKwvO
11+
kO48G/Y+k8DXnwIR5qcGhAZP7wxb2cvzWEQwuBDNKedCNAInjjakXJt4bH+vYAE6
12+
RXlzZnQC2LRMKomlCIcaJeINlhlCX/HJPYQrz8Zav6WTAYvolHqW9HRBqp0mG7iZ
13+
O6NmLvOVAoGBAO6CHnsHKUo2rlf5E68u8HlbxPJcToOt+APLymvJOcjGnrgLKo01
14+
KqMMyUVVXyGfpYcN2Bxvk92BTQ71xt4FzqaNn+Ag/NRtHi/ecYnPrH3X+Dd0WRd/
15+
VFX4cGdqd0JXNOMLhKPsk+qO9h9lAoBiDMM2B6pyN4P8mLs3VXU1QrG/AoGBAOkU
16+
nIWzWTMqShkv6CmE2dBkeZaDq3vsgdvGYkaluhJ4nKoMM2GCPtcVmSpKna5GNcsx
17+
rAkxSbnz+WEUGJ+XQxP2bsZsfUbSsBqYOYSqqGVJaBsIXR4s+iB27l/XAKDuPsYr
18+
eYH7HbDf6afxEz5Bbf2E8ZvEZQ0M+UrPRB75IOmvAoGBAL5G2IJWCD7IuPY+I9IS
19+
pI5tBAZGVez/kWmV33t2Ib9nlaBGaEAXNli2Dqxdm3N7pdbE2LB244RHb26L7Yeb
20+
Im4FdpKcPphKJVcTI4lKQNZ0wfWbwKfaUTH07dfTPCmU4QBxY/RS/P6X5wrMzt4V
21+
WxExvZPhYyDNGBvj3S2QvBCJAoGBAIZmKjM2TbMhKYUIiNiYEHkH1syhtBpLMD4o
22+
ULboDTllbwDm9CG/1rhzbdRjHjVFqvM1+zt5vkeJlT0TN3ee40D5krq8CCj0iDNt
23+
n40OUvfEslEUK42g5cIekimVcnlZp7zhiLkYsfAxzSvX6P62/9N1+1OUlahG2OD4
24+
TxGFGiNlAoGAE6S7R3GJyBUrgEd7ViOFGYkArmZnYgEvGgZ8IuS17BXFZdENdzjz
25+
b78WsPgxyRSMttKnmcDEErdtfVNyS2tFNSfTRpHHFxM8x2Ot/mw0krUSpXzMGc1s
26+
i6TltbVl1gSrhE1P8Kpuw4farJaP8M6P5UMU/HpPCO38EmnvKvxdTgA=
27+
-----END RSA PRIVATE KEY-----
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import {
2+
BaseMessage,
3+
isMessage,
4+
NotificationMessage,
5+
SubscriptionConfirmationMessage,
6+
UnsubscribeConfirmationMessage,
7+
} from "../lib/Message";
8+
9+
const validNotification: NotificationMessage = {
10+
Type: "Notification",
11+
MessageId: "da41e39f-ea4d-435a-b922-c6aae3915ebe",
12+
TopicArn: "arn:aws:sns:us-west-2:123456789012:MyTopic",
13+
Subject: "test",
14+
Message: "test message",
15+
Timestamp: "2012-04-25T21:49:25.719Z",
16+
SignatureVersion: "1",
17+
Signature: "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
18+
SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
19+
UnsubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
20+
};
21+
22+
const validSubscriptionConfirmation: SubscriptionConfirmationMessage = {
23+
Type: "SubscriptionConfirmation",
24+
MessageId: "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
25+
Token: "2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
26+
TopicArn: "arn:aws:sns:us-west-2:123456789012:MyTopic",
27+
Message: "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
28+
SubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
29+
Timestamp: "2012-04-26T20:45:04.751Z",
30+
SignatureVersion: "1",
31+
Signature: "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",
32+
SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
33+
};
34+
35+
const validUnsubscribeConfirmation: UnsubscribeConfirmationMessage = {
36+
Type: "UnsubscribeConfirmation",
37+
MessageId: "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
38+
Token: "2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
39+
TopicArn: "arn:aws:sns:us-west-2:123456789012:MyTopic",
40+
Message: "You have chosen to deactivate subscription arn:aws:sns:us-east-1:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.",
41+
SubscribeURL: "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
42+
Timestamp: "2012-04-26T20:45:04.751Z",
43+
SignatureVersion: "1",
44+
Signature: "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",
45+
SigningCertURL: "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
46+
};
47+
48+
describe('isMessage', () => {
49+
it('should reject scalar values', () => {
50+
for (let scalar of ['string', 20, null, void 0, true]) {
51+
expect(isMessage(scalar)).toBe(false);
52+
}
53+
});
54+
55+
for (let requiredField of ['Type', 'Message', 'MessageId', 'Signature', 'SigningCertURL', 'Timestamp', 'TopicArn']) {
56+
it(`should reject messages where ${requiredField} is not defined`, () => {
57+
expect(isMessage({...validNotification, [requiredField]: void 0}))
58+
.toBe(false);
59+
});
60+
}
61+
62+
it(
63+
'should reject messages whose Type is not Notification, SubscriptionConfirmation, or UnsubscribeConfirmation',
64+
() => {
65+
expect(isMessage({...validNotification, Type: 'foo'})).toBe(false);
66+
}
67+
);
68+
69+
it('should reject messages whose SignatureVersion is not a string', () => {
70+
expect(isMessage({...validNotification, SignatureVersion: 1}))
71+
.toBe(false);
72+
});
73+
74+
describe('notification messages', () => {
75+
it('should accept valid notification messages', () => {
76+
expect(isMessage(validNotification)).toBe(true);
77+
});
78+
79+
it('should accept notification messages with no subject', () => {
80+
expect(isMessage({...validNotification, Subject: void 0}))
81+
.toBe(true);
82+
});
83+
84+
it(
85+
'should reject notification messages whose subject is neither a string nor undefined',
86+
() => {
87+
expect(isMessage({...validNotification, Subject: 10}))
88+
.toBe(false);
89+
}
90+
);
91+
92+
it('should reject notification messages without an UnsubscribeURL', () => {
93+
expect(isMessage({...validNotification, UnsubscribeURL: void 0}))
94+
.toBe(false);
95+
});
96+
});
97+
98+
describe('subscription confirmation messages', () => {
99+
it('should accept a valid subscription confirmation message', () => {
100+
expect(isMessage(validSubscriptionConfirmation)).toBe(true);
101+
});
102+
103+
it(
104+
'should reject subscription confirmation messages without a SubscribeURL',
105+
() => {
106+
expect(isMessage({
107+
...validSubscriptionConfirmation,
108+
SubscribeURL: void 0
109+
})).toBe(false);
110+
}
111+
);
112+
113+
it(
114+
'should reject subscription confirmation messages without a Token',
115+
() => {
116+
expect(isMessage({
117+
...validSubscriptionConfirmation,
118+
Token: void 0
119+
})).toBe(false);
120+
}
121+
);
122+
});
123+
124+
describe('unsubscribe confirmation messages', () => {
125+
it('should accept a valid subscription confirmation message', () => {
126+
expect(isMessage(validUnsubscribeConfirmation)).toBe(true);
127+
});
128+
129+
it(
130+
'should reject subscription confirmation messages without a SubscribeURL',
131+
() => {
132+
expect(isMessage({
133+
...validUnsubscribeConfirmation,
134+
SubscribeURL: void 0
135+
})).toBe(false);
136+
}
137+
);
138+
139+
it(
140+
'should reject subscription confirmation messages without a Token',
141+
() => {
142+
expect(isMessage({
143+
...validUnsubscribeConfirmation,
144+
Token: void 0
145+
})).toBe(false);
146+
}
147+
);
148+
});
149+
});

0 commit comments

Comments
 (0)