Просмотр исходного кода

chore(dropbox-web) Accommodate short-lived access token

master
hmuresan 4 лет назад
Родитель
Сommit
bec9920c79

+ 11
- 5
package-lock.json Просмотреть файл

7489
       }
7489
       }
7490
     },
7490
     },
7491
     "dropbox": {
7491
     "dropbox": {
7492
-      "version": "4.0.9",
7493
-      "resolved": "https://registry.npmjs.org/dropbox/-/dropbox-4.0.9.tgz",
7494
-      "integrity": "sha512-UeaKw7DY24ZGLRV8xboZvbZXhbTVrFjPjfpr0LfF/KVOzBUad9vJJwqz3udqTLNxD0FXbFlC9rlNLLNXaj9msg==",
7492
+      "version": "10.7.0",
7493
+      "resolved": "https://registry.npmjs.org/dropbox/-/dropbox-10.7.0.tgz",
7494
+      "integrity": "sha512-btNLOYHxukACfnkEUNhlTPCnkecfbL89mrPU3RMKAWdCQXM18aRLm+t+0xIpzvRUSGeXPER+3d+QJk5Wi+4QGw==",
7495
       "requires": {
7495
       "requires": {
7496
-        "buffer": "^5.0.8",
7497
-        "moment": "^2.19.3"
7496
+        "node-fetch": "^2.6.1"
7497
+      },
7498
+      "dependencies": {
7499
+        "node-fetch": {
7500
+          "version": "2.6.1",
7501
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
7502
+          "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
7503
+        }
7498
       }
7504
       }
7499
     },
7505
     },
7500
     "duplexer": {
7506
     "duplexer": {

+ 1
- 1
package.json Просмотреть файл

47
     "base64-js": "1.3.1",
47
     "base64-js": "1.3.1",
48
     "bc-css-flags": "3.0.0",
48
     "bc-css-flags": "3.0.0",
49
     "clipboard-copy": "4.0.1",
49
     "clipboard-copy": "4.0.1",
50
-    "dropbox": "4.0.9",
50
+    "dropbox": "10.7.0",
51
     "focus-visible": "5.1.0",
51
     "focus-visible": "5.1.0",
52
     "i18n-iso-countries": "6.8.0",
52
     "i18n-iso-countries": "6.8.0",
53
     "i18next": "17.0.6",
53
     "i18next": "17.0.6",

+ 10
- 4
react/features/dropbox/actions.js Просмотреть файл

24
 
24
 
25
         _authorizeDropbox(dropbox.appKey, redirectURI)
25
         _authorizeDropbox(dropbox.appKey, redirectURI)
26
             .then(
26
             .then(
27
-                token => dispatch(updateDropboxToken(token)));
27
+                ({ token, rToken, expireDate }) => dispatch(updateDropboxToken(token, rToken, expireDate)));
28
     };
28
     };
29
 }
29
 }
30
 
30
 
32
  * Action to update the dropbox access token.
32
  * Action to update the dropbox access token.
33
  *
33
  *
34
  * @param {string} token - The new token.
34
  * @param {string} token - The new token.
35
+ * @param {string} rToken - The refresh token.
36
+ * @param {string} expireDate - The token expiration date as ISO string.
35
  * @returns {{
37
  * @returns {{
36
  *     type: UPDATE_DROPBOX_TOKEN,
38
  *     type: UPDATE_DROPBOX_TOKEN,
37
- *     token: string
39
+ *     token: string,
40
+ *     rToken: string,
41
+ *     expireDate: string
38
  * }}
42
  * }}
39
  */
43
  */
40
-export function updateDropboxToken(token: string) {
44
+export function updateDropboxToken(token: string, rToken: string, expireDate: string) {
41
     return {
45
     return {
42
         type: UPDATE_DROPBOX_TOKEN,
46
         type: UPDATE_DROPBOX_TOKEN,
43
-        token
47
+        token,
48
+        rToken,
49
+        expireDate
44
     };
50
     };
45
 }
51
 }

+ 4
- 1
react/features/dropbox/functions.native.js Просмотреть файл

13
  * access token or rejected with an error.
13
  * access token or rejected with an error.
14
  */
14
  */
15
 export function _authorizeDropbox(): Promise<string> {
15
 export function _authorizeDropbox(): Promise<string> {
16
-    return Dropbox.authorize();
16
+    return Dropbox.authorize()
17
+        .then(token => {
18
+            return { token };
19
+        });
17
 }
20
 }
18
 
21
 
19
 /**
22
 /**

+ 53
- 16
react/features/dropbox/functions.web.js Просмотреть файл

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { Dropbox } from 'dropbox';
3
+import { Dropbox, DropboxAuth } from 'dropbox';
4
 
4
 
5
-import {
6
-    getJitsiMeetGlobalNS,
7
-    parseStandardURIString,
8
-    parseURLParams
9
-} from '../base/util';
5
+import { getJitsiMeetGlobalNS } from '../base/util';
10
 
6
 
11
 /**
7
 /**
12
  * Executes the oauth flow.
8
  * Executes the oauth flow.
31
     });
27
     });
32
 }
28
 }
33
 
29
 
30
+/**
31
+ * Returns the token's expiry date as ISO string.
32
+ *
33
+ * @param {number} expiresIn - The seconds in which the token expires.
34
+ * @returns {string} - The ISO value for the expiry date.
35
+ */
36
+function getTokenExpiresAtDate(expiresIn: number) {
37
+    return new Date(Date.now() + (expiresIn * 1000)).toISOString();
38
+}
39
+
34
 /**
40
 /**
35
  * Action to authorize the Jitsi Recording app in dropbox.
41
  * Action to authorize the Jitsi Recording app in dropbox.
36
  *
42
  *
41
 export function _authorizeDropbox(
47
 export function _authorizeDropbox(
42
         appKey: string,
48
         appKey: string,
43
         redirectURI: string
49
         redirectURI: string
44
-): Promise<string> {
45
-    const dropboxAPI = new Dropbox({ clientId: appKey });
46
-    const url = dropboxAPI.getAuthenticationUrl(redirectURI);
50
+): Promise<Object> {
51
+    const dropbox = new DropboxAuth({ clientId: appKey });
52
+
53
+    return dropbox.getAuthenticationUrl(redirectURI, undefined, 'code', 'offline', undefined, undefined, true)
54
+        .then(authorize)
55
+        .then(returnUrl => {
56
+            const params = new URLSearchParams(new URL(returnUrl).search);
57
+            const code = params.get('code');
58
+
59
+            return dropbox.getAccessTokenFromCode(redirectURI, code);
60
+        })
61
+        .then(resp => {
62
+            return {
63
+                token: resp.result.access_token,
64
+                rToken: resp.result.refresh_token,
65
+                expireDate: getTokenExpiresAtDate(resp.result.expires_in)
66
+            };
67
+        });
68
+}
47
 
69
 
48
-    return authorize(url).then(returnUrl => {
49
-        const params
50
-            = parseURLParams(parseStandardURIString(returnUrl), true) || {};
51
 
70
 
52
-        return params.access_token;
53
-    });
71
+/**
72
+ * Gets a new acccess token based on the refresh token.
73
+ *
74
+ * @param {string} appKey - The dropbox appKey.
75
+ * @param {string} rToken - The refresh token.
76
+ * @returns {Promise}
77
+ */
78
+export function getNewAccessToken(appKey: string, rToken: string) {
79
+    const dropbox = new DropboxAuth({ clientId: appKey });
80
+
81
+    dropbox.setRefreshToken(rToken);
82
+
83
+    return dropbox.refreshAccessToken()
84
+        .then(() => {
85
+            return {
86
+                token: dropbox.getAccessToken(),
87
+                rToken: dropbox.getRefreshToken(),
88
+                expireDate: dropbox.getAccessTokenExpiresAt().toISOString()
89
+            };
90
+        });
54
 }
91
 }
55
 
92
 
56
 /**
93
 /**
68
 
105
 
69
     return (
106
     return (
70
         dropboxAPI.usersGetCurrentAccount()
107
         dropboxAPI.usersGetCurrentAccount()
71
-            .then(account => account.name.display_name));
108
+            .then(account => account.result.name.display_name));
72
 }
109
 }
73
 
110
 
74
 /**
111
 /**
85
     });
122
     });
86
 
123
 
87
     return dropboxAPI.usersGetSpaceUsage().then(space => {
124
     return dropboxAPI.usersGetSpaceUsage().then(space => {
88
-        const { allocation, used } = space;
125
+        const { allocation, used } = space.result;
89
         const { allocated } = allocation;
126
         const { allocated } = allocation;
90
 
127
 
91
         return {
128
         return {

+ 3
- 1
react/features/dropbox/reducer.js Просмотреть файл

19
     case UPDATE_DROPBOX_TOKEN:
19
     case UPDATE_DROPBOX_TOKEN:
20
         return {
20
         return {
21
             ...state,
21
             ...state,
22
-            token: action.token
22
+            token: action.token,
23
+            rToken: action.rToken,
24
+            expireDate: action.expireDate
23
         };
25
         };
24
     default:
26
     default:
25
         return state;
27
         return state;

+ 37
- 4
react/features/recording/components/Recording/AbstractStartRecordingDialog.js Просмотреть файл

9
 import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
9
 import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
10
 import {
10
 import {
11
     getDropboxData,
11
     getDropboxData,
12
-    isEnabled as isDropboxEnabled
12
+    isEnabled as isDropboxEnabled,
13
+    getNewAccessToken,
14
+    updateDropboxToken
13
 } from '../../../dropbox';
15
 } from '../../../dropbox';
14
 import { showErrorNotification } from '../../../notifications';
16
 import { showErrorNotification } from '../../../notifications';
15
 import { toggleRequestingSubtitles } from '../../../subtitles';
17
 import { toggleRequestingSubtitles } from '../../../subtitles';
50
      */
52
      */
51
     _isDropboxEnabled: boolean,
53
     _isDropboxEnabled: boolean,
52
 
54
 
55
+    /**
56
+     * The dropbox refresh token.
57
+     */
58
+    _rToken: string,
59
+
60
+    /**
61
+     * Access token's expiration date as ISO string.
62
+     */
63
+    _tokenExpireDate?: string,
64
+
53
     /**
65
     /**
54
      * The dropbox access token.
66
      * The dropbox access token.
55
      */
67
      */
209
      * @returns {void}
221
      * @returns {void}
210
      */
222
      */
211
     _onTokenUpdated() {
223
     _onTokenUpdated() {
212
-        const { _appKey, _isDropboxEnabled, _token } = this.props;
224
+        const { _appKey, _isDropboxEnabled, _token, _rToken, _tokenExpireDate, dispatch } = this.props;
213
 
225
 
214
         if (!_isDropboxEnabled) {
226
         if (!_isDropboxEnabled) {
215
             return;
227
             return;
221
                 isValidating: false
233
                 isValidating: false
222
             });
234
             });
223
         } else {
235
         } else {
236
+            if (_tokenExpireDate && Date.now() > new Date(_tokenExpireDate)) {
237
+                getNewAccessToken(_appKey, _rToken)
238
+                    .then(resp => dispatch(updateDropboxToken(resp.token, resp.rToken, resp.expireDate)));
239
+
240
+                return;
241
+            }
242
+
224
             this.setState({
243
             this.setState({
225
                 isTokenValid: false,
244
                 isTokenValid: false,
226
                 isValidating: true
245
                 isValidating: true
251
      * @returns {boolean} - True (to note that the modal should be closed).
270
      * @returns {boolean} - True (to note that the modal should be closed).
252
      */
271
      */
253
     _onSubmit() {
272
     _onSubmit() {
254
-        const { _autoCaptionOnRecord, _conference, _isDropboxEnabled, _token, dispatch } = this.props;
273
+        const {
274
+            _appKey,
275
+            _autoCaptionOnRecord,
276
+            _conference,
277
+            _isDropboxEnabled,
278
+            _rToken,
279
+            _token,
280
+            dispatch
281
+        } = this.props;
255
         let appData;
282
         let appData;
256
         const attributes = {};
283
         const attributes = {};
257
 
284
 
261
                     'file_recording_metadata': {
288
                     'file_recording_metadata': {
262
                         'upload_credentials': {
289
                         'upload_credentials': {
263
                             'service_name': RECORDING_TYPES.DROPBOX,
290
                             'service_name': RECORDING_TYPES.DROPBOX,
264
-                            'token': _token
291
+                            'token': _token,
292
+                            'r_token': _rToken,
293
+                            'app_key': _appKey
265
                         }
294
                         }
266
                     }
295
                     }
267
                 });
296
                 });
320
  *     _fileRecordingsServiceEnabled: boolean,
349
  *     _fileRecordingsServiceEnabled: boolean,
321
  *     _fileRecordingsServiceSharingEnabled: boolean,
350
  *     _fileRecordingsServiceSharingEnabled: boolean,
322
  *     _isDropboxEnabled: boolean,
351
  *     _isDropboxEnabled: boolean,
352
+ *     _rToken:string,
353
+ *     _tokenExpireDate: string,
323
  *     _token: string
354
  *     _token: string
324
  * }}
355
  * }}
325
  */
356
  */
338
         _fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
369
         _fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
339
         _fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled,
370
         _fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled,
340
         _isDropboxEnabled: isDropboxEnabled(state),
371
         _isDropboxEnabled: isDropboxEnabled(state),
372
+        _rToken: state['features/dropbox'].rToken,
373
+        _tokenExpireDate: state['features/dropbox'].expireDate,
341
         _token: state['features/dropbox'].token
374
         _token: state['features/dropbox'].token
342
     };
375
     };
343
 }
376
 }

Загрузка…
Отмена
Сохранить