pryv 3.12.1 → 3.14.2

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.
@@ -19,11 +19,80 @@ const Messages = {
19
19
  SIGNOUT_CONFIRM: {
20
20
  en: 'Logout?',
21
21
  fr: 'Se déconnecter ?'
22
+ },
23
+ MENU_TITLE: {
24
+ en: 'Account',
25
+ fr: 'Compte'
26
+ },
27
+ LOGOUT: {
28
+ en: 'Log out',
29
+ fr: 'Se déconnecter'
30
+ },
31
+ MANAGE_ACCOUNT: {
32
+ en: 'Manage my account',
33
+ fr: 'Gérer mon compte'
34
+ },
35
+ APP: {
36
+ en: 'app',
37
+ fr: 'app'
38
+ },
39
+ CLOSE: {
40
+ en: 'Close',
41
+ fr: 'Fermer'
42
+ },
43
+ CANCEL: {
44
+ en: 'Cancel',
45
+ fr: 'Annuler'
46
+ },
47
+ LOGOUT_ALL: {
48
+ en: 'Log out of all accounts',
49
+ fr: 'Se déconnecter de tous les comptes'
50
+ },
51
+ MANAGE_ACCOUNT_OF: {
52
+ en: 'Manage {username}\'s account',
53
+ fr: 'Gérer le compte de {username}'
54
+ },
55
+ USE_FOR: {
56
+ en: 'Use this app for',
57
+ fr: 'Utiliser cette app pour'
58
+ },
59
+ ME: {
60
+ en: 'me',
61
+ fr: 'moi'
62
+ },
63
+ VIA: {
64
+ en: 'via',
65
+ fr: 'via'
66
+ },
67
+ ACTING_AS: {
68
+ en: 'acting as',
69
+ fr: 'pour le compte'
70
+ },
71
+ SWITCH_BACK: {
72
+ en: 'Switch back to {username}',
73
+ fr: 'Revenir à {username}'
74
+ },
75
+ SWITCHING: {
76
+ en: 'Switching...',
77
+ fr: 'Changement...'
78
+ },
79
+ OTHER_ACCOUNT: {
80
+ en: 'Another account...',
81
+ fr: 'Un autre compte...'
82
+ },
83
+ UNAVAILABLE: {
84
+ en: 'no longer available',
85
+ fr: 'plus disponible'
22
86
  }
23
87
  };
24
88
 
89
+ /**
90
+ * Messages for a language. `definitions` (a service's own messages) override
91
+ * the defaults key by key, so a key the service does not define still has
92
+ * its default text.
93
+ */
25
94
  function get (languageCode, definitions) {
26
- const myMessages = definitions || Messages;
95
+ const myMessages = Object.assign({}, Messages, definitions || {});
27
96
  const res = {};
28
97
  Object.keys(myMessages).forEach((key) => {
29
98
  res[key] = myMessages[key][languageCode] || myMessages[key].en;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @license
3
+ * [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
4
+ */
5
+
6
+ /**
7
+ * The accounts a sign-in button remembers for one app, as stored in its
8
+ * authorization data:
9
+ * `{ apiEndpoint, username, actingAs?, authUrl?, profiles: [...] }`.
10
+ * The top-level `apiEndpoint` / `username` are the active account (what
11
+ * versions without profiles read); `profiles` lists every remembered
12
+ * account, most recently used first, the active one included.
13
+ * A profile is `{ username, apiEndpoint, actingAs?, unavailable? }`, where
14
+ * `actingAs = { username, delegate }` marks an account used through account
15
+ * delegation (`delegate` is the username of the person acting).
16
+ * @memberof pryv.Auth
17
+ */
18
+ module.exports = {
19
+ DEFAULT_LIMIT: 5,
20
+ read,
21
+ write,
22
+ activate,
23
+ remove,
24
+ markUnavailable,
25
+ profileOf,
26
+ fromAccepted,
27
+ carriesToken
28
+ };
29
+
30
+ const utils = require('../utils');
31
+
32
+ /**
33
+ * Whether an apiEndpoint carries a token. A stored sign-in without one
34
+ * cannot call the API (3.13.0 saved such sign-ins after a redirect return,
35
+ * the credential hand-off not being redeemed).
36
+ * @param {string} apiEndpoint
37
+ * @returns {boolean}
38
+ */
39
+ function carriesToken (apiEndpoint) {
40
+ try {
41
+ return Boolean(utils.extractTokenAndAPIEndpoint(apiEndpoint).token);
42
+ } catch (e) {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Parse stored authorization data (any version) into
49
+ * `{ active, profiles, authUrl }`; `active` is `profiles[0]` or null.
50
+ * @param {Object|null|undefined} stored
51
+ */
52
+ function read (stored) {
53
+ const store = { active: null, profiles: [], authUrl: undefined };
54
+ if (stored == null || typeof stored !== 'object' || stored.deleted === true) return store;
55
+ if (typeof stored.authUrl === 'string') store.authUrl = stored.authUrl;
56
+ if (Array.isArray(stored.profiles)) {
57
+ store.profiles = stored.profiles.filter(isProfile).map(profileOf);
58
+ }
59
+ if (isProfile(stored)) {
60
+ const active = profileOf(stored);
61
+ store.profiles = [active].concat(store.profiles.filter((p) => p.username !== active.username));
62
+ store.active = active;
63
+ }
64
+ return store;
65
+ }
66
+
67
+ /**
68
+ * The authorization data to store for `store`.
69
+ * @returns {Object|null} null when nothing is left to remember
70
+ */
71
+ function write (store) {
72
+ if (store.profiles.length === 0) return null;
73
+ const data = {};
74
+ if (store.active != null) {
75
+ data.apiEndpoint = store.active.apiEndpoint;
76
+ data.username = store.active.username;
77
+ if (store.active.actingAs != null) data.actingAs = store.active.actingAs;
78
+ }
79
+ if (store.authUrl != null) data.authUrl = store.authUrl;
80
+ data.profiles = store.profiles.map(profileOf);
81
+ return data;
82
+ }
83
+
84
+ /**
85
+ * Make `profile` the active account (replacing a stored one with the same
86
+ * username), then forget the least recently used accounts beyond `limit`.
87
+ */
88
+ function activate (store, profile, limit) {
89
+ const max = Math.max(1, limit || module.exports.DEFAULT_LIMIT);
90
+ const active = profileOf(profile);
91
+ const profiles = [active].concat(store.profiles.filter((p) => p.username !== active.username));
92
+ return Object.assign({}, store, { active, profiles: profiles.slice(0, max) });
93
+ }
94
+
95
+ /** Forget `username`; forgetting the active account leaves none active. */
96
+ function remove (store, username) {
97
+ const profiles = store.profiles.filter((p) => p.username !== username);
98
+ const active = (store.active != null && store.active.username !== username) ? store.active : null;
99
+ return Object.assign({}, store, { active, profiles });
100
+ }
101
+
102
+ /** Keep `username` listed, marked as no longer usable (revoked, detached). */
103
+ function markUnavailable (store, username) {
104
+ const mark = (p) => (p.username === username ? Object.assign(profileOf(p), { unavailable: true }) : p);
105
+ const profiles = store.profiles.map(mark);
106
+ const active = (store.active != null && store.active.username === username) ? null : store.active;
107
+ return Object.assign({}, store, { active, profiles });
108
+ }
109
+
110
+ /** The stored fields of a profile, nothing else (credentials included). */
111
+ function profileOf (p) {
112
+ const profile = { username: p.username, apiEndpoint: p.apiEndpoint };
113
+ if (p.actingAs != null && typeof p.actingAs.delegate === 'string') {
114
+ profile.actingAs = { username: p.username, delegate: p.actingAs.delegate };
115
+ }
116
+ if (p.unavailable === true) profile.unavailable = true;
117
+ return profile;
118
+ }
119
+
120
+ function isProfile (p) {
121
+ return p != null && typeof p.username === 'string' && typeof p.apiEndpoint === 'string';
122
+ }
123
+
124
+ /**
125
+ * The profile of an ACCEPTED auth-request body. Its `delegation` block is a
126
+ * display hint posted by the auth page; `accessInfo().delegation` is
127
+ * authoritative and replaces it when the profile is next activated.
128
+ */
129
+ function fromAccepted (body) {
130
+ const profile = { username: body.username, apiEndpoint: body.apiEndpoint };
131
+ const d = body.delegation;
132
+ if (d != null && d.isDelegatedAccess === true && d.controlledUsername === body.username &&
133
+ typeof d.delegate?.username === 'string') {
134
+ profile.actingAs = { username: body.username, delegate: d.delegate.username };
135
+ }
136
+ return profile;
137
+ }
package/src/Auth/index.js CHANGED
@@ -26,11 +26,14 @@ module.exports = {
26
26
  * @param {string} [settings.authRequest.languageCode] Language code, as per LoginButton Messages: 'en', 'fr
27
27
  * @param {string} settings.authRequest.requestingAppId Application id, ex: 'my-app'
28
28
  * @param {Object} settings.authRequest.requestedPermissions
29
- * @param {string | boolean} settings.authRequest.returnURL : false, // set this if you don't want a popup
29
+ * @param {string | false} [settings.authRequest.returnURL] 'auto#' (default, also when unset or false):
30
+ * popup on desktop, redirect on a phone or tablet; 'self#': always redirect back to this page;
31
+ * a URL: always redirect back to that URL. Must end with '#', '?' or '&'.
32
+ * @param {string} [settings.authRequest.authUrl] Your own auth page for this request; honoured only
33
+ * when it matches the platform's `access:trustedAuthUrls`
30
34
  * @param {string} [settings.authRequest.referer] To track registration source
31
35
  * @param {string} settings.spanButtonID set and <span> id in DOM to insert default login button or null for custom
32
36
  * @param {Function} settings.onStateChange
33
- * @param {string} [settings.returnURL] Set to "self#" to disable popup and force using the same page
34
37
  * @param {string} serviceInfoUrl
35
38
  * @param {Object} [serviceCustomizations] override properties of serviceInfoUrl
36
39
  * @returns {Promise<Service>}