
New localDbSvc.getWorkspaceItems method used to export workspaces. Added offline availability in the workspace management modal. New accordion in the badge management modal. Add badge creation checks in unit tests.
191 lines
4.9 KiB
JavaScript
191 lines
4.9 KiB
JavaScript
import networkSvc from '../../networkSvc';
|
|
import userSvc from '../../userSvc';
|
|
import store from '../../../store';
|
|
import badgeSvc from '../../badgeSvc';
|
|
|
|
const getAppKey = (fullAccess) => {
|
|
if (fullAccess) {
|
|
return store.getters['data/serverConf'].dropboxAppKeyFull;
|
|
}
|
|
return store.getters['data/serverConf'].dropboxAppKey;
|
|
};
|
|
|
|
const httpHeaderSafeJson = args => args && JSON.stringify(args)
|
|
.replace(/[\u007f-\uffff]/g, c => `\\u${`000${c.charCodeAt(0).toString(16)}`.slice(-4)}`);
|
|
|
|
const request = ({ accessToken }, options, args) => networkSvc.request({
|
|
...options,
|
|
headers: {
|
|
...options.headers || {},
|
|
'Content-Type': options.body && (typeof options.body === 'string'
|
|
? 'application/octet-stream' : 'application/json; charset=utf-8'),
|
|
'Dropbox-API-Arg': httpHeaderSafeJson(args),
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
});
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#users-get_account
|
|
*/
|
|
const subPrefix = 'db';
|
|
userSvc.setInfoResolver('dropbox', subPrefix, async (sub) => {
|
|
const dropboxToken = Object.values(store.getters['data/dropboxTokensBySub'])[0];
|
|
try {
|
|
const { body } = await request(dropboxToken, {
|
|
method: 'POST',
|
|
url: 'https://api.dropboxapi.com/2/users/get_account',
|
|
body: {
|
|
account_id: sub,
|
|
},
|
|
});
|
|
|
|
return {
|
|
id: `${subPrefix}:${body.account_id}`,
|
|
name: body.name.display_name,
|
|
imageUrl: body.profile_photo_url || '',
|
|
};
|
|
} catch (err) {
|
|
if (!dropboxToken || err.status !== 404) {
|
|
throw new Error('RETRY');
|
|
}
|
|
throw err;
|
|
}
|
|
});
|
|
|
|
export default {
|
|
subPrefix,
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#oauth2-authorize
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#users-get_current_account
|
|
*/
|
|
async startOauth2(fullAccess, sub = null, silent = false) {
|
|
// Get an OAuth2 code
|
|
const { accessToken } = await networkSvc.startOauth2(
|
|
'https://www.dropbox.com/oauth2/authorize',
|
|
{
|
|
client_id: getAppKey(fullAccess),
|
|
response_type: 'token',
|
|
},
|
|
silent,
|
|
);
|
|
|
|
// Call the user info endpoint
|
|
const { body } = await request({ accessToken }, {
|
|
method: 'POST',
|
|
url: 'https://api.dropboxapi.com/2/users/get_current_account',
|
|
});
|
|
userSvc.addUserInfo({
|
|
id: `${subPrefix}:${body.account_id}`,
|
|
name: body.name.display_name,
|
|
imageUrl: body.profile_photo_url || '',
|
|
});
|
|
|
|
// Check the returned sub consistency
|
|
if (sub && `${body.account_id}` !== sub) {
|
|
throw new Error('Dropbox account ID not expected.');
|
|
}
|
|
|
|
// Build token object including scopes and sub
|
|
const token = {
|
|
accessToken,
|
|
name: body.name.display_name,
|
|
sub: `${body.account_id}`,
|
|
fullAccess,
|
|
};
|
|
|
|
// Add token to dropbox tokens
|
|
store.dispatch('data/addDropboxToken', token);
|
|
return token;
|
|
},
|
|
async addAccount(fullAccess = false) {
|
|
const token = await this.startOauth2(fullAccess);
|
|
badgeSvc.addBadge('addDropboxAccount');
|
|
return token;
|
|
},
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#files-upload
|
|
*/
|
|
async uploadFile({
|
|
token,
|
|
path,
|
|
content,
|
|
fileId,
|
|
}) {
|
|
return (await request(token, {
|
|
method: 'POST',
|
|
url: 'https://content.dropboxapi.com/2/files/upload',
|
|
body: content,
|
|
}, {
|
|
path: fileId || path,
|
|
mode: 'overwrite',
|
|
})).body;
|
|
},
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#files-download
|
|
*/
|
|
async downloadFile({
|
|
token,
|
|
path,
|
|
fileId,
|
|
}) {
|
|
const res = await request(token, {
|
|
method: 'POST',
|
|
url: 'https://content.dropboxapi.com/2/files/download',
|
|
raw: true,
|
|
}, {
|
|
path: fileId || path,
|
|
});
|
|
return {
|
|
id: JSON.parse(res.headers['dropbox-api-result']).id,
|
|
content: res.body,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/documentation/http/documentation#list-revisions
|
|
*/
|
|
async listRevisions({
|
|
token,
|
|
path,
|
|
fileId,
|
|
}) {
|
|
const res = await request(token, {
|
|
method: 'POST',
|
|
url: 'https://api.dropboxapi.com/2/files/list_revisions',
|
|
body: fileId ? {
|
|
path: fileId,
|
|
mode: 'id',
|
|
limit: 100,
|
|
} : {
|
|
path,
|
|
limit: 100,
|
|
},
|
|
});
|
|
return res.body.entries;
|
|
},
|
|
|
|
/**
|
|
* https://www.dropbox.com/developers/chooser
|
|
*/
|
|
async openChooser(token) {
|
|
if (!window.Dropbox) {
|
|
await networkSvc.loadScript('https://www.dropbox.com/static/api/2/dropins.js');
|
|
}
|
|
return new Promise((resolve) => {
|
|
window.Dropbox.appKey = getAppKey(token.fullAccess);
|
|
window.Dropbox.choose({
|
|
multiselect: true,
|
|
linkType: 'direct',
|
|
success: files => resolve(files.map((file) => {
|
|
const path = file.link.replace(/.*\/view\/[^/]*/, '');
|
|
return decodeURI(path);
|
|
})),
|
|
cancel: () => resolve([]),
|
|
});
|
|
});
|
|
},
|
|
};
|