Skip to content

Commit

Permalink
Add error on invalid expiration request and updat documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
marc1706 committed Feb 27, 2024
1 parent 801db42 commit 4f1abdd
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 7 deletions.
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,43 @@ Additional fields are specified in square brackets.
- Output:
```
{
data: PushSubscriptionJSON[+clientHash]
data: PushSubscriptionJSON[+clientHash]
}
```

#### Expire subscription
- URL: `http://localhost:8090/expire-subscription/[+clientHash]`
- Input: None (expect for clientHash in URL)
- Output:
- Status:
- 200 for success
- 400 on error e.g. when subscription does not exist
- Body:
- None for success
- Error return on error

#### Send push notification
- URL: `PushSubscriptionJSON.endpoint` (format: `http://localhost:8090/notify/[+clientHash]`)
- Headers: See e.g. [RFC 8291](https://datatracker.ietf.org/doc/html/rfc8291) on required headers
- Input: Encrypted payload
- Output:
- Status: 201 for success, 400/410 on errors
- No body
- Status:
- 201 for success
- 400 on errors
- 410 on expired subscriptions
- Body
- Error:
```
{
error: { message: err.message }
}
```
- Expired subscription:
```
{
reason: 'Push subscription has unsubscribed or expired.',
}
```

#### Get endpoint notifications
- URL: `http://localhost:8090/get-notifications`
Expand Down
2 changes: 2 additions & 0 deletions src/PushApiModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ class PushApiModel {
expireSubscription(clientHash) {
if (typeof this.subscriptions[clientHash] !== 'undefined') {

Check failure on line 165 in src/PushApiModel.js

View workflow job for this annotation

GitHub Actions / tests (15.x)

Unexpected negated condition

Check failure on line 165 in src/PushApiModel.js

View workflow job for this annotation

GitHub Actions / tests (16.x)

Unexpected negated condition

Check failure on line 165 in src/PushApiModel.js

View workflow job for this annotation

GitHub Actions / tests (17.x)

Unexpected negated condition
this.subscriptions[clientHash].isExpired = true;
} else {
throw new RangeError('Subscription with specified client hash does not exist');
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,15 @@ class WebPushTestingServer {
expireSubscription(req, res) {
const {clientHash} = req.params;

apiModel.expireSubscription(clientHash);
try {
apiModel.expireSubscription(clientHash);
} catch (err) {
res.status(400).send({
error: {
message: err.message,
}

Check failure on line 137 in src/server.js

View workflow job for this annotation

GitHub Actions / tests (15.x)

Missing trailing comma

Check failure on line 137 in src/server.js

View workflow job for this annotation

GitHub Actions / tests (16.x)

Missing trailing comma

Check failure on line 137 in src/server.js

View workflow job for this annotation

GitHub Actions / tests (17.x)

Missing trailing comma
});
}

console.log('Expire subscription for ' + clientHash);
res.sendStatus(200);
Expand Down
17 changes: 14 additions & 3 deletions test/PushApiModelTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,24 @@ describe('Push API Model tests', () => {
assert.hasAllKeys(subscribeReturn.keys, ['p256dh', 'auth']);
assert.hasAllKeys(model.subscriptions, [subscribeReturn.clientHash]);

assert.isFalse(model.isSubscriptionExpired('doesNotExist'));
assert.isFalse(model.isSubscriptionExpired(subscribeReturn.clientHash));
model.expireSubscription(subscribeReturn.clientHash);
assert.isTrue(model.isSubscriptionExpired(subscribeReturn.clientHash));
model.expireSubscription('doesNotExist');
assert.isFalse(model.isSubscriptionExpired('doesNotExist'));
});

it ('Invalid subscription is properly handled', async () => {
const model = new PushApiModel();

assert.isFalse(model.isSubscriptionExpired('doesNotExist'));

try {
model.expireSubscription('doesNotExist');
} catch(err) {
assert.instanceOf(err, RangeError);
assert.equal(err.message, 'Subscription with specified client hash does not exist');
}
assert.isFalse(model.isSubscriptionExpired('doesNotExist'));
})
});

describe('Validate notification headers', () => {
Expand Down
31 changes: 31 additions & 0 deletions test/serverTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,37 @@ describe('Push Server tests', () => {
});
});

describe('Expire non-existent subscription', () => {
it('Should return 400', async () => {
const model = new PushApiModel();
const port = 8990;

const server = new WebPushTestingServer(model, port);
startLogging();
server.startServer();

await fetch('http://localhost:' + port + '/status', {
method: 'POST',
}).then(response => {
response.status.should.equal(200);
consoleLogs.length.should.equal(1);
consoleLogs[0].should.match(/Server running/);
});

// Try expiring a non-existent subscription
await fetch('http://localhost:' + port + '/expire-subscription/doesNotExist', {
method: 'POST',
}).then(async response => {
server._server.close();
endLogging();

response.status.should.equal(400);
const responseBody = await response.json();
responseBody.error.message.should.equal('Subscription with specified client hash does not exist');
});
});
});

describe('Send notifications', () => {
const input = [
{
Expand Down

0 comments on commit 4f1abdd

Please sign in to comment.