chore(dropbox-web) Accommodate short-lived access token
This commit is contained in:
parent
5367d43c26
commit
bec9920c79
|
@ -7489,12 +7489,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dropbox": {
|
"dropbox": {
|
||||||
"version": "4.0.9",
|
"version": "10.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/dropbox/-/dropbox-4.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/dropbox/-/dropbox-10.7.0.tgz",
|
||||||
"integrity": "sha512-UeaKw7DY24ZGLRV8xboZvbZXhbTVrFjPjfpr0LfF/KVOzBUad9vJJwqz3udqTLNxD0FXbFlC9rlNLLNXaj9msg==",
|
"integrity": "sha512-btNLOYHxukACfnkEUNhlTPCnkecfbL89mrPU3RMKAWdCQXM18aRLm+t+0xIpzvRUSGeXPER+3d+QJk5Wi+4QGw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"buffer": "^5.0.8",
|
"node-fetch": "^2.6.1"
|
||||||
"moment": "^2.19.3"
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"duplexer": {
|
"duplexer": {
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"base64-js": "1.3.1",
|
"base64-js": "1.3.1",
|
||||||
"bc-css-flags": "3.0.0",
|
"bc-css-flags": "3.0.0",
|
||||||
"clipboard-copy": "4.0.1",
|
"clipboard-copy": "4.0.1",
|
||||||
"dropbox": "4.0.9",
|
"dropbox": "10.7.0",
|
||||||
"focus-visible": "5.1.0",
|
"focus-visible": "5.1.0",
|
||||||
"i18n-iso-countries": "6.8.0",
|
"i18n-iso-countries": "6.8.0",
|
||||||
"i18next": "17.0.6",
|
"i18next": "17.0.6",
|
||||||
|
|
|
@ -24,7 +24,7 @@ export function authorizeDropbox() {
|
||||||
|
|
||||||
_authorizeDropbox(dropbox.appKey, redirectURI)
|
_authorizeDropbox(dropbox.appKey, redirectURI)
|
||||||
.then(
|
.then(
|
||||||
token => dispatch(updateDropboxToken(token)));
|
({ token, rToken, expireDate }) => dispatch(updateDropboxToken(token, rToken, expireDate)));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,14 +32,20 @@ export function authorizeDropbox() {
|
||||||
* Action to update the dropbox access token.
|
* Action to update the dropbox access token.
|
||||||
*
|
*
|
||||||
* @param {string} token - The new token.
|
* @param {string} token - The new token.
|
||||||
|
* @param {string} rToken - The refresh token.
|
||||||
|
* @param {string} expireDate - The token expiration date as ISO string.
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* type: UPDATE_DROPBOX_TOKEN,
|
* type: UPDATE_DROPBOX_TOKEN,
|
||||||
* token: string
|
* token: string,
|
||||||
|
* rToken: string,
|
||||||
|
* expireDate: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function updateDropboxToken(token: string) {
|
export function updateDropboxToken(token: string, rToken: string, expireDate: string) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_DROPBOX_TOKEN,
|
type: UPDATE_DROPBOX_TOKEN,
|
||||||
token
|
token,
|
||||||
|
rToken,
|
||||||
|
expireDate
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,10 @@ const { Dropbox } = NativeModules;
|
||||||
* access token or rejected with an error.
|
* access token or rejected with an error.
|
||||||
*/
|
*/
|
||||||
export function _authorizeDropbox(): Promise<string> {
|
export function _authorizeDropbox(): Promise<string> {
|
||||||
return Dropbox.authorize();
|
return Dropbox.authorize()
|
||||||
|
.then(token => {
|
||||||
|
return { token };
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { Dropbox } from 'dropbox';
|
import { Dropbox, DropboxAuth } from 'dropbox';
|
||||||
|
|
||||||
import {
|
import { getJitsiMeetGlobalNS } from '../base/util';
|
||||||
getJitsiMeetGlobalNS,
|
|
||||||
parseStandardURIString,
|
|
||||||
parseURLParams
|
|
||||||
} from '../base/util';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the oauth flow.
|
* Executes the oauth flow.
|
||||||
|
@ -31,6 +27,16 @@ function authorize(authUrl: string): Promise<string> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the token's expiry date as ISO string.
|
||||||
|
*
|
||||||
|
* @param {number} expiresIn - The seconds in which the token expires.
|
||||||
|
* @returns {string} - The ISO value for the expiry date.
|
||||||
|
*/
|
||||||
|
function getTokenExpiresAtDate(expiresIn: number) {
|
||||||
|
return new Date(Date.now() + (expiresIn * 1000)).toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to authorize the Jitsi Recording app in dropbox.
|
* Action to authorize the Jitsi Recording app in dropbox.
|
||||||
*
|
*
|
||||||
|
@ -41,15 +47,46 @@ function authorize(authUrl: string): Promise<string> {
|
||||||
export function _authorizeDropbox(
|
export function _authorizeDropbox(
|
||||||
appKey: string,
|
appKey: string,
|
||||||
redirectURI: string
|
redirectURI: string
|
||||||
): Promise<string> {
|
): Promise<Object> {
|
||||||
const dropboxAPI = new Dropbox({ clientId: appKey });
|
const dropbox = new DropboxAuth({ clientId: appKey });
|
||||||
const url = dropboxAPI.getAuthenticationUrl(redirectURI);
|
|
||||||
|
|
||||||
return authorize(url).then(returnUrl => {
|
return dropbox.getAuthenticationUrl(redirectURI, undefined, 'code', 'offline', undefined, undefined, true)
|
||||||
const params
|
.then(authorize)
|
||||||
= parseURLParams(parseStandardURIString(returnUrl), true) || {};
|
.then(returnUrl => {
|
||||||
|
const params = new URLSearchParams(new URL(returnUrl).search);
|
||||||
|
const code = params.get('code');
|
||||||
|
|
||||||
return params.access_token;
|
return dropbox.getAccessTokenFromCode(redirectURI, code);
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
return {
|
||||||
|
token: resp.result.access_token,
|
||||||
|
rToken: resp.result.refresh_token,
|
||||||
|
expireDate: getTokenExpiresAtDate(resp.result.expires_in)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a new acccess token based on the refresh token.
|
||||||
|
*
|
||||||
|
* @param {string} appKey - The dropbox appKey.
|
||||||
|
* @param {string} rToken - The refresh token.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function getNewAccessToken(appKey: string, rToken: string) {
|
||||||
|
const dropbox = new DropboxAuth({ clientId: appKey });
|
||||||
|
|
||||||
|
dropbox.setRefreshToken(rToken);
|
||||||
|
|
||||||
|
return dropbox.refreshAccessToken()
|
||||||
|
.then(() => {
|
||||||
|
return {
|
||||||
|
token: dropbox.getAccessToken(),
|
||||||
|
rToken: dropbox.getRefreshToken(),
|
||||||
|
expireDate: dropbox.getAccessTokenExpiresAt().toISOString()
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +105,7 @@ export function getDisplayName(token: string, appKey: string) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
dropboxAPI.usersGetCurrentAccount()
|
dropboxAPI.usersGetCurrentAccount()
|
||||||
.then(account => account.name.display_name));
|
.then(account => account.result.name.display_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +122,7 @@ export function getSpaceUsage(token: string, appKey: string) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return dropboxAPI.usersGetSpaceUsage().then(space => {
|
return dropboxAPI.usersGetSpaceUsage().then(space => {
|
||||||
const { allocation, used } = space;
|
const { allocation, used } = space.result;
|
||||||
const { allocated } = allocation;
|
const { allocated } = allocation;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -19,7 +19,9 @@ ReducerRegistry.register(STORE_NAME, (state = {}, action) => {
|
||||||
case UPDATE_DROPBOX_TOKEN:
|
case UPDATE_DROPBOX_TOKEN:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
token: action.token
|
token: action.token,
|
||||||
|
rToken: action.rToken,
|
||||||
|
expireDate: action.expireDate
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -9,7 +9,9 @@ import {
|
||||||
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
||||||
import {
|
import {
|
||||||
getDropboxData,
|
getDropboxData,
|
||||||
isEnabled as isDropboxEnabled
|
isEnabled as isDropboxEnabled,
|
||||||
|
getNewAccessToken,
|
||||||
|
updateDropboxToken
|
||||||
} from '../../../dropbox';
|
} from '../../../dropbox';
|
||||||
import { showErrorNotification } from '../../../notifications';
|
import { showErrorNotification } from '../../../notifications';
|
||||||
import { toggleRequestingSubtitles } from '../../../subtitles';
|
import { toggleRequestingSubtitles } from '../../../subtitles';
|
||||||
|
@ -50,6 +52,16 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_isDropboxEnabled: boolean,
|
_isDropboxEnabled: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dropbox refresh token.
|
||||||
|
*/
|
||||||
|
_rToken: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access token's expiration date as ISO string.
|
||||||
|
*/
|
||||||
|
_tokenExpireDate?: string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dropbox access token.
|
* The dropbox access token.
|
||||||
*/
|
*/
|
||||||
|
@ -209,7 +221,7 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onTokenUpdated() {
|
_onTokenUpdated() {
|
||||||
const { _appKey, _isDropboxEnabled, _token } = this.props;
|
const { _appKey, _isDropboxEnabled, _token, _rToken, _tokenExpireDate, dispatch } = this.props;
|
||||||
|
|
||||||
if (!_isDropboxEnabled) {
|
if (!_isDropboxEnabled) {
|
||||||
return;
|
return;
|
||||||
|
@ -221,6 +233,13 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
isValidating: false
|
isValidating: false
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
if (_tokenExpireDate && Date.now() > new Date(_tokenExpireDate)) {
|
||||||
|
getNewAccessToken(_appKey, _rToken)
|
||||||
|
.then(resp => dispatch(updateDropboxToken(resp.token, resp.rToken, resp.expireDate)));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isTokenValid: false,
|
isTokenValid: false,
|
||||||
isValidating: true
|
isValidating: true
|
||||||
|
@ -251,7 +270,15 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
* @returns {boolean} - True (to note that the modal should be closed).
|
* @returns {boolean} - True (to note that the modal should be closed).
|
||||||
*/
|
*/
|
||||||
_onSubmit() {
|
_onSubmit() {
|
||||||
const { _autoCaptionOnRecord, _conference, _isDropboxEnabled, _token, dispatch } = this.props;
|
const {
|
||||||
|
_appKey,
|
||||||
|
_autoCaptionOnRecord,
|
||||||
|
_conference,
|
||||||
|
_isDropboxEnabled,
|
||||||
|
_rToken,
|
||||||
|
_token,
|
||||||
|
dispatch
|
||||||
|
} = this.props;
|
||||||
let appData;
|
let appData;
|
||||||
const attributes = {};
|
const attributes = {};
|
||||||
|
|
||||||
|
@ -261,7 +288,9 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
'file_recording_metadata': {
|
'file_recording_metadata': {
|
||||||
'upload_credentials': {
|
'upload_credentials': {
|
||||||
'service_name': RECORDING_TYPES.DROPBOX,
|
'service_name': RECORDING_TYPES.DROPBOX,
|
||||||
'token': _token
|
'token': _token,
|
||||||
|
'r_token': _rToken,
|
||||||
|
'app_key': _appKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -320,6 +349,8 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
* _fileRecordingsServiceEnabled: boolean,
|
* _fileRecordingsServiceEnabled: boolean,
|
||||||
* _fileRecordingsServiceSharingEnabled: boolean,
|
* _fileRecordingsServiceSharingEnabled: boolean,
|
||||||
* _isDropboxEnabled: boolean,
|
* _isDropboxEnabled: boolean,
|
||||||
|
* _rToken:string,
|
||||||
|
* _tokenExpireDate: string,
|
||||||
* _token: string
|
* _token: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
|
@ -338,6 +369,8 @@ export function mapStateToProps(state: Object) {
|
||||||
_fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
|
_fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
|
||||||
_fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled,
|
_fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled,
|
||||||
_isDropboxEnabled: isDropboxEnabled(state),
|
_isDropboxEnabled: isDropboxEnabled(state),
|
||||||
|
_rToken: state['features/dropbox'].rToken,
|
||||||
|
_tokenExpireDate: state['features/dropbox'].expireDate,
|
||||||
_token: state['features/dropbox'].token
|
_token: state['features/dropbox'].token
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue