pryv 3.0.3 → 3.1.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/package.json +1 -1
- package/src/Connection.js +57 -3
- package/src/Service.js +376 -6
- package/src/index.d.ts +114 -2
- package/src/index.js +7 -1
- package/src/lib/MfaRequiredError.js +46 -0
- package/src/lib/PryvError.js +38 -4
- package/src/lib/StaleAccessIdError.js +40 -0
- package/src/lib/errorIds.js +67 -0
- package/src/utils.js +50 -0
- package/test/Connection.test.js +26 -0
- package/test/PryvError.test.js +34 -0
- package/test/Service.accessRequest.test.js +78 -0
- package/test/Service.createUser.test.js +104 -0
- package/test/Service.hostings.test.js +53 -0
- package/test/Service.mfa.test.js +94 -0
- package/test/Service.passwordReset.test.js +87 -0
- package/test/Service.userExists.test.js +29 -0
- package/test/Service.userIdForEmail.test.js +30 -0
- package/test/utils.test.js +44 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
5
|
+
/* global describe, it, before, expect, pryv, testData */
|
|
6
|
+
|
|
7
|
+
const { createId: cuid } = require('@paralleldrive/cuid2');
|
|
8
|
+
|
|
9
|
+
describe('[PWRX] Service.requestPasswordReset', function () {
|
|
10
|
+
let service;
|
|
11
|
+
|
|
12
|
+
before(async function () {
|
|
13
|
+
this.timeout(15000);
|
|
14
|
+
await testData.prepare();
|
|
15
|
+
service = new pryv.Service(testData.serviceInfoUrl);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('[PWRA] rejects when required args are missing', async function () {
|
|
19
|
+
let caught;
|
|
20
|
+
try {
|
|
21
|
+
await service.requestPasswordReset(testData.username);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
caught = e;
|
|
24
|
+
}
|
|
25
|
+
expect(caught).to.be.instanceOf(pryv.PryvError);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('[PWRB] either resolves or throws PryvError (server may require trusted appId)', async function () {
|
|
29
|
+
this.timeout(15000);
|
|
30
|
+
// Pryv platforms typically restrict password-reset to a trusted-appId
|
|
31
|
+
// allowlist (pryv.me does). On a permissive deployment this resolves;
|
|
32
|
+
// on a stricter one we expect a structured PryvError, not a raw throw.
|
|
33
|
+
let caught;
|
|
34
|
+
try {
|
|
35
|
+
await service.requestPasswordReset(testData.username, 'jslib-test');
|
|
36
|
+
} catch (e) {
|
|
37
|
+
caught = e;
|
|
38
|
+
}
|
|
39
|
+
if (caught) {
|
|
40
|
+
expect(caught).to.be.instanceOf(pryv.PryvError);
|
|
41
|
+
expect(caught.status).to.be.gte(400);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
// Note: a "user does not exist" path can't be exercised against pryv.me
|
|
45
|
+
// because per-user DNS doesn't resolve for unregistered usernames — fetch
|
|
46
|
+
// throws TypeError before any HTTP exchange. That's an environmental
|
|
47
|
+
// limit, not a code path; the bogus-reset-token test below covers the
|
|
48
|
+
// server-side error-mapping equivalent.
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('[PWSX] Service.resetPassword', function () {
|
|
52
|
+
let service;
|
|
53
|
+
|
|
54
|
+
before(async function () {
|
|
55
|
+
this.timeout(15000);
|
|
56
|
+
await testData.prepare();
|
|
57
|
+
service = new pryv.Service(testData.serviceInfoUrl);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('[PWSA] rejects when required args are missing', async function () {
|
|
61
|
+
let caught;
|
|
62
|
+
try {
|
|
63
|
+
await service.resetPassword(testData.username, 'newpw', '', 'jslib-test');
|
|
64
|
+
} catch (e) {
|
|
65
|
+
caught = e;
|
|
66
|
+
}
|
|
67
|
+
expect(caught).to.be.instanceOf(pryv.PryvError);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('[PWSB] throws PryvError with structured fields on bogus reset token', async function () {
|
|
71
|
+
this.timeout(15000);
|
|
72
|
+
let caught;
|
|
73
|
+
try {
|
|
74
|
+
await service.resetPassword(
|
|
75
|
+
testData.username,
|
|
76
|
+
testData.password + 'X',
|
|
77
|
+
'bogus-reset-token-' + cuid().slice(0, 8),
|
|
78
|
+
'jslib-test'
|
|
79
|
+
);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
caught = e;
|
|
82
|
+
}
|
|
83
|
+
expect(caught).to.be.instanceOf(pryv.PryvError);
|
|
84
|
+
expect(caught.status).to.be.gte(400);
|
|
85
|
+
expect(caught.response).to.have.property('status');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
5
|
+
/* global describe, it, before, expect, pryv, testData */
|
|
6
|
+
|
|
7
|
+
const { createId: cuid } = require('@paralleldrive/cuid2');
|
|
8
|
+
|
|
9
|
+
describe('[USRX] Service.userExists', function () {
|
|
10
|
+
before(async function () {
|
|
11
|
+
this.timeout(15000);
|
|
12
|
+
await testData.prepare();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('[USRA] returns true for a registered user', async function () {
|
|
16
|
+
this.timeout(15000);
|
|
17
|
+
const service = new pryv.Service(testData.serviceInfoUrl);
|
|
18
|
+
const exists = await service.userExists(testData.username);
|
|
19
|
+
expect(exists).to.equal(true);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('[USRB] returns false for an unknown user (404)', async function () {
|
|
23
|
+
this.timeout(15000);
|
|
24
|
+
const service = new pryv.Service(testData.serviceInfoUrl);
|
|
25
|
+
const fakeUser = 'no-' + cuid().slice(0, 12);
|
|
26
|
+
const exists = await service.userExists(fakeUser);
|
|
27
|
+
expect(exists).to.equal(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
5
|
+
/* global describe, it, before, expect, pryv, testData */
|
|
6
|
+
|
|
7
|
+
const { createId: cuid } = require('@paralleldrive/cuid2');
|
|
8
|
+
|
|
9
|
+
describe('[UEMX] Service.userIdForEmail', function () {
|
|
10
|
+
before(async function () {
|
|
11
|
+
this.timeout(15000);
|
|
12
|
+
await testData.prepare();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('[UEMA] returns the username for a known email', async function () {
|
|
16
|
+
this.timeout(15000);
|
|
17
|
+
const service = new pryv.Service(testData.serviceInfoUrl);
|
|
18
|
+
const knownEmail = testData.username + '@pryv.io';
|
|
19
|
+
const userId = await service.userIdForEmail(knownEmail);
|
|
20
|
+
expect(userId).to.equal(testData.username);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('[UEMB] returns null for an unknown email', async function () {
|
|
24
|
+
this.timeout(15000);
|
|
25
|
+
const service = new pryv.Service(testData.serviceInfoUrl);
|
|
26
|
+
const unknownEmail = 'ghost-' + cuid().slice(0, 12) + '@example.com';
|
|
27
|
+
const userId = await service.userIdForEmail(unknownEmail);
|
|
28
|
+
expect(userId).to.equal(null);
|
|
29
|
+
});
|
|
30
|
+
});
|
package/test/utils.test.js
CHANGED
|
@@ -59,4 +59,48 @@ describe('[UTLX] utils', function () {
|
|
|
59
59
|
expect(apiEndpoint).to.equal(testData.apiEndpoint);
|
|
60
60
|
done();
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
// Plan 66 — composite access references.
|
|
64
|
+
|
|
65
|
+
it('[UTLF] parseAccessRef on a bare cuid returns { base, serial: null }', function () {
|
|
66
|
+
const ref = pryv.utils.parseAccessRef('abc123def456');
|
|
67
|
+
expect(ref).to.eql({ base: 'abc123def456', serial: null });
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('[UTLG] parseAccessRef on a composite returns { base, serial }', function () {
|
|
71
|
+
const ref = pryv.utils.parseAccessRef('abc123:7');
|
|
72
|
+
expect(ref).to.eql({ base: 'abc123', serial: 7 });
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('[UTLH] parseAccessRef on garbage throws', function () {
|
|
76
|
+
expect(() => pryv.utils.parseAccessRef('')).to.throw();
|
|
77
|
+
expect(() => pryv.utils.parseAccessRef(':1')).to.throw();
|
|
78
|
+
expect(() => pryv.utils.parseAccessRef('abc:notanumber')).to.throw();
|
|
79
|
+
expect(() => pryv.utils.parseAccessRef('abc:0')).to.throw();
|
|
80
|
+
expect(() => pryv.utils.parseAccessRef('abc:-1')).to.throw();
|
|
81
|
+
expect(() => pryv.utils.parseAccessRef(null)).to.throw();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('[UTLI] serializeAccessRef round-trips parseAccessRef', function () {
|
|
85
|
+
const samples = ['plainCuid', 'plainCuid:1', 'plainCuid:42'];
|
|
86
|
+
for (const s of samples) {
|
|
87
|
+
expect(pryv.utils.serializeAccessRef(pryv.utils.parseAccessRef(s))).to.equal(s);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('[UTLJ] serializeAccessRef rejects bad inputs', function () {
|
|
92
|
+
expect(() => pryv.utils.serializeAccessRef(null)).to.throw();
|
|
93
|
+
expect(() => pryv.utils.serializeAccessRef({ base: '' })).to.throw();
|
|
94
|
+
expect(() => pryv.utils.serializeAccessRef({ base: 'abc', serial: 0 })).to.throw();
|
|
95
|
+
expect(() => pryv.utils.serializeAccessRef({ base: 'abc', serial: 1.5 })).to.throw();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('[UTLK] StaleAccessIdError extends PryvError', function () {
|
|
99
|
+
const err = new pryv.StaleAccessIdError('stale!', { provided: 'abc:1', currentSerial: 2 });
|
|
100
|
+
expect(err).to.be.instanceOf(pryv.StaleAccessIdError);
|
|
101
|
+
expect(err).to.be.instanceOf(pryv.PryvError);
|
|
102
|
+
expect(err.data.provided).to.equal('abc:1');
|
|
103
|
+
expect(err.data.currentSerial).to.equal(2);
|
|
104
|
+
expect(err.name).to.equal('StaleAccessIdError');
|
|
105
|
+
});
|
|
62
106
|
});
|