pryv 2.1.8

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.
Files changed (43) hide show
  1. package/.jsdoc-conf.json +29 -0
  2. package/.mocharc.js +13 -0
  3. package/LICENSE.md +27 -0
  4. package/README.md +723 -0
  5. package/package.json +57 -0
  6. package/scripts/setup-environment-dev.sh +28 -0
  7. package/scripts/upload.sh +15 -0
  8. package/src/Auth/AuthController.js +276 -0
  9. package/src/Auth/AuthStates.js +20 -0
  10. package/src/Auth/LoginMessages.js +29 -0
  11. package/src/Auth/index.js +43 -0
  12. package/src/Browser/CookieUtils.js +51 -0
  13. package/src/Browser/LoginButton.js +199 -0
  14. package/src/Browser/index.js +55 -0
  15. package/src/Connection.js +331 -0
  16. package/src/Pryv.js +19 -0
  17. package/src/Service.js +197 -0
  18. package/src/ServiceAssets.js +162 -0
  19. package/src/index-socket.io-monitor.js +4 -0
  20. package/src/index.html +17 -0
  21. package/src/index.js +3 -0
  22. package/src/lib/browser-getEventStreamed.js +80 -0
  23. package/src/lib/json-parser.js +156 -0
  24. package/src/utils.js +136 -0
  25. package/test/Browser.AuthController.test.js +97 -0
  26. package/test/Browser.test.js +79 -0
  27. package/test/Connection.test.js +455 -0
  28. package/test/Service.test.js +89 -0
  29. package/test/ServiceAssets.test.js +79 -0
  30. package/test/Y.png +0 -0
  31. package/test/browser-index.js +11 -0
  32. package/test/browser-tests.html +31 -0
  33. package/test/helpers.js +8 -0
  34. package/test/load-test-account.js +108 -0
  35. package/test/test-data.js +92 -0
  36. package/test/utils.test.js +68 -0
  37. package/web-demos/auth-with-redirection.html +72 -0
  38. package/web-demos/auth.html +77 -0
  39. package/web-demos/custom-login-button.html +158 -0
  40. package/web-demos/index.html +186 -0
  41. package/web-demos/service-info.json +13 -0
  42. package/web-demos/stream-examples.html +80 -0
  43. package/webpack.config.js +71 -0
package/src/utils.js ADDED
@@ -0,0 +1,136 @@
1
+
2
+ const regexAPIandToken = /(.+):\/\/(.+)@(.+)/gm;
3
+ const regexSchemaAndPath = /(.+):\/\/(.+)/gm;
4
+
5
+ /**
6
+ * Utilities to access Pryv API.
7
+ * Exposes superagent and methods to manipulate Pryv's api endpoints
8
+ * @memberof Pryv
9
+ * @namespace Pryv.utils
10
+ */
11
+ const utils = {
12
+
13
+ /**
14
+ * Exposes superagent https://visionmedia.github.io/superagent/
15
+ * @memberof Pryv.utils
16
+ * @property {Superagent} superagent
17
+ */
18
+ superagent: require('superagent'),
19
+
20
+ /**
21
+ * Returns true is run in a browser
22
+ * @memberof Pryv.utils
23
+ * @returns {boolean}
24
+ */
25
+ isBrowser: function() {
26
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
27
+ },
28
+
29
+
30
+ /**
31
+ * From a PryvApiEndpoint URL, return an object (TokenAndAPI) with two properties
32
+ * @memberof Pryv.utils
33
+ * @param {PryvApiEndpoint} pryvApiEndpoint
34
+ * @returns {TokenAndEndpoint}
35
+ */
36
+ extractTokenAndApiEndpoint: function (pryvApiEndpoint) {
37
+ regexAPIandToken.lastIndex = 0;
38
+ const res = regexAPIandToken.exec(pryvApiEndpoint);
39
+
40
+ if (res !== null) { // has token
41
+ // add a trailing '/' to end point if missing
42
+ if (!res[3].endsWith('/')) {
43
+ res[3] += '/';
44
+ }
45
+ return { endpoint: res[1] + '://' + res[3], token: res[2] }
46
+ }
47
+ // else check if valid url
48
+ regexSchemaAndPath.lastIndex = 0;
49
+ const res2 = regexSchemaAndPath.exec(pryvApiEndpoint);
50
+ if (res2 === null) {
51
+ throw new Error('Cannot find endpoint, invalid URL format');
52
+ }
53
+ // add a trailing '/' to end point if missing
54
+ if (!res2[2].endsWith('/')) {
55
+ res2[2] += '/';
56
+ }
57
+
58
+ return { endpoint: res2[1] + '://' + res2[2] , token: null }
59
+ },
60
+
61
+ /**
62
+ * Get a PryvApiEndpoint URL from a TokenAndAPI object
63
+ * @memberof Pryv.utils
64
+ * @param {TokenAndEndpoint} tokenAndApi
65
+ * @returns {PryvApiEndpoint}
66
+ */
67
+ buildPryvApiEndpoint: function (tokenAndApi) {
68
+ if (! tokenAndApi.token) { 
69
+ let res = tokenAndApi.endpoint + '';
70
+ if (!tokenAndApi.endpoint.endsWith('/')) {
71
+ res += '/';
72
+ }
73
+ return res;
74
+ }
75
+ regexSchemaAndPath.lastIndex = 0;
76
+ let res = regexSchemaAndPath.exec(tokenAndApi.endpoint);
77
+ // add a trailing '/' to end point if missing
78
+ if (!res[2].endsWith('/')) {
79
+ res[2] += '/';
80
+ }
81
+ return res[1] + '://' + tokenAndApi.token + '@' + res[2];
82
+ },
83
+
84
+ /**
85
+ *
86
+ * @param {Object} [navigatorForTests] mock navigator var only for testing purposes
87
+ */
88
+ browserIsMobileOrTablet: function (navigator) {
89
+ if (navigator == null) {
90
+ return false;
91
+ }
92
+ let check = false;
93
+ (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; })(navigator.userAgent || navigator.vendor || navigator.opera);
94
+ return check;
95
+ },
96
+
97
+ cleanURLFromPrYvParams: function (url) {
98
+ const PRYV_REGEXP = /[?#&]+prYv([^=&]+)=([^&]*)/g;
99
+ return url.replace(PRYV_REGEXP, '');
100
+ },
101
+
102
+ getQueryParamsFromURL: function (url) {
103
+ let vars = {};
104
+ const QUERY_REGEXP = /[?#&]+([^=&]+)=([^&]*)/g;
105
+ url.replace(QUERY_REGEXP,
106
+ function (m, key, value) {
107
+ vars[key] = decodeURIComponent(value);
108
+ });
109
+ return vars;
110
+ }
111
+ }
112
+
113
+ module.exports = utils;
114
+
115
+ // --------------- typedfs ------------------------------- //
116
+
117
+ /**
118
+ * An object with two properties: token & apiEndpoint
119
+ * @typedef {Object} TokenAndEndpoint
120
+ * @property {string} [token] Authorization token
121
+ * @property {string} endpoint url of Pryv api endpoint
122
+ */
123
+
124
+ /**
125
+ * A String url of the form http(s)://{token}@{apiEndpoint}
126
+ * @typedef {string} PryvApiEndpoint
127
+ */
128
+
129
+
130
+ /**
131
+ * Common Meta are returned by each standard call on the API https://api.pryv.com/reference/#in-method-results
132
+ * @typedef {Object} CommonMeta
133
+ * @property {string} apiVersion The version of the API in the form {major}.{minor}.{revision}. Mirrored in HTTP header API-Version.
134
+ * @property {number} serverTime The current server time as a timestamp in second. Keeping track of server time is necessary to properly handle time in API calls.
135
+ * @property {string} serial The serial will change every time the core or register is updated. If you compare it with the serial of a previous response and notice a difference, you should reload the service information.
136
+ */
@@ -0,0 +1,97 @@
1
+ const expect = chai.expect;
2
+
3
+ const utils = require('../src/utils.js');
4
+ const Service = require('../src/Service');
5
+ const AuthController = require('../src/Auth/AuthController.js');
6
+ const testData = require('./test-data.js');
7
+
8
+ describe('Browser.LoginButton', function() {
9
+ this.timeout(5000);
10
+
11
+ let auth;
12
+ let removeZombie = false;
13
+ before(async function() {
14
+ if (typeof document !== 'undefined') return; // in browser
15
+ removeZombie = true;
16
+ const browser = new Browser();
17
+ browser.visit('./?pryvServiceInfoUrl=https://zouzou.com/service/info');
18
+ global.document = browser.document;
19
+ global.window = browser.window;
20
+ global.location = browser.location;
21
+ global.navigator = { userAgent: 'Safari' };
22
+ });
23
+
24
+ after(async function() {
25
+ if (!removeZombie) return; // in browser
26
+ delete global.document;
27
+ delete global.window;
28
+ delete global.location;
29
+ });
30
+ before(async function() {
31
+ let service = new Service(testData.serviceInfoUrl);
32
+ await service.info();
33
+ auth = new AuthController({
34
+ authRequest: {
35
+ requestingAppId: 'lib-js-test',
36
+ requestedPermissions: []
37
+ }
38
+ }, service);
39
+ await auth.init();
40
+ });
41
+
42
+ it('getReturnURL()', async function() {
43
+ const myUrl = 'https://mysite.com/bobby';
44
+ let error = null;
45
+ try {
46
+ auth.getReturnURL('auto');
47
+ } catch (e) {
48
+ error = e;
49
+ }
50
+ expect(error).to.be.not.null;
51
+
52
+ let fakeNavigator = { userAgent: 'android' };
53
+ expect(auth.getReturnURL('auto#', myUrl, fakeNavigator)).to.equal(myUrl + '#');
54
+ expect(auth.getReturnURL('auto?', myUrl, fakeNavigator)).to.equal(myUrl + '?');
55
+ expect(auth.getReturnURL(false, myUrl, fakeNavigator)).to.equal(myUrl + '#');
56
+ expect(auth.getReturnURL('self?', myUrl, fakeNavigator)).to.equal(myUrl + '?');
57
+
58
+ expect(auth.getReturnURL('http://zou.zou/toto#', myUrl, fakeNavigator)).to.equal('http://zou.zou/toto#');
59
+
60
+ fakeNavigator = { userAgent: 'Safari' };
61
+ expect(auth.getReturnURL('auto#', myUrl, fakeNavigator)).to.equal(false);
62
+ expect(auth.getReturnURL('auto?', myUrl, fakeNavigator)).to.equal(false);
63
+ expect(auth.getReturnURL(false, myUrl, fakeNavigator)).to.equal(false);
64
+ expect(auth.getReturnURL('self?', myUrl, fakeNavigator)).to.equal(myUrl + '?');
65
+ expect(auth.getReturnURL('http://zou.zou/toto#', myUrl, fakeNavigator)).to.equal('http://zou.zou/toto#');
66
+ global.window = { location: { href: myUrl + '?prYvstatus=zouzou'} }
67
+ expect(auth.getReturnURL('self?', myUrl, fakeNavigator)).to.equal(myUrl + '?');
68
+ });
69
+
70
+ it('browserIsMobileOrTablet()', async function() {
71
+ expect(utils.browserIsMobileOrTablet({ userAgent: 'android' })).to.be.true;
72
+ expect(utils.browserIsMobileOrTablet({ userAgent: 'Safari' })).to.be.false;
73
+ });
74
+
75
+
76
+ it('cleanURLFromPrYvParams()', async function() {
77
+
78
+ expect('https://my.Url.com/?bobby=2').to.equal(utils.cleanURLFromPrYvParams(
79
+ 'https://my.Url.com/?bobby=2&prYvZoutOu=1&prYvstatus=2jsadh'));
80
+
81
+ expect('https://my.Url.com/?pryvServiceInfoUrl=zzz').to.equal(utils.cleanURLFromPrYvParams(
82
+ 'https://my.Url.com/?pryvServiceInfoUrl=zzz#prYvZoutOu=1&prYvstatus=2jsadh'));
83
+
84
+ expect('https://my.Url.com/').to.equal(utils.cleanURLFromPrYvParams(
85
+ 'https://my.Url.com/?prYvstatus=2jsadh'));
86
+
87
+ expect('https://my.Url.com/').to.equal(utils.cleanURLFromPrYvParams(
88
+ 'https://my.Url.com/#prYvstatus=2jsadh'));
89
+
90
+ expect('https://my.Url.com/#bobby=2').to.equal(utils.cleanURLFromPrYvParams(
91
+ 'https://my.Url.com/#bobby=2&prYvZoutOu=1&prYvstatus=2jsadh'));
92
+
93
+ });
94
+
95
+ });
96
+
97
+
@@ -0,0 +1,79 @@
1
+
2
+ const should = chai.should();
3
+ const expect = chai.expect;
4
+
5
+ const testData = require('./test-data.js');
6
+
7
+ function genSettings() {
8
+ function defaultStateChange(state) {
9
+ console.log('Test unimplemented on state change', state);
10
+ }
11
+ return {
12
+ authRequest: {
13
+ requestingAppId: 'lib-js-test',
14
+ requestedPermissions: [{ streamId: '*', level: 'read' }],
15
+ },
16
+ onStateChange: defaultStateChange
17
+ };
18
+ }
19
+
20
+ describe('Browser', function () {
21
+ this.timeout(5000);
22
+
23
+ before(async function () {
24
+ this.timeout(5000);
25
+ await testData.prepare();
26
+ });
27
+
28
+ let removeZombie = false;
29
+
30
+ before(async () => {
31
+ if (typeof document !== 'undefined') return; // in browser
32
+ removeZombie = true;
33
+ const browser = new Browser();
34
+ browser.visit('./?pryvServiceInfoUrl=https://zouzou.com/service/info');
35
+ global.document = browser.document;
36
+ global.window = browser.window;
37
+ global.location = browser.location;
38
+ global.navigator = {userAgent: 'Safari'};
39
+ });
40
+
41
+ after(async () => {
42
+ if (!removeZombie) return; // in browser
43
+ delete global.document;
44
+ delete global.window;
45
+ delete global.location;
46
+ });
47
+
48
+ it('setupAuth()', async () => {
49
+ const settings = genSettings();
50
+ let AuthLoaded = false;
51
+ settings.onStateChange = function (state) {
52
+ should.exist(state.id);
53
+ if (state.id == Pryv.Auth.AuthStates.LOADING) {
54
+ AuthLoaded = true;
55
+ }
56
+ if (state.id == Pryv.Auth.AuthStates.INITIALIZED) {
57
+ expect(AuthLoaded).to.true;
58
+ }
59
+ }
60
+
61
+ try {
62
+ const service = await Pryv.Auth.setupAuth(settings, testData.serviceInfoUrl);
63
+ const serviceInfo = service.infoSync();
64
+ should.exist(serviceInfo.access);
65
+ should.exist(serviceInfo.serial);
66
+ } catch(error) {
67
+ console.log(error);
68
+ should.not.exist(error);
69
+ }
70
+ });
71
+
72
+
73
+ it('serviceInfoFromUrl()', async () => {
74
+ expect('https://zouzou.com/service/info').to.equal(Pryv.Browser.serviceInfoFromUrl());
75
+ });
76
+
77
+ });
78
+
79
+