mirror of https://github.com/laurent22/joplin.git
parent
aa147bbcdc
commit
799a9e810d
|
@ -82,6 +82,15 @@ class SyncTargetOneDrive extends BaseSyncTarget {
|
|||
}
|
||||
|
||||
async initFileApi() {
|
||||
let context = Setting.value(`sync.${this.syncTargetId()}.context`);
|
||||
context = context === '' ? null : JSON.parse(context);
|
||||
let accountProperties = context ? context.accountProperties : null;
|
||||
if (!accountProperties) {
|
||||
accountProperties = await this.api_.execAccountPropertiesRequest();
|
||||
context ? context.accountProperties = accountProperties : context = { accountProperties: accountProperties };
|
||||
Setting.setValue(`sync.${this.syncTargetId()}.context`, JSON.stringify(context));
|
||||
}
|
||||
this.api_.setAccountProperties(accountProperties);
|
||||
const appDir = await this.api().appDirectory();
|
||||
const fileApi = new FileApi(appDir, new FileApiDriverOneDrive(this.api()));
|
||||
fileApi.setSyncTargetId(this.syncTargetId());
|
||||
|
@ -90,8 +99,15 @@ class SyncTargetOneDrive extends BaseSyncTarget {
|
|||
}
|
||||
|
||||
async initSynchronizer() {
|
||||
if (!(await this.isAuthenticated())) throw new Error('User is not authentified');
|
||||
return new Synchronizer(this.db(), await this.fileApi(), Setting.value('appType'));
|
||||
try {
|
||||
if (!(await this.isAuthenticated())) throw new Error('User is not authentified');
|
||||
return new Synchronizer(this.db(), await this.fileApi(), Setting.value('appType'));
|
||||
} catch (error) {
|
||||
BaseSyncTarget.dispatch({ type: 'SYNC_REPORT_UPDATE', report: { errors: [error] } });
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,9 @@ class FileApiDriverOneDrive {
|
|||
};
|
||||
|
||||
const freshStartDelta = () => {
|
||||
const url = `${this.makePath_(path)}:/delta`;
|
||||
// Business Accounts are only allowed to make delta requests to the root. For some reason /delta gives an error for personal accounts and :/delta an error for business accounts
|
||||
const accountProperties = this.api_.accountProperties_;
|
||||
const url = (accountProperties.accountType === 'business') ? `/drives/${accountProperties.driveId}/root/delta` : `${this.makePath_(path)}:/delta`;
|
||||
const query = this.itemFilter_();
|
||||
query.select += ',deleted';
|
||||
return { url: url, query: query };
|
||||
|
@ -265,14 +267,14 @@ class FileApiDriverOneDrive {
|
|||
|
||||
const items = [];
|
||||
|
||||
// The delta API might return things that happen in subdirectories of the root and we don't want to
|
||||
// deal with these since all the files we're interested in are at the root (The .resource dir
|
||||
// is special since it's managed directly by the clients and resources never change - only the
|
||||
// associated .md file at the root is synced). So in the loop below we check that the parent is
|
||||
// indeed the root, otherwise the item is skipped.
|
||||
// (Not sure but it's possible the delta API also returns events for files that are copied outside
|
||||
// of the app directory and later deleted or modified. We also don't want to deal with
|
||||
// these files during sync).
|
||||
// The delta API might return things that happens in subdirectories and outside of the joplin directory.
|
||||
// We don't want to deal with these since all the files we're interested in are at the root of the joplin directory
|
||||
// (The .resource dir is special since it's managed directly by the clients and resources never change - only the
|
||||
// associated .md file at the root is synced). So in the loop below we check that the parent is indeed the joplin
|
||||
// directory, otherwise the item is skipped.
|
||||
// At OneDrive for Business delta requests can only make at the root of OneDrive. Not sure but it's possible that
|
||||
// the delta API also returns events for files that are copied outside of the app directory and later deleted or
|
||||
// modified when using OneDrive Personal).
|
||||
|
||||
for (let i = 0; i < response.value.length; i++) {
|
||||
const v = response.value[i];
|
||||
|
|
|
@ -13,6 +13,7 @@ class OneDriveApi {
|
|||
this.clientId_ = clientId;
|
||||
this.clientSecret_ = clientSecret;
|
||||
this.auth_ = null;
|
||||
this.accountProperties_ = null;
|
||||
this.isPublic_ = isPublic;
|
||||
this.listeners_ = {
|
||||
authRefreshed: [],
|
||||
|
@ -73,14 +74,15 @@ class OneDriveApi {
|
|||
}
|
||||
|
||||
async appDirectory() {
|
||||
const r = await this.execJson('GET', '/drive/special/approot');
|
||||
const driveId = this.accountProperties_.driveId;
|
||||
const r = await this.execJson('GET', `/me/drives/${driveId}/special/approot`);
|
||||
return `${r.parentReference.path}/${r.name}`;
|
||||
}
|
||||
|
||||
authCodeUrl(redirectUri) {
|
||||
const query = {
|
||||
client_id: this.clientId_,
|
||||
scope: 'files.readwrite offline_access',
|
||||
scope: 'files.readwrite offline_access sites.readwrite.all',
|
||||
response_type: 'code',
|
||||
redirect_uri: redirectUri,
|
||||
};
|
||||
|
@ -320,6 +322,29 @@ class OneDriveApi {
|
|||
throw new Error(`Could not execute request after multiple attempts: ${method} ${url}`);
|
||||
}
|
||||
|
||||
setAccountProperties(accountProperties) {
|
||||
this.accountProperties_ = accountProperties;
|
||||
}
|
||||
|
||||
async execAccountPropertiesRequest() {
|
||||
const response = await shim.fetch('https://graph.microsoft.com/v1.0/me/drive', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': this.token(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`Could not retrieve account details (drive ID, Account type): ${response.status}: ${response.statusText}: ${text}`);
|
||||
} else {
|
||||
const data = await response.json();
|
||||
const accountProperties = { accountType: data.driveType, driveId: data.id };
|
||||
return accountProperties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async execJson(method, path, query, data) {
|
||||
const response = await this.exec(method, path, query, data);
|
||||
const errorResponseText = await response.text();
|
||||
|
|
|
@ -2,7 +2,6 @@ const { Logger } = require('lib/logger.js');
|
|||
const Setting = require('lib/models/Setting.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const SyncTargetRegistry = require('lib/SyncTargetRegistry.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
|
||||
const reg = {};
|
||||
|
||||
|
@ -141,20 +140,6 @@ reg.scheduleSync = async (delay = null, syncOptions = null) => {
|
|||
} catch (error) {
|
||||
reg.logger().info('Could not run background sync:');
|
||||
reg.logger().info(error);
|
||||
|
||||
// Special case to display OneDrive Business error. This is the full error that's received when trying to use a OneDrive Business account:
|
||||
//
|
||||
// {"error":"invalid_client","error_description":"AADSTS50011: The reply address 'http://localhost:1917' does not match the reply addresses configured for
|
||||
// the application: 'cbabb902-d276-4ea4-aa88-062a5889d6dc'. More details: not specified\r\nTrace ID: 6e63dac6-8b37-47e2-bd1b-4768f8713400\r\nCorrelation
|
||||
// ID: acfd6503-8d97-4349-ae2e-e7a19dd7b6bc\r\nTimestamp: 2017-12-01 13:35:55Z","error_codes":[50011],"timestamp":"2017-12-01 13:35:55Z","trace_id":
|
||||
// "6e63dac6-8b37-47e2-bd1b-4768f8713400","correlation_id":"acfd6503-8d97-4349-ae2e-e7a19dd7b6bc"}: TOKEN: null Error: {"error":"invalid_client",
|
||||
// "error_description":"AADSTS50011: The reply address 'http://localhost:1917' does not match the reply addresses configured for the application:
|
||||
// 'cbabb902-d276-4ea4-aa88-062a5889d6dc'. More details: not specified\r\nTrace ID: 6e63dac6-8b37-47e2-bd1b-4768f8713400\r\nCorrelation ID
|
||||
// acfd6503-8d97-4349-ae2e-e7a19dd7b6bc\r\nTimestamp: 2017-12-01 13:35:55Z","error_codes":[50011],"timestamp":"2017-12-01 13:35:55Z","trace_id":
|
||||
// "6e63dac6-8b37-47e2-bd1b-4768f8713400","correlation_id":"acfd6503-8d97-4349-ae2e-e7a19dd7b6bc"}
|
||||
if (error && error.message && error.message.indexOf('"invalid_client"') >= 0) {
|
||||
reg.showErrorMessageBox(_('Could not synchronise with OneDrive.\n\nThis error often happens when using OneDrive for Business, which unfortunately cannot be supported.\n\nPlease consider using a regular OneDrive account.'));
|
||||
}
|
||||
}
|
||||
reg.setupRecurrentSync();
|
||||
promiseResolve();
|
||||
|
|
Loading…
Reference in New Issue