@tryvital/vital-node 0.3.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/Activity.ts +1 -1
- package/client/Body.ts +1 -1
- package/client/Profile.ts +25 -0
- package/client/Sleep.ts +2 -2
- package/client/Testkits.ts +11 -8
- package/client/User.ts +2 -2
- package/client/Vitals.ts +45 -45
- package/client/Webhooks.ts +7 -58
- package/client/Workouts.ts +3 -3
- package/client/index.ts +1 -1
- package/client/models/activity.ts +10 -3
- package/client/models/body_model.ts +0 -18
- package/client/models/profile_model.ts +34 -0
- package/client/models/testkit_models.ts +16 -2
- package/client/models/user_models.ts +4 -0
- package/dist/client/Activity.js +1 -1
- package/dist/client/Body.js +1 -1
- package/dist/client/Profile.d.ts +8 -0
- package/dist/client/{ProviderSpecific.js → Profile.js} +8 -12
- package/dist/client/Sleep.js +2 -2
- package/dist/client/Testkits.d.ts +3 -2
- package/dist/client/Testkits.js +15 -1
- package/dist/client/User.d.ts +2 -2
- package/dist/client/Vitals.d.ts +7 -6
- package/dist/client/Vitals.js +16 -41
- package/dist/client/Webhooks.d.ts +1 -7
- package/dist/client/Webhooks.js +4 -102
- package/dist/client/Workouts.d.ts +1 -1
- package/dist/client/Workouts.js +3 -3
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/models/activity.d.ts +9 -3
- package/dist/client/models/body_model.d.ts +0 -18
- package/dist/client/models/profile_model.d.ts +33 -0
- package/dist/{swagger_client/models/client-activity-response.js → client/models/profile_model.js} +0 -0
- package/dist/client/models/testkit_models.d.ts +15 -2
- package/dist/client/models/user_models.d.ts +3 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +11 -11
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/config.js +0 -1
- package/index.ts +14 -14
- package/lib/config.ts +0 -1
- package/package.json +3 -2
- package/client/ProviderSpecific.ts +0 -31
- package/dist/client/ProviderSpecific.d.ts +0 -8
- package/dist/swagger_client/api.d.ts +0 -18
- package/dist/swagger_client/api.js +0 -32
- package/dist/swagger_client/apis/activity-api.d.ts +0 -86
- package/dist/swagger_client/apis/activity-api.js +0 -241
- package/dist/swagger_client/apis/body-api.d.ts +0 -86
- package/dist/swagger_client/apis/body-api.js +0 -241
- package/dist/swagger_client/apis/link-api.d.ts +0 -115
- package/dist/swagger_client/apis/link-api.js +0 -310
- package/dist/swagger_client/apis/provider-specific-api.d.ts +0 -90
- package/dist/swagger_client/apis/provider-specific-api.js +0 -250
- package/dist/swagger_client/apis/sleep-api.d.ts +0 -120
- package/dist/swagger_client/apis/sleep-api.js +0 -330
- package/dist/swagger_client/apis/user-api.d.ts +0 -243
- package/dist/swagger_client/apis/user-api.js +0 -657
- package/dist/swagger_client/apis/webhooks-api.d.ts +0 -138
- package/dist/swagger_client/apis/webhooks-api.js +0 -379
- package/dist/swagger_client/apis/workouts-api.d.ts +0 -120
- package/dist/swagger_client/apis/workouts-api.js +0 -330
- package/dist/swagger_client/base.d.ts +0 -55
- package/dist/swagger_client/base.js +0 -67
- package/dist/swagger_client/configuration.d.ts +0 -63
- package/dist/swagger_client/configuration.js +0 -16
- package/dist/swagger_client/index.d.ts +0 -13
- package/dist/swagger_client/index.js +0 -27
- package/dist/swagger_client/models/client-activity-response.d.ts +0 -24
- package/dist/swagger_client/models/client-body-response.d.ts +0 -24
- package/dist/swagger_client/models/client-body-response.js +0 -2
- package/dist/swagger_client/models/client-facing-activity.d.ts +0 -84
- package/dist/swagger_client/models/client-facing-activity.js +0 -2
- package/dist/swagger_client/models/client-facing-body.d.ts +0 -72
- package/dist/swagger_client/models/client-facing-body.js +0 -2
- package/dist/swagger_client/models/client-facing-sleep-stream.d.ts +0 -48
- package/dist/swagger_client/models/client-facing-sleep-stream.js +0 -2
- package/dist/swagger_client/models/client-facing-sleep.d.ts +0 -138
- package/dist/swagger_client/models/client-facing-sleep.js +0 -2
- package/dist/swagger_client/models/client-facing-source-specific.d.ts +0 -48
- package/dist/swagger_client/models/client-facing-source-specific.js +0 -2
- package/dist/swagger_client/models/client-facing-sport.d.ts +0 -30
- package/dist/swagger_client/models/client-facing-sport.js +0 -2
- package/dist/swagger_client/models/client-facing-stream.d.ts +0 -84
- package/dist/swagger_client/models/client-facing-stream.js +0 -2
- package/dist/swagger_client/models/client-facing-user.d.ts +0 -48
- package/dist/swagger_client/models/client-facing-user.js +0 -2
- package/dist/swagger_client/models/client-facing-webhook.d.ts +0 -42
- package/dist/swagger_client/models/client-facing-webhook.js +0 -2
- package/dist/swagger_client/models/client-facing-workout.d.ts +0 -150
- package/dist/swagger_client/models/client-facing-workout.js +0 -2
- package/dist/swagger_client/models/client-sleep-response.d.ts +0 -24
- package/dist/swagger_client/models/client-sleep-response.js +0 -2
- package/dist/swagger_client/models/client-source-specific-response.d.ts +0 -24
- package/dist/swagger_client/models/client-source-specific-response.js +0 -2
- package/dist/swagger_client/models/client-webhook-response.d.ts +0 -24
- package/dist/swagger_client/models/client-webhook-response.js +0 -2
- package/dist/swagger_client/models/client-workout-response.d.ts +0 -24
- package/dist/swagger_client/models/client-workout-response.js +0 -2
- package/dist/swagger_client/models/connected-source-client-facing.d.ts +0 -24
- package/dist/swagger_client/models/connected-source-client-facing.js +0 -2
- package/dist/swagger_client/models/httpvalidation-error.d.ts +0 -24
- package/dist/swagger_client/models/httpvalidation-error.js +0 -2
- package/dist/swagger_client/models/index.d.ts +0 -32
- package/dist/swagger_client/models/index.js +0 -44
- package/dist/swagger_client/models/individual-provider-data.d.ts +0 -30
- package/dist/swagger_client/models/individual-provider-data.js +0 -2
- package/dist/swagger_client/models/link-token-exchange-response.d.ts +0 -24
- package/dist/swagger_client/models/link-token-exchange-response.js +0 -2
- package/dist/swagger_client/models/link-token-exchange.d.ts +0 -30
- package/dist/swagger_client/models/link-token-exchange.js +0 -2
- package/dist/swagger_client/models/password-providers.d.ts +0 -22
- package/dist/swagger_client/models/password-providers.js +0 -28
- package/dist/swagger_client/models/provider-link-response.d.ts +0 -30
- package/dist/swagger_client/models/provider-link-response.js +0 -2
- package/dist/swagger_client/models/providers-that-require-password-auth-whoop-renpho-peloton-zwift.d.ts +0 -18
- package/dist/swagger_client/models/providers-that-require-password-auth-whoop-renpho-peloton-zwift.js +0 -2
- package/dist/swagger_client/models/providers.d.ts +0 -27
- package/dist/swagger_client/models/providers.js +0 -33
- package/dist/swagger_client/models/source-client-facing.d.ts +0 -36
- package/dist/swagger_client/models/source-client-facing.js +0 -2
- package/dist/swagger_client/models/user-create.d.ts +0 -24
- package/dist/swagger_client/models/user-create.js +0 -2
- package/dist/swagger_client/models/user-key-response.d.ts +0 -30
- package/dist/swagger_client/models/user-key-response.js +0 -2
- package/dist/swagger_client/models/user-success-response.d.ts +0 -24
- package/dist/swagger_client/models/user-success-response.js +0 -2
- package/dist/swagger_client/models/validation-error.d.ts +0 -36
- package/dist/swagger_client/models/validation-error.js +0 -2
- package/dist/swagger_client/models/webhook-register.d.ts +0 -36
- package/dist/swagger_client/models/webhook-register.js +0 -2
- package/dist/swagger_client/models/webhook-type.d.ts +0 -24
- package/dist/swagger_client/models/webhook-type.js +0 -30
- package/dist/test/data/mock_webhook.d.ts +0 -49
- package/dist/test/data/mock_webhook.js +0 -170
- package/dist/test/webhook.spec.d.ts +0 -1
- package/dist/test/webhook.spec.js +0 -160
- package/test/data/mock_webhook.ts +0 -167
- package/test/webhook.spec.ts +0 -254
@@ -1,160 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
var webhooks = require("../client/lib/WebhookVerification");
|
4
|
-
var api = require("../client/Webhooks");
|
5
|
-
var mocha_1 = require("mocha");
|
6
|
-
var mock_webhook_1 = require("./data/mock_webhook");
|
7
|
-
var axios_1 = require("axios");
|
8
|
-
var axiosInstance = axios_1.default.create({
|
9
|
-
baseURL: 'https://some-domain.com/api/',
|
10
|
-
timeout: 1000,
|
11
|
-
headers: { 'X-Custom-Header': 'foobar' }
|
12
|
-
});
|
13
|
-
var expect = require('chai').expect; // eslint-disable-line
|
14
|
-
var EVENT_PAYLOAD = mock_webhook_1.mockWebhookData;
|
15
|
-
var EVENT_PAYLOAD_STRING = JSON.stringify(EVENT_PAYLOAD, null, 2);
|
16
|
-
var SECRET = 'whsec_test_secret';
|
17
|
-
mocha_1.describe('Webhooks', function () {
|
18
|
-
mocha_1.describe('.generateTestHeaderString', function () {
|
19
|
-
mocha_1.it('should throw when no opts are passed', function () {
|
20
|
-
expect(function () {
|
21
|
-
// @ts-ignore
|
22
|
-
webhooks.generateTestHeaderString();
|
23
|
-
}).to.throw();
|
24
|
-
});
|
25
|
-
mocha_1.it('should correctly construct a webhook header', function () {
|
26
|
-
var header = webhooks.generateTestHeaderString({
|
27
|
-
payload: EVENT_PAYLOAD_STRING,
|
28
|
-
secret: SECRET,
|
29
|
-
});
|
30
|
-
expect(header).to.not.be.undefined; //eslint-disable
|
31
|
-
expect(header.split(',')).to.have.lengthOf(2);
|
32
|
-
});
|
33
|
-
});
|
34
|
-
mocha_1.describe('.constructWebhookEvent', function () {
|
35
|
-
mocha_1.it('should return an Event instance from a valid JSON payload and valid signature header', function () {
|
36
|
-
var _a;
|
37
|
-
var header = webhooks.generateTestHeaderString({
|
38
|
-
payload: EVENT_PAYLOAD_STRING,
|
39
|
-
secret: SECRET,
|
40
|
-
});
|
41
|
-
var event = new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(EVENT_PAYLOAD_STRING, header, SECRET);
|
42
|
-
// @ts-ignore
|
43
|
-
expect((_a = event.data) === null || _a === void 0 ? void 0 : _a.id).to.equal(EVENT_PAYLOAD.data.id);
|
44
|
-
});
|
45
|
-
mocha_1.it('should raise a JSON error from invalid JSON payload', function () {
|
46
|
-
var header = webhooks.generateTestHeaderString({
|
47
|
-
payload: '} I am not valid JSON; 123][',
|
48
|
-
secret: SECRET,
|
49
|
-
});
|
50
|
-
expect(function () {
|
51
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent('} I am not valid JSON; 123][', header, SECRET);
|
52
|
-
}).to.throw(/Unexpected token/);
|
53
|
-
expect(function () {
|
54
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent('} I am not valid JSON; 123][', header, SECRET);
|
55
|
-
}).to.throw(/Unexpected token/);
|
56
|
-
});
|
57
|
-
mocha_1.it('should raise a SignatureVerificationError from a valid JSON payload and an invalid signature header', function () {
|
58
|
-
var header = 'bad_header';
|
59
|
-
expect(function () {
|
60
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(EVENT_PAYLOAD_STRING, header, SECRET);
|
61
|
-
}).to.throw(/Unable to extract timestamp and signatures from header/);
|
62
|
-
});
|
63
|
-
mocha_1.it('should error if you pass a signature which is an array, even though our types say you can', function () {
|
64
|
-
var header = webhooks.generateTestHeaderString({
|
65
|
-
payload: EVENT_PAYLOAD_STRING,
|
66
|
-
secret: SECRET,
|
67
|
-
});
|
68
|
-
expect(function () {
|
69
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(EVENT_PAYLOAD_STRING,
|
70
|
-
// @ts-ignore
|
71
|
-
[header], SECRET);
|
72
|
-
}).to.throw('Unexpected: An array was passed as a header, which should not be possible for the vital-signature header.');
|
73
|
-
});
|
74
|
-
});
|
75
|
-
mocha_1.describe('.verifySignatureHeader', function () {
|
76
|
-
mocha_1.it('should raise a SignatureVerificationError when the header does not have the expected format', function () {
|
77
|
-
var header = "I'm not even a real signature header";
|
78
|
-
var expectedMessage = /Unable to extract timestamp and signatures from header/;
|
79
|
-
expect(function () {
|
80
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
81
|
-
}).to.throw(expectedMessage);
|
82
|
-
expect(function () {
|
83
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, null, SECRET);
|
84
|
-
}).to.throw(expectedMessage);
|
85
|
-
expect(function () {
|
86
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, undefined, SECRET);
|
87
|
-
}).to.throw(expectedMessage);
|
88
|
-
expect(function () {
|
89
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, '', SECRET);
|
90
|
-
}).to.throw(expectedMessage);
|
91
|
-
});
|
92
|
-
mocha_1.it('should raise a SignatureVerificationError when there are no signatures with the expected scheme', function () {
|
93
|
-
var header = webhooks.generateTestHeaderString({
|
94
|
-
payload: EVENT_PAYLOAD_STRING,
|
95
|
-
secret: SECRET,
|
96
|
-
scheme: 'v0',
|
97
|
-
});
|
98
|
-
expect(function () {
|
99
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
100
|
-
}).to.throw(/No signatures found with expected scheme/);
|
101
|
-
});
|
102
|
-
mocha_1.it('should raise a SignatureVerificationError when there are no valid signatures for the payload', function () {
|
103
|
-
var header = webhooks.generateTestHeaderString({
|
104
|
-
payload: EVENT_PAYLOAD_STRING,
|
105
|
-
secret: SECRET,
|
106
|
-
signature: 'bad_signature',
|
107
|
-
});
|
108
|
-
expect(function () {
|
109
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
110
|
-
}).to.throw(/No signatures found matching the expected signature for payload/);
|
111
|
-
});
|
112
|
-
mocha_1.it('should raise a SignatureVerificationError when the timestamp is not within the tolerance', function () {
|
113
|
-
var header = webhooks.generateTestHeaderString({
|
114
|
-
timestamp: Date.now() / 1000 - 15,
|
115
|
-
payload: EVENT_PAYLOAD_STRING,
|
116
|
-
secret: SECRET,
|
117
|
-
});
|
118
|
-
expect(function () {
|
119
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET, 10);
|
120
|
-
}).to.throw(/Timestamp outside the tolerance zone/);
|
121
|
-
});
|
122
|
-
mocha_1.it('should return true when the header contains a valid signature and ' +
|
123
|
-
'the timestamp is within the tolerance', function () {
|
124
|
-
var header = webhooks.generateTestHeaderString({
|
125
|
-
timestamp: Date.now() / 1000,
|
126
|
-
payload: EVENT_PAYLOAD_STRING,
|
127
|
-
secret: SECRET,
|
128
|
-
});
|
129
|
-
expect(webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET, 10)).to.equal(true);
|
130
|
-
});
|
131
|
-
mocha_1.it('should return true when the header contains at least one valid signature', function () {
|
132
|
-
var header = webhooks.generateTestHeaderString({
|
133
|
-
timestamp: Date.now() / 1000,
|
134
|
-
payload: EVENT_PAYLOAD_STRING,
|
135
|
-
secret: SECRET,
|
136
|
-
});
|
137
|
-
header += ',v1=potato';
|
138
|
-
expect(webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET, 10)).to.equal(true);
|
139
|
-
});
|
140
|
-
mocha_1.it('should return true when the header contains a valid signature ' +
|
141
|
-
'and the timestamp is off but no tolerance is provided', function () {
|
142
|
-
var header = webhooks.generateTestHeaderString({
|
143
|
-
timestamp: 12345,
|
144
|
-
payload: EVENT_PAYLOAD_STRING,
|
145
|
-
secret: SECRET,
|
146
|
-
});
|
147
|
-
expect(webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET)).to.equal(true);
|
148
|
-
});
|
149
|
-
mocha_1.it('should accept Buffer instances for the payload and header', function () {
|
150
|
-
var header = webhooks.generateTestHeaderString({
|
151
|
-
timestamp: Date.now() / 1000,
|
152
|
-
payload: EVENT_PAYLOAD_STRING,
|
153
|
-
secret: SECRET,
|
154
|
-
});
|
155
|
-
expect(webhooks.signature.verifyHeader(
|
156
|
-
// @ts-ignore
|
157
|
-
Buffer.from(EVENT_PAYLOAD_STRING), Buffer.from(header), SECRET, 10)).to.equal(true);
|
158
|
-
});
|
159
|
-
});
|
160
|
-
});
|
@@ -1,167 +0,0 @@
|
|
1
|
-
// @ts-nocheck
|
2
|
-
export const mockWebhookData = {
|
3
|
-
event_type: 'workouts',
|
4
|
-
data: {
|
5
|
-
id: '85b9fb9c-ebc1-4187-a506-49ecf2c27000',
|
6
|
-
title: null,
|
7
|
-
average_hr: 151,
|
8
|
-
max_hr: 175,
|
9
|
-
distance: null,
|
10
|
-
time_start: '2021-08-12T16:13:57.406000+00:00',
|
11
|
-
time_end: '2021-08-12T17:03:27.832000+00:00',
|
12
|
-
calories: 680.0,
|
13
|
-
sport: { id: 53, name: 'Gymnastics' },
|
14
|
-
source: {
|
15
|
-
name: 'Whoop',
|
16
|
-
slug: 'whoop',
|
17
|
-
logo: 'https://storage.googleapis.com/vital-assets/whoop.png',
|
18
|
-
},
|
19
|
-
hr_zones: [14, 62, 312, 607, 1773, 199],
|
20
|
-
user_id: 'e67a8c73-5639-48be-83fe-1657d63e1aea',
|
21
|
-
moving_time: null,
|
22
|
-
total_elevation_gain: null,
|
23
|
-
elev_high: null,
|
24
|
-
elev_low: null,
|
25
|
-
average_speed: null,
|
26
|
-
max_speed: null,
|
27
|
-
average_watts: null,
|
28
|
-
device_watts: null,
|
29
|
-
max_watts: null,
|
30
|
-
weighted_average_watts: null,
|
31
|
-
map: null,
|
32
|
-
stream: {
|
33
|
-
id: 23680,
|
34
|
-
cadence: null,
|
35
|
-
time: [
|
36
|
-
1628784837, 1628784844, 1628784850, 1628784857, 1628784864, 1628784871,
|
37
|
-
1628784877, 1628784884, 1628784891, 1628784897, 1628784904, 1628784911,
|
38
|
-
1628784918, 1628784924, 1628784931, 1628784938, 1628784945, 1628784951,
|
39
|
-
1628784958, 1628784965, 1628784971, 1628784978, 1628784985, 1628784992,
|
40
|
-
1628784998, 1628785005, 1628785012, 1628785019, 1628785025, 1628785032,
|
41
|
-
1628785039, 1628785046, 1628785052, 1628785059, 1628785066, 1628785072,
|
42
|
-
1628785079, 1628785086, 1628785093, 1628785099, 1628785106, 1628785113,
|
43
|
-
1628785120, 1628785126, 1628785133, 1628785140, 1628785146, 1628785153,
|
44
|
-
1628785160, 1628785167, 1628785173, 1628785180, 1628785187, 1628785194,
|
45
|
-
1628785200, 1628785207, 1628785214, 1628785220, 1628785227, 1628785234,
|
46
|
-
1628785241, 1628785247, 1628785254, 1628785261, 1628785268, 1628785274,
|
47
|
-
1628785281, 1628785288, 1628785294, 1628785301, 1628785308, 1628785315,
|
48
|
-
1628785321, 1628785328, 1628785335, 1628785342, 1628785348, 1628785355,
|
49
|
-
1628785362, 1628785369, 1628785375, 1628785382, 1628785389, 1628785395,
|
50
|
-
1628785402, 1628785409, 1628785416, 1628785422, 1628785429, 1628785436,
|
51
|
-
1628785443, 1628785449, 1628785456, 1628785463, 1628785469, 1628785476,
|
52
|
-
1628785483, 1628785490, 1628785496, 1628785503, 1628785510, 1628785517,
|
53
|
-
1628785523, 1628785530, 1628785537, 1628785543, 1628785550, 1628785557,
|
54
|
-
1628785564, 1628785570, 1628785577, 1628785584, 1628785591, 1628785597,
|
55
|
-
1628785604, 1628785611, 1628785617, 1628785624, 1628785631, 1628785638,
|
56
|
-
1628785644, 1628785651, 1628785658, 1628785665, 1628785671, 1628785678,
|
57
|
-
1628785686, 1628785692, 1628785699, 1628785706, 1628785713, 1628785719,
|
58
|
-
1628785726, 1628785733, 1628785740, 1628785746, 1628785753, 1628785760,
|
59
|
-
1628785766, 1628785773, 1628785780, 1628785787, 1628785793, 1628785800,
|
60
|
-
1628785807, 1628785814, 1628785820, 1628785827, 1628785834, 1628785841,
|
61
|
-
1628785847, 1628785854, 1628785861, 1628785867, 1628785874, 1628785881,
|
62
|
-
1628785888, 1628785894, 1628785901, 1628785908, 1628785915, 1628785921,
|
63
|
-
1628785928, 1628785935, 1628785941, 1628785948, 1628785955, 1628785962,
|
64
|
-
1628785968, 1628785975, 1628785982, 1628785989, 1628785995, 1628786002,
|
65
|
-
1628786009, 1628786015, 1628786022, 1628786029, 1628786036, 1628786042,
|
66
|
-
1628786049, 1628786056, 1628786063, 1628786069, 1628786076, 1628786083,
|
67
|
-
1628786089, 1628786096, 1628786103, 1628786110, 1628786116, 1628786123,
|
68
|
-
1628786130, 1628786137, 1628786143, 1628786150, 1628786157, 1628786164,
|
69
|
-
1628786170, 1628786177, 1628786184, 1628786190, 1628786197, 1628786204,
|
70
|
-
1628786211, 1628786217, 1628786224, 1628786231, 1628786238, 1628786244,
|
71
|
-
1628786251, 1628786258, 1628786264, 1628786271, 1628786278, 1628786285,
|
72
|
-
1628786291, 1628786298, 1628786305, 1628786312, 1628786318, 1628786325,
|
73
|
-
1628786332, 1628786338, 1628786345, 1628786352, 1628786359, 1628786365,
|
74
|
-
1628786372, 1628786379, 1628786386, 1628786392, 1628786399, 1628786406,
|
75
|
-
1628786412, 1628786419, 1628786426, 1628786433, 1628786439, 1628786446,
|
76
|
-
1628786453, 1628786460, 1628786466, 1628786473, 1628786480, 1628786487,
|
77
|
-
1628786493, 1628786500, 1628786507, 1628786513, 1628786520, 1628786527,
|
78
|
-
1628786534, 1628786540, 1628786547, 1628786554, 1628786561, 1628786567,
|
79
|
-
1628786574, 1628786581, 1628786587, 1628786594, 1628786601, 1628786608,
|
80
|
-
1628786614, 1628786621, 1628786628, 1628786635, 1628786641, 1628786648,
|
81
|
-
1628786655, 1628786661, 1628786668, 1628786675, 1628786682, 1628786688,
|
82
|
-
1628786695, 1628786702, 1628786709, 1628786715, 1628786722, 1628786729,
|
83
|
-
1628786735, 1628786742, 1628786749, 1628786756, 1628786762, 1628786769,
|
84
|
-
1628786776, 1628786783, 1628786789, 1628786796, 1628786803, 1628786809,
|
85
|
-
1628786816, 1628786823, 1628786830, 1628786836, 1628786843, 1628786850,
|
86
|
-
1628786857, 1628786864, 1628786871, 1628786878, 1628786884, 1628786891,
|
87
|
-
1628786899, 1628786906, 1628786912, 1628786919, 1628786926, 1628786933,
|
88
|
-
1628786939, 1628786946, 1628786953, 1628786959, 1628786966, 1628786973,
|
89
|
-
1628786980, 1628786987, 1628786994, 1628787001, 1628787008, 1628787014,
|
90
|
-
1628787021, 1628787028, 1628787034, 1628787041, 1628787048, 1628787055,
|
91
|
-
1628787061, 1628787068, 1628787075, 1628787082, 1628787088, 1628787095,
|
92
|
-
1628787102, 1628787108, 1628787115, 1628787122, 1628787129, 1628787135,
|
93
|
-
1628787142, 1628787149, 1628787156, 1628787162, 1628787169, 1628787176,
|
94
|
-
1628787182, 1628787189, 1628787196, 1628787203, 1628787209, 1628787216,
|
95
|
-
1628787223, 1628787230, 1628787236, 1628787243, 1628787250, 1628787257,
|
96
|
-
1628787263, 1628787270, 1628787277, 1628787283, 1628787290, 1628787297,
|
97
|
-
1628787304, 1628787310, 1628787317, 1628787324, 1628787331, 1628787337,
|
98
|
-
1628787344, 1628787351, 1628787357, 1628787364, 1628787371, 1628787378,
|
99
|
-
1628787384, 1628787391, 1628787398, 1628787405, 1628787411, 1628787418,
|
100
|
-
1628787425, 1628787431, 1628787438, 1628787445, 1628787452, 1628787458,
|
101
|
-
1628787465, 1628787472, 1628787479, 1628787485, 1628787492, 1628787499,
|
102
|
-
1628787505, 1628787512, 1628787519, 1628787526, 1628787532, 1628787539,
|
103
|
-
1628787546, 1628787553, 1628787559, 1628787566, 1628787573, 1628787580,
|
104
|
-
1628787586, 1628787593, 1628787600, 1628787606, 1628787613, 1628787620,
|
105
|
-
1628787627, 1628787633, 1628787640, 1628787647, 1628787654, 1628787660,
|
106
|
-
1628787667, 1628787674, 1628787680, 1628787687, 1628787694, 1628787701,
|
107
|
-
1628787707, 1628787714, 1628787721, 1628787728, 1628787734, 1628787741,
|
108
|
-
1628787748, 1628787754, 1628787761, 1628787768, 1628787775, 1628787781,
|
109
|
-
1628787788, 1628787795, 1628787802,
|
110
|
-
],
|
111
|
-
altitude: null,
|
112
|
-
velocity_smooth: null,
|
113
|
-
heartrate: [
|
114
|
-
94.0, 96.0, 97.0, 95.0, 96.0, 97.0, 99.0, 100.0, 107.0, 107.0, 109.0,
|
115
|
-
110.0, 119.0, 120.0, 122.0, 127.0, 127.0, 126.0, 125.0, 126.0, 131.0,
|
116
|
-
132.0, 132.0, 130.0, 130.0, 131.0, 133.0, 136.0, 141.0, 146.0, 147.0,
|
117
|
-
152.0, 153.0, 154.0, 155.0, 157.0, 159.0, 159.0, 162.0, 161.0, 160.0,
|
118
|
-
159.0, 156.0, 155.0, 154.0, 153.0, 154.0, 157.0, 157.0, 157.0, 156.0,
|
119
|
-
157.0, 157.0, 156.0, 154.0, 153.0, 152.0, 150.0, 149.0, 148.0, 144.0,
|
120
|
-
141.0, 140.0, 140.0, 139.0, 139.0, 137.0, 137.0, 136.0, 135.0, 130.0,
|
121
|
-
127.0, 126.0, 125.0, 122.0, 120.0, 120.0, 120.0, 118.0, 118.0, 119.0,
|
122
|
-
120.0, 122.0, 123.0, 125.0, 126.0, 127.0, 129.0, 130.0, 133.0, 135.0,
|
123
|
-
136.0, 137.0, 141.0, 141.0, 142.0, 151.0, 151.0, 144.0, 140.0, 139.0,
|
124
|
-
136.0, 133.0, 136.0, 135.0, 138.0, 139.0, 146.0, 147.0, 149.0, 152.0,
|
125
|
-
151.0, 151.0, 151.0, 153.0, 153.0, 157.0, 159.0, 159.0, 157.0, 156.0,
|
126
|
-
153.0, 155.0, 151.0, 151.0, 151.0, 153.0, 154.0, 155.0, 155.0, 155.0,
|
127
|
-
155.0, 152.0, 151.0, 151.0, 150.0, 152.0, 152.0, 150.0, 151.0, 152.0,
|
128
|
-
151.0, 150.0, 146.0, 143.0, 138.0, 140.0, 146.0, 146.0, 147.0, 151.0,
|
129
|
-
152.0, 153.0, 154.0, 157.0, 158.0, 158.0, 158.0, 159.0, 163.0, 162.0,
|
130
|
-
160.0, 158.0, 158.0, 157.0, 153.0, 152.0, 151.0, 153.0, 156.0, 157.0,
|
131
|
-
160.0, 161.0, 161.0, 162.0, 163.0, 163.0, 163.0, 164.0, 165.0, 165.0,
|
132
|
-
164.0, 165.0, 165.0, 165.0, 167.0, 167.0, 167.0, 166.0, 165.0, 164.0,
|
133
|
-
164.0, 162.0, 162.0, 163.0, 164.0, 165.0, 165.0, 165.0, 166.0, 166.0,
|
134
|
-
166.0, 166.0, 166.0, 166.0, 167.0, 167.0, 166.0, 166.0, 166.0, 166.0,
|
135
|
-
163.0, 162.0, 161.0, 160.0, 164.0, 164.0, 163.0, 158.0, 157.0, 158.0,
|
136
|
-
160.0, 161.0, 161.0, 158.0, 155.0, 153.0, 153.0, 156.0, 154.0, 155.0,
|
137
|
-
163.0, 165.0, 169.0, 171.0, 172.0, 173.0, 173.0, 174.0, 174.0, 174.0,
|
138
|
-
174.0, 171.0, 170.0, 172.0, 171.0, 169.0, 165.0, 171.0, 172.0, 171.0,
|
139
|
-
169.0, 168.0, 167.0, 166.0, 166.0, 165.0, 161.0, 164.0, 166.0, 167.0,
|
140
|
-
168.0, 168.0, 168.0, 168.0, 168.0, 168.0, 169.0, 171.0, 172.0, 173.0,
|
141
|
-
172.0, 171.0, 171.0, 172.0, 173.0, 171.0, 170.0, 170.0, 171.0, 172.0,
|
142
|
-
172.0, 172.0, 171.0, 170.0, 172.0, 172.0, 172.0, 172.0, 172.0, 172.0,
|
143
|
-
171.0, 172.0, 172.0, 169.0, 170.0, 169.0, 170.0, 171.0, 171.0, 171.0,
|
144
|
-
168.0, 167.0, 167.0, 165.0, 165.0, 170.0, 171.0, 171.0, 169.0, 173.0,
|
145
|
-
174.0, 171.0, 163.0, 165.0, 164.0, 163.0, 159.0, 160.0, 161.0, 161.0,
|
146
|
-
160.0, 160.0, 160.0, 159.0, 156.0, 155.0, 155.0, 154.0, 155.0, 156.0,
|
147
|
-
153.0, 156.0, 156.0, 156.0, 157.0, 157.0, 160.0, 160.0, 160.0, 162.0,
|
148
|
-
162.0, 165.0, 162.0, 162.0, 165.0, 160.0, 160.0, 162.0, 163.0, 163.0,
|
149
|
-
162.0, 166.0, 169.0, 164.0, 158.0, 156.0, 161.0, 158.0, 157.0, 158.0,
|
150
|
-
148.0, 142.0, 141.0, 136.0, 136.0, 137.0, 137.0, 140.0, 139.0, 140.0,
|
151
|
-
140.0, 135.0, 129.0, 128.0, 131.0, 130.0, 128.0, 129.0, 129.0, 130.0,
|
152
|
-
129.0, 129.0, 135.0, 137.0, 138.0, 136.0, 138.0, 134.0, 136.0, 137.0,
|
153
|
-
151.0, 153.0, 154.0, 158.0, 161.0, 165.0, 166.0, 169.0, 169.0, 169.0,
|
154
|
-
169.0, 168.0, 169.0, 170.0, 170.0, 169.0, 169.0, 170.0, 170.0, 171.0,
|
155
|
-
172.0, 171.0, 167.0, 164.0, 159.0, 158.0, 152.0, 152.0, 153.0, 153.0,
|
156
|
-
155.0, 156.0, 156.0, 157.0, 158.0, 159.0, 160.0, 161.0, 165.0, 167.0,
|
157
|
-
168.0, 168.0, 169.0, 170.0, 170.0, 170.0, 170.0, 170.0, 170.0, 169.0,
|
158
|
-
],
|
159
|
-
lat: null,
|
160
|
-
lng: null,
|
161
|
-
distance: null,
|
162
|
-
power: null,
|
163
|
-
resistance: null,
|
164
|
-
},
|
165
|
-
},
|
166
|
-
event_code: 'UPDATED',
|
167
|
-
};
|
package/test/webhook.spec.ts
DELETED
@@ -1,254 +0,0 @@
|
|
1
|
-
import * as webhooks from '../client/lib/WebhookVerification';
|
2
|
-
import * as api from '../client/Webhooks';
|
3
|
-
import { describe, it } from 'mocha';
|
4
|
-
import { mockWebhookData } from './data/mock_webhook';
|
5
|
-
import axios from 'axios';
|
6
|
-
|
7
|
-
|
8
|
-
const axiosInstance = axios.create({
|
9
|
-
baseURL: 'https://some-domain.com/api/',
|
10
|
-
timeout: 1000,
|
11
|
-
headers: {'X-Custom-Header': 'foobar'}
|
12
|
-
});
|
13
|
-
|
14
|
-
|
15
|
-
const expect = require('chai').expect; // eslint-disable-line
|
16
|
-
|
17
|
-
const EVENT_PAYLOAD = mockWebhookData;
|
18
|
-
const EVENT_PAYLOAD_STRING = JSON.stringify(EVENT_PAYLOAD, null, 2);
|
19
|
-
const SECRET = 'whsec_test_secret';
|
20
|
-
|
21
|
-
describe('Webhooks', () => {
|
22
|
-
describe('.generateTestHeaderString', () => {
|
23
|
-
it('should throw when no opts are passed', () => {
|
24
|
-
expect(() => {
|
25
|
-
// @ts-ignore
|
26
|
-
webhooks.generateTestHeaderString();
|
27
|
-
}).to.throw();
|
28
|
-
});
|
29
|
-
|
30
|
-
it('should correctly construct a webhook header', () => {
|
31
|
-
const header = webhooks.generateTestHeaderString({
|
32
|
-
payload: EVENT_PAYLOAD_STRING,
|
33
|
-
secret: SECRET,
|
34
|
-
});
|
35
|
-
|
36
|
-
expect(header).to.not.be.undefined; //eslint-disable
|
37
|
-
expect(header.split(',')).to.have.lengthOf(2);
|
38
|
-
});
|
39
|
-
});
|
40
|
-
|
41
|
-
describe('.constructWebhookEvent', () => {
|
42
|
-
it('should return an Event instance from a valid JSON payload and valid signature header', () => {
|
43
|
-
const header = webhooks.generateTestHeaderString({
|
44
|
-
payload: EVENT_PAYLOAD_STRING,
|
45
|
-
secret: SECRET,
|
46
|
-
});
|
47
|
-
|
48
|
-
const event = new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(
|
49
|
-
EVENT_PAYLOAD_STRING,
|
50
|
-
header,
|
51
|
-
SECRET
|
52
|
-
);
|
53
|
-
// @ts-ignore
|
54
|
-
expect(event.data?.id).to.equal(EVENT_PAYLOAD.data.id);
|
55
|
-
});
|
56
|
-
|
57
|
-
it('should raise a JSON error from invalid JSON payload', () => {
|
58
|
-
const header = webhooks.generateTestHeaderString({
|
59
|
-
payload: '} I am not valid JSON; 123][',
|
60
|
-
secret: SECRET,
|
61
|
-
});
|
62
|
-
expect(() => {
|
63
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(
|
64
|
-
'} I am not valid JSON; 123][',
|
65
|
-
header,
|
66
|
-
SECRET
|
67
|
-
);
|
68
|
-
}).to.throw(/Unexpected token/);
|
69
|
-
expect(() => {
|
70
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(
|
71
|
-
'} I am not valid JSON; 123][',
|
72
|
-
header,
|
73
|
-
SECRET
|
74
|
-
);
|
75
|
-
}).to.throw(/Unexpected token/);
|
76
|
-
});
|
77
|
-
|
78
|
-
it('should raise a SignatureVerificationError from a valid JSON payload and an invalid signature header', () => {
|
79
|
-
const header = 'bad_header';
|
80
|
-
|
81
|
-
expect(() => {
|
82
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(
|
83
|
-
EVENT_PAYLOAD_STRING,
|
84
|
-
header,
|
85
|
-
SECRET
|
86
|
-
);
|
87
|
-
}).to.throw(/Unable to extract timestamp and signatures from header/);
|
88
|
-
});
|
89
|
-
|
90
|
-
it('should error if you pass a signature which is an array, even though our types say you can', () => {
|
91
|
-
const header = webhooks.generateTestHeaderString({
|
92
|
-
payload: EVENT_PAYLOAD_STRING,
|
93
|
-
secret: SECRET,
|
94
|
-
});
|
95
|
-
|
96
|
-
expect(() => {
|
97
|
-
new api.WebhooksApi("base_url", axiosInstance).constructWebhookEvent(
|
98
|
-
EVENT_PAYLOAD_STRING,
|
99
|
-
// @ts-ignore
|
100
|
-
[header],
|
101
|
-
SECRET
|
102
|
-
);
|
103
|
-
}).to.throw(
|
104
|
-
'Unexpected: An array was passed as a header, which should not be possible for the vital-signature header.'
|
105
|
-
);
|
106
|
-
});
|
107
|
-
});
|
108
|
-
|
109
|
-
describe('.verifySignatureHeader', () => {
|
110
|
-
it('should raise a SignatureVerificationError when the header does not have the expected format', () => {
|
111
|
-
const header = "I'm not even a real signature header";
|
112
|
-
|
113
|
-
const expectedMessage =
|
114
|
-
/Unable to extract timestamp and signatures from header/;
|
115
|
-
|
116
|
-
expect(() => {
|
117
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
118
|
-
}).to.throw(expectedMessage);
|
119
|
-
|
120
|
-
expect(() => {
|
121
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, null, SECRET);
|
122
|
-
}).to.throw(expectedMessage);
|
123
|
-
|
124
|
-
expect(() => {
|
125
|
-
webhooks.signature.verifyHeader(
|
126
|
-
EVENT_PAYLOAD_STRING,
|
127
|
-
undefined,
|
128
|
-
SECRET
|
129
|
-
);
|
130
|
-
}).to.throw(expectedMessage);
|
131
|
-
|
132
|
-
expect(() => {
|
133
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, '', SECRET);
|
134
|
-
}).to.throw(expectedMessage);
|
135
|
-
});
|
136
|
-
|
137
|
-
it('should raise a SignatureVerificationError when there are no signatures with the expected scheme', () => {
|
138
|
-
const header = webhooks.generateTestHeaderString({
|
139
|
-
payload: EVENT_PAYLOAD_STRING,
|
140
|
-
secret: SECRET,
|
141
|
-
scheme: 'v0',
|
142
|
-
});
|
143
|
-
|
144
|
-
expect(() => {
|
145
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
146
|
-
}).to.throw(/No signatures found with expected scheme/);
|
147
|
-
});
|
148
|
-
|
149
|
-
it('should raise a SignatureVerificationError when there are no valid signatures for the payload', () => {
|
150
|
-
const header = webhooks.generateTestHeaderString({
|
151
|
-
payload: EVENT_PAYLOAD_STRING,
|
152
|
-
secret: SECRET,
|
153
|
-
signature: 'bad_signature',
|
154
|
-
});
|
155
|
-
|
156
|
-
expect(() => {
|
157
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET);
|
158
|
-
}).to.throw(
|
159
|
-
/No signatures found matching the expected signature for payload/
|
160
|
-
);
|
161
|
-
});
|
162
|
-
|
163
|
-
it('should raise a SignatureVerificationError when the timestamp is not within the tolerance', () => {
|
164
|
-
const header = webhooks.generateTestHeaderString({
|
165
|
-
timestamp: Date.now() / 1000 - 15,
|
166
|
-
payload: EVENT_PAYLOAD_STRING,
|
167
|
-
secret: SECRET,
|
168
|
-
});
|
169
|
-
|
170
|
-
expect(() => {
|
171
|
-
webhooks.signature.verifyHeader(
|
172
|
-
EVENT_PAYLOAD_STRING,
|
173
|
-
header,
|
174
|
-
SECRET,
|
175
|
-
10
|
176
|
-
);
|
177
|
-
}).to.throw(/Timestamp outside the tolerance zone/);
|
178
|
-
});
|
179
|
-
|
180
|
-
it(
|
181
|
-
'should return true when the header contains a valid signature and ' +
|
182
|
-
'the timestamp is within the tolerance',
|
183
|
-
() => {
|
184
|
-
const header = webhooks.generateTestHeaderString({
|
185
|
-
timestamp: Date.now() / 1000,
|
186
|
-
payload: EVENT_PAYLOAD_STRING,
|
187
|
-
secret: SECRET,
|
188
|
-
});
|
189
|
-
|
190
|
-
expect(
|
191
|
-
webhooks.signature.verifyHeader(
|
192
|
-
EVENT_PAYLOAD_STRING,
|
193
|
-
header,
|
194
|
-
SECRET,
|
195
|
-
10
|
196
|
-
)
|
197
|
-
).to.equal(true);
|
198
|
-
}
|
199
|
-
);
|
200
|
-
|
201
|
-
it('should return true when the header contains at least one valid signature', () => {
|
202
|
-
let header = webhooks.generateTestHeaderString({
|
203
|
-
timestamp: Date.now() / 1000,
|
204
|
-
payload: EVENT_PAYLOAD_STRING,
|
205
|
-
secret: SECRET,
|
206
|
-
});
|
207
|
-
|
208
|
-
header += ',v1=potato';
|
209
|
-
|
210
|
-
expect(
|
211
|
-
webhooks.signature.verifyHeader(
|
212
|
-
EVENT_PAYLOAD_STRING,
|
213
|
-
header,
|
214
|
-
SECRET,
|
215
|
-
10
|
216
|
-
)
|
217
|
-
).to.equal(true);
|
218
|
-
});
|
219
|
-
|
220
|
-
it(
|
221
|
-
'should return true when the header contains a valid signature ' +
|
222
|
-
'and the timestamp is off but no tolerance is provided',
|
223
|
-
() => {
|
224
|
-
const header = webhooks.generateTestHeaderString({
|
225
|
-
timestamp: 12345,
|
226
|
-
payload: EVENT_PAYLOAD_STRING,
|
227
|
-
secret: SECRET,
|
228
|
-
});
|
229
|
-
|
230
|
-
expect(
|
231
|
-
webhooks.signature.verifyHeader(EVENT_PAYLOAD_STRING, header, SECRET)
|
232
|
-
).to.equal(true);
|
233
|
-
}
|
234
|
-
);
|
235
|
-
|
236
|
-
it('should accept Buffer instances for the payload and header', () => {
|
237
|
-
const header = webhooks.generateTestHeaderString({
|
238
|
-
timestamp: Date.now() / 1000,
|
239
|
-
payload: EVENT_PAYLOAD_STRING,
|
240
|
-
secret: SECRET,
|
241
|
-
});
|
242
|
-
|
243
|
-
expect(
|
244
|
-
webhooks.signature.verifyHeader(
|
245
|
-
// @ts-ignore
|
246
|
-
Buffer.from(EVENT_PAYLOAD_STRING),
|
247
|
-
Buffer.from(header),
|
248
|
-
SECRET,
|
249
|
-
10
|
250
|
-
)
|
251
|
-
).to.equal(true);
|
252
|
-
});
|
253
|
-
});
|
254
|
-
});
|