180 lines
4.7 KiB
JavaScript
180 lines
4.7 KiB
JavaScript
import networkSvc from '../../networkSvc';
|
|
import userSvc from '../../userSvc';
|
|
import store from '../../../store';
|
|
|
|
const getAppKey = (fullAccess) => {
|
|
if (fullAccess) {
|
|
return 'lq6mwopab8wskas';
|
|
}
|
|
return 'sw0hlixhr8q1xk0';
|
|
};
|
|
|
|
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) {
|
|
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.addInfo({
|
|
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;
|
|
},
|
|
addAccount(fullAccess = false) {
|
|
return this.startOauth2(fullAccess);
|
|
},
|
|
|
|
/**
|
|
* 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, fileId) {
|
|
const res = await request(token, {
|
|
method: 'POST',
|
|
url: 'https://api.dropboxapi.com/2/files/list_revisions',
|
|
body: {
|
|
path: fileId,
|
|
mode: 'id',
|
|
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([]),
|
|
});
|
|
});
|
|
},
|
|
};
|