mirror of
https://github.com/laurent22/joplin.git
synced 2025-02-01 19:15:01 +02:00
Making oneDrive work on RN
This commit is contained in:
parent
bdb250de8a
commit
1c6b569795
@ -677,27 +677,28 @@ async function synchronizer(syncTarget) {
|
||||
let fileApi = null;
|
||||
|
||||
if (syncTarget == 'onedrive') {
|
||||
const CLIENT_ID = 'e09fc0de-c958-424f-83a2-e56a721d331b';
|
||||
const CLIENT_SECRET = 'JA3cwsqSGHFtjMwd5XoF5L5';
|
||||
let oneDriveApi = oneDriveApi.instance();
|
||||
// const CLIENT_ID = 'e09fc0de-c958-424f-83a2-e56a721d331b';
|
||||
// const CLIENT_SECRET = 'JA3cwsqSGHFtjMwd5XoF5L5';
|
||||
|
||||
let driver = new FileApiDriverOneDrive(CLIENT_ID, CLIENT_SECRET);
|
||||
//let driver = new FileApiDriverOneDrive(CLIENT_ID, CLIENT_SECRET);
|
||||
let driver = new FileApiDriverOneDrive(oneDriveApi);
|
||||
let auth = Setting.value('sync.onedrive.auth');
|
||||
|
||||
if (auth) {
|
||||
auth = JSON.parse(auth);
|
||||
} else {
|
||||
//auth = await driver.api().oauthDance(vorpal);
|
||||
const oneDriveApiUtils = new OneDriveApiNodeUtils(driver.api());
|
||||
const oneDriveApiUtils = new OneDriveApiNodeUtils(oneDriveApi);
|
||||
auth = await oneDriveApiUtils.oauthDance(vorpal);
|
||||
Setting.setValue('sync.onedrive.auth', JSON.stringify(auth));
|
||||
}
|
||||
|
||||
driver.api().setAuth(auth);
|
||||
driver.api().on('authRefreshed', (a) => {
|
||||
//oneDriveApi.setAuth(auth);
|
||||
oneDriveApi.on('authRefreshed', (a) => {
|
||||
Setting.setValue('sync.onedrive.auth', JSON.stringify(a));
|
||||
});
|
||||
|
||||
let appDir = await driver.api().appDirectory();
|
||||
let appDir = await oneDriveApi.appDirectory();
|
||||
logger.info('App dir: ' + appDir);
|
||||
fileApi = new FileApi(appDir, driver);
|
||||
fileApi.setLogger(logger);
|
||||
|
@ -53,35 +53,49 @@ class OneDriveApiNodeUtils {
|
||||
|
||||
if (!query.code) return writeResponse(400, '"code" query parameter is missing');
|
||||
|
||||
let body = new FormData();
|
||||
body.append('client_id', this.api().clientId());
|
||||
body.append('client_secret', this.api().clientSecret());
|
||||
body.append('code', query.code ? query.code : '');
|
||||
body.append('redirect_uri', 'http://localhost:' + port.toString());
|
||||
body.append('grant_type', 'authorization_code');
|
||||
// let body = new FormData();
|
||||
// body.append('client_id', this.api().clientId());
|
||||
// body.append('client_secret', this.api().clientSecret());
|
||||
// body.append('code', query.code ? query.code : '');
|
||||
// body.append('redirect_uri', 'http://localhost:' + port.toString());
|
||||
// body.append('grant_type', 'authorization_code');
|
||||
|
||||
let options = {
|
||||
method: 'POST',
|
||||
body: body,
|
||||
};
|
||||
// let options = {
|
||||
// method: 'POST',
|
||||
// body: body,
|
||||
// };
|
||||
|
||||
fetch(this.api().tokenBaseUrl(), options).then((r) => {
|
||||
if (!r.ok) {
|
||||
errorMessage = 'Could not retrieve auth code: ' + r.status + ': ' + r.statusText;
|
||||
writeResponse(400, errorMessage);
|
||||
targetConsole.log('');
|
||||
targetConsole.log(errorMessage);
|
||||
server.destroy();
|
||||
return;
|
||||
}
|
||||
// fetch(this.api().tokenBaseUrl(), options).then((r) => {
|
||||
|
||||
return r.json().then((json) => {
|
||||
this.api().setAuth(json);
|
||||
writeResponse(200, 'The application has been authorised - you may now close this browser tab.');
|
||||
targetConsole.log('');
|
||||
targetConsole.log('The application has been successfully authorised.');
|
||||
server.destroy();
|
||||
});
|
||||
// this.api().execTokenRequest(query.code, 'http://localhost:' + port.toString()).then((r) => {
|
||||
// if (!r.ok) {
|
||||
// errorMessage = 'Could not retrieve auth code: ' + r.status + ': ' + r.statusText;
|
||||
// writeResponse(400, errorMessage);
|
||||
// targetConsole.log('');
|
||||
// targetConsole.log(errorMessage);
|
||||
// server.destroy();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// return r.json().then((json) => {
|
||||
// this.api().setAuth(json);
|
||||
// writeResponse(200, 'The application has been authorised - you may now close this browser tab.');
|
||||
// targetConsole.log('');
|
||||
// targetConsole.log('The application has been successfully authorised.');
|
||||
// server.destroy();
|
||||
// });
|
||||
// });
|
||||
|
||||
this.api().execTokenRequest(query.code, 'http://localhost:' + port.toString()).then(() => {
|
||||
writeResponse(200, 'The application has been authorised - you may now close this browser tab.');
|
||||
targetConsole.log('');
|
||||
targetConsole.log('The application has been successfully authorised.');
|
||||
server.destroy();
|
||||
}).catch((error) => {
|
||||
writeResponse(400, error.message);
|
||||
targetConsole.log('');
|
||||
targetConsole.log(error.message);
|
||||
server.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -41,6 +41,11 @@ class ScreenHeaderComponent extends Component {
|
||||
}
|
||||
|
||||
menu_synchronize() {
|
||||
this.props.dispatch({
|
||||
type: 'Navigation/NAVIGATE',
|
||||
routeName: 'OneDriveLogin',
|
||||
});
|
||||
|
||||
// const CLIENT_ID = 'e09fc0de-c958-424f-83a2-e56a721d331b';
|
||||
// const CLIENT_SECRET = 'JA3cwsqSGHFtjMwd5XoF5L5';
|
||||
|
||||
|
90
ReactNativeClient/lib/components/screens/onedrive-login.js
Normal file
90
ReactNativeClient/lib/components/screens/onedrive-login.js
Normal file
@ -0,0 +1,90 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { WebView, Button } from 'react-native';
|
||||
import { connect } from 'react-redux'
|
||||
import { Log } from 'lib/log.js'
|
||||
import { ScreenHeader } from 'lib/components/screen-header.js';
|
||||
import { OneDriveApi } from 'lib/onedrive-api.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
|
||||
class OneDriveLoginScreenComponent extends React.Component {
|
||||
|
||||
static navigationOptions(options) {
|
||||
return { header: null };
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { webviewUrl: '' };
|
||||
this.authCode_ = null;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({
|
||||
webviewUrl: this.api().authCodeUrl(this.redirectUrl()),
|
||||
});
|
||||
}
|
||||
|
||||
api() {
|
||||
return OneDriveApi.instance();
|
||||
|
||||
redirectUrl() {
|
||||
return 'https://login.microsoftonline.com/common/oauth2/nativeclient';
|
||||
}
|
||||
|
||||
async webview_load(noIdeaWhatThisIs) {
|
||||
// This is deprecated according to the doc but since the non-deprecated property (source)
|
||||
// doesn't exist, use this for now. The whole component is completely undocumented
|
||||
// at the moment so it's likely to change.
|
||||
const url = noIdeaWhatThisIs.url;
|
||||
|
||||
console.info('URL: ' + url);
|
||||
|
||||
if (!this.authCode_) {
|
||||
if (url.indexOf(this.redirectUrl() + '?code=') === 0) {
|
||||
let code = url.split('?code=');
|
||||
this.authCode_ = code[1];
|
||||
|
||||
await this.api().execTokenRequest(this.authCode_, this.redirectUrl(), true);
|
||||
Setting.setValue('sync.onedrive.auth', JSON.stringify(this.api().auth()));
|
||||
oneDriveApi.on('authRefreshed', (a) => {
|
||||
Setting.setValue('sync.onedrive.auth', JSON.stringify(a));
|
||||
});
|
||||
|
||||
let appDir = await this.api().appDirectory();
|
||||
|
||||
Log.info('APP DIR: ' + appDir);
|
||||
// fileApi = new FileApi(appDir, driver);
|
||||
// fileApi.setLogger(logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const source = {
|
||||
uri: this.state.webviewUrl,
|
||||
}
|
||||
|
||||
// <Button title="Start" onPress={() => this.startButton_press()}></Button>
|
||||
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<ScreenHeader navState={this.props.navigation.state} />
|
||||
<WebView
|
||||
source={source}
|
||||
style={{marginTop: 20}}
|
||||
onNavigationStateChange={(o) => { this.webview_load(o); }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const OneDriveLoginScreen = connect(
|
||||
(state) => {
|
||||
return {};
|
||||
}
|
||||
)(OneDriveLoginScreenComponent)
|
||||
|
||||
export { OneDriveLoginScreen };
|
@ -5,8 +5,10 @@ import { OneDriveApi } from 'lib/onedrive-api.js';
|
||||
|
||||
class FileApiDriverOneDrive {
|
||||
|
||||
constructor(clientId, clientSecret) {
|
||||
this.api_ = new OneDriveApi(clientId, clientSecret);
|
||||
//constructor(clientId, clientSecret) {
|
||||
constructor(api) {
|
||||
this.api_ = api;
|
||||
//this.api_ = new OneDriveApi(clientId, clientSecret);
|
||||
}
|
||||
|
||||
api() {
|
||||
|
@ -12,6 +12,15 @@ class OneDriveApi {
|
||||
};
|
||||
}
|
||||
|
||||
static instance() {
|
||||
if (this.instance_) return this.instance_;
|
||||
|
||||
const CLIENT_ID = 'e09fc0de-c958-424f-83a2-e56a721d331b';
|
||||
const CLIENT_SECRET = 'JA3cwsqSGHFtjMwd5XoF5L5';
|
||||
this.instance_ = new OneDriveApi(CLIENT_ID, CLIENT_SECRET);
|
||||
return this.instance_;
|
||||
}
|
||||
|
||||
dispatch(eventName, param) {
|
||||
let ls = this.listeners_[eventName];
|
||||
for (let i = 0; i < ls.length; i++) {
|
||||
@ -47,10 +56,6 @@ class OneDriveApi {
|
||||
return this.clientSecret_;
|
||||
}
|
||||
|
||||
// possibleOAuthDancePorts() {
|
||||
// return [1917, 9917, 8917];
|
||||
// }
|
||||
|
||||
async appDirectory() {
|
||||
let r = await this.execJson('GET', '/drive/special/approot');
|
||||
return r.parentReference.path + '/' + r.name;
|
||||
@ -66,6 +71,34 @@ class OneDriveApi {
|
||||
return 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?' + stringify(query);
|
||||
}
|
||||
|
||||
async execTokenRequest(code, redirectUri, isPublic = false) {
|
||||
let body = new shim.FormData();
|
||||
body.append('client_id', this.clientId());
|
||||
if (!isPublic) body.append('client_secret', this.clientSecret());
|
||||
body.append('code', code);
|
||||
body.append('redirect_uri', redirectUri);
|
||||
body.append('grant_type', 'authorization_code');
|
||||
|
||||
const r = await shim.fetch(this.tokenBaseUrl(), {
|
||||
method: 'POST',
|
||||
body: body,
|
||||
})
|
||||
|
||||
if (!r.ok) {
|
||||
const text = await r.text();
|
||||
throw new Error('Could not retrieve auth code: ' + r.status + ': ' + r.statusText + ': ' + text);
|
||||
}
|
||||
|
||||
try {
|
||||
const json = await r.json();
|
||||
this.setAuth(json);
|
||||
} catch (error) {
|
||||
const text = await r.text();
|
||||
error.message += ': ' + text;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
oneDriveErrorResponseToError(errorResponse) {
|
||||
if (!errorResponse) return new Error('Undefined error');
|
||||
|
||||
@ -181,90 +214,6 @@ class OneDriveApi {
|
||||
this.dispatch('authRefreshed', this.auth_);
|
||||
}
|
||||
|
||||
// async oauthDance(targetConsole = null) {
|
||||
// if (targetConsole === null) targetConsole = console;
|
||||
|
||||
// this.auth_ = null;
|
||||
|
||||
// let ports = this.possibleOAuthDancePorts();
|
||||
// let port = null;
|
||||
// for (let i = 0; i < ports.length; i++) {
|
||||
// let inUse = await tcpPortUsed.check(ports[i]);
|
||||
// if (!inUse) {
|
||||
// port = ports[i];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!port) throw new Error('All potential ports are in use - please report the issue at https://github.com/laurent22/joplin');
|
||||
|
||||
// let authCodeUrl = this.authCodeUrl('http://localhost:' + port);
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// let server = http.createServer();
|
||||
// let errorMessage = null;
|
||||
|
||||
// server.on('request', (request, response) => {
|
||||
// const query = urlParser.parse(request.url, true).query;
|
||||
|
||||
// function writeResponse(code, message) {
|
||||
// response.writeHead(code, {"Content-Type": "text/html"});
|
||||
// response.write(message);
|
||||
// response.end();
|
||||
// }
|
||||
|
||||
// if (!query.code) return writeResponse(400, '"code" query parameter is missing');
|
||||
|
||||
// let body = new shim.FormData();
|
||||
// body.append('client_id', this.clientId());
|
||||
// body.append('client_secret', this.clientSecret());
|
||||
// body.append('code', query.code ? query.code : '');
|
||||
// body.append('redirect_uri', 'http://localhost:' + port.toString());
|
||||
// body.append('grant_type', 'authorization_code');
|
||||
|
||||
// let options = {
|
||||
// method: 'POST',
|
||||
// body: body,
|
||||
// };
|
||||
|
||||
// fetch(this.tokenBaseUrl(), options).then((r) => {
|
||||
// if (!r.ok) {
|
||||
// errorMessage = 'Could not retrieve auth code: ' + r.status + ': ' + r.statusText;
|
||||
// writeResponse(400, errorMessage);
|
||||
// targetConsole.log('');
|
||||
// targetConsole.log(errorMessage);
|
||||
// server.destroy();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// return r.json().then((json) => {
|
||||
// this.auth_ = json;
|
||||
// writeResponse(200, 'The application has been authorised - you may now close this browser tab.');
|
||||
// targetConsole.log('');
|
||||
// targetConsole.log('The application has been successfully authorised.');
|
||||
// server.destroy();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// server.on('close', () => {
|
||||
// if (errorMessage) {
|
||||
// reject(new Error(errorMessage));
|
||||
// } else {
|
||||
// resolve(this.auth_);
|
||||
// }
|
||||
// });
|
||||
|
||||
// server.listen(port);
|
||||
|
||||
// enableServerDestroy(server);
|
||||
|
||||
// targetConsole.log('Please open this URL in your browser to authentify the application:');
|
||||
// targetConsole.log('');
|
||||
// targetConsole.log(authCodeUrl);
|
||||
// });
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
export { OneDriveApi };
|
@ -1,6 +1,7 @@
|
||||
let shim = {};
|
||||
|
||||
shim.fetch = typeof fetch !== 'undefined' ? fetch : null;
|
||||
shim.FormData = typeof FormData !== 'undefined' ? FormData : null;
|
||||
|
||||
if (!shim.fetch) {
|
||||
let moduleName = 'node-fetch';
|
||||
|
@ -19,6 +19,7 @@ import { FolderScreen } from 'lib/components/screens/folder.js'
|
||||
import { FoldersScreen } from 'lib/components/screens/folders.js'
|
||||
import { LoginScreen } from 'lib/components/screens/login.js'
|
||||
import { LoadingScreen } from 'lib/components/screens/loading.js'
|
||||
import { OneDriveLoginScreen } from 'lib/components/screens/onedrive-login.js'
|
||||
import { Setting } from 'lib/models/setting.js'
|
||||
import { Synchronizer } from 'lib/synchronizer.js'
|
||||
import { MenuContext } from 'react-native-popup-menu';
|
||||
@ -184,6 +185,7 @@ const AppNavigator = StackNavigator({
|
||||
Folders: { screen: FoldersScreen },
|
||||
Login: { screen: LoginScreen },
|
||||
Loading: { screen: LoadingScreen },
|
||||
OneDriveLogin: { screen: OneDriveLoginScreen },
|
||||
});
|
||||
|
||||
class AppComponent extends React.Component {
|
||||
|
Loading…
x
Reference in New Issue
Block a user