Skip to content

Commit

Permalink
refactor Odoo service
Browse files Browse the repository at this point in the history
  • Loading branch information
Todomir committed Aug 1, 2022
1 parent 598336f commit 878b71a
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 152 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.7",
"@react-native-cookies/cookies": "^6.2.1",
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"odoo-await": "^3.3.0",
"react": "18.0.0",
"react-native": "0.69.3",
"react-native-dotenv": "^3.3.1",
Expand Down
42 changes: 21 additions & 21 deletions src/context/OdooProvider/helpers/login.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
/* eslint-disable no-alert */
import AsyncStorage from '@react-native-async-storage/async-storage';
import OdooApi from '../../../services/odoo';
import {Alert} from 'react-native';
import createOdooService from '../../../services/odoo';

export const login = async ({server, username, password}) => {
try {
const odoo_api = await new OdooApi(server, username, password);
const odoo = createOdooService(server, username, password);
const databases = await odoo.getDatabases();
const [database] = databases;

const database_list = await odoo_api.database_list;
const connection = await odoo.connect(database);

if (database_list && database_list.length) {
const [database] = database_list;
const connection = await odoo_api.connect(database);

if (!connection) {
alert('Could not connect to database');
} else if (!connection.uid || typeof connection.uid !== 'number') {
alert('No database found');
}
const imagem = await odoo_api.get_user_image(connection.uid);
const res = {
...connection,
backend_url: odoo_api.server_backend_url,
avatar: imagem,
};
await AsyncStorage.setItem('session', JSON.stringify(res));
return res;
if (!connection) {
Alert.alert('Could not connect to database');
} else if (!connection.uid || typeof connection.uid !== 'number') {
Alert.alert('Invalid UID');
}

const res = {
...connection,
backend_url: odoo.backendUrl,
hostname: odoo.hostname,
avatar: null,
};

await AsyncStorage.setItem('session', JSON.stringify(res));

return res;
} catch (error) {
console.error(error);
}
Expand Down
21 changes: 17 additions & 4 deletions src/context/OdooProvider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import * as React from 'react';
import {login} from './helpers';
import {useNavigation} from '@react-navigation/native';
import AuthLoadingScreen from '../../components/auth';
import {Alert} from 'react-native';
import CookieManager from '@react-native-cookies/cookies';

const OdooContext = React.createContext({});

Expand Down Expand Up @@ -31,10 +33,21 @@ export default function OdooProvider({children}) {

const signIn = React.useCallback(
async ({server, username, password}) => {
const connection = await login({server, username, password});
if (connection) {
setSession(connection);
navigation.navigate('Home', {url: connection.backend_url});
try {
const connection = await login({server, username, password});
if (connection) {
setSession(connection);
await CookieManager.set(connection.backend_url, {
name: 'session_id',
value: connection.session_id,
domain: connection.hostname,
path: '/',
});
navigation.navigate('Home', {url: connection.backend_url});
}
} catch (error) {
Alert.alert('An unknown error occurred', error.message);
console.error(error);
}
},
[navigation],
Expand Down
48 changes: 28 additions & 20 deletions src/pages/backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import {WebView} from 'react-native-webview';

import styles from './style';
import {useOdooContext} from '../../context/OdooProvider';
import CookieManager from '@react-native-cookies/cookies';

const CHECK_COOKIE = `
ReactNativeWebView.postMessage("Cookie: " + document.cookie);
true;
`;

function ActivityIndicatorLoadingView() {
return (
Expand All @@ -18,31 +24,28 @@ function ActivityIndicatorLoadingView() {
}

export default function OdooBackend({navigation}) {
const [url, setUrl] = React.useState('');
const {session} = useOdooContext();

React.useEffect(() => {
try {
AsyncStorage.getItem('last_url').then(last_url => {
if (
last_url === 'about:blank' ||
typeof last_url === 'undefined' ||
last_url == null
) {
setUrl(session.backend_url);
} else {
setUrl(last_url);
}
});
} catch (error) {
console.error(error);
}
}, [session]);
const webViewRef = React.useRef(null);

const onNavigationStateChange = webViewState => {
console.log({
current: webViewState.url,
backendUrl: session.backend_url,
});
if (webViewRef.current) {
webViewRef.current.injectJavaScript(CHECK_COOKIE);
}
AsyncStorage.setItem('last_url', webViewState.url);
};

const onMessage = async event => {
const {data} = event.nativeEvent;
if (data.includes('Cookie:')) {
console.log(session);
await CookieManager.get(session.backend_url, true);
}
};

const handleBackendMessage = message => {
switch (message) {
case 'REACT_EXIT':
Expand All @@ -65,15 +68,20 @@ export default function OdooBackend({navigation}) {

return (
<WebView
source={{uri: url}}
source={{
uri: session.backend_url,
}}
ref={webViewRef}
onNavigationStateChange={onNavigationStateChange}
javaScriptEnabled={true}
domStorageEnabled={true}
sharedCookiesEnabled={true}
startInLoadingState={true}
renderLoading={ActivityIndicatorLoadingView}
injectedJavaScript={runFirst}
// injectedJavaScript={this.state.cookie}
onMessage={event => {
onMessage(event);
handleBackendMessage(event.nativeEvent.data);
}}
/>
Expand Down
10 changes: 8 additions & 2 deletions src/pages/login/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TouchableWithoutFeedback,
KeyboardAvoidingView,
Linking,
Alert,
} from 'react-native';

import {Button, Input} from 'react-native-elements';
Expand All @@ -15,7 +16,7 @@ import styles from './style';

import {useOdooContext} from '../../context/OdooProvider';

export default function SignInScreen({navigation}) {
export default function SignInScreen() {
const {signIn} = useOdooContext();

const [state, setState] = React.useState({
Expand All @@ -38,7 +39,12 @@ export default function SignInScreen({navigation}) {

const handleSignIn = async () => {
const {server, user, password} = state;
await signIn({server, username: user, password});
try {
await signIn({server, username: user, password});
} catch (error) {
Alert.alert('An unknown error occurred', error.message);
console.error(error);
}
};

return (
Expand Down
129 changes: 50 additions & 79 deletions src/services/odoo.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,91 +25,62 @@ const url_api = require('url');
// // }
// }

class OdooApi {
constructor(url, login, password) {
this.complete_url = url;
this.login = login;
this.password = password;
this._parseURL();
this.odoo = new Odoo({
host: this.hostname,
port: this.port,
username: this.login,
password: this.password,
protocol: this.protocol,
});
this.database_list = [];
const parseUrl = url => {
if (!url.includes('http')) {
url = 'https://' + url;
}
let urlParsed = url_api.parse(url);
const hostname = urlParsed.hostname;
const protocol = urlParsed.protocol.replace(':', '');

_parseURL() {
if (!this.complete_url.includes('http')) {
this.complete_url = 'https://' + this.complete_url;
}
var url = url_api.parse(this.complete_url);
this.hostname = url.hostname;
urlParsed.port = protocol === 'https' ? 443 : 80;
const completeUrl = urlParsed.href.replace(urlParsed.path, '/');
const backendUrl = completeUrl + 'web';

this.protocol = url.protocol.replace(':', '');
return {
hostname,
port: urlParsed.port,
protocol,
completeUrl,
backendUrl,
};
};

if (url.port === null) {
if (this.protocol === 'https') {
this.port = 443;
} else if (this.protocol === 'http') {
this.port = 80;
}
} else {
this.port = url.port;
}
this.server_complete_url = url.href.replace(url.path, '/');
this.server_backend_url = this.server_complete_url + 'web';
}
const createOdooService = (url, user, password) => {
const {hostname, port, protocol, backendUrl, completeUrl} = parseUrl(url);

get database_list() {
return this._getDatabases();
}
const odoo = new Odoo({
host: hostname,
port: port,
username: user,
password: password,
protocol: protocol,
});

_getDatabases() {
return this.odoo
.rpc_call('/web/database/list', {})
.then(response => {
if (response.success === true) {
console.log(response.data);
return response.data;
}
})
.catch(e => {
console.log(e);
});
}
const getDatabases = async () => {
try {
const res = await odoo.rpc_call('/web/database/list', {});
return res.data;
} catch (error) {
console.log(error);
}
};

connect(database) {
this.odoo.database = database;
return this.odoo
.connect()
.then(response => {
if (response.success === true) {
return response.data;
}
})
.catch(e => {
return false;
});
}
const connect = async db => {
odoo.database = db;
try {
const res = await odoo.connect();
return res.data;
} catch (error) {
console.error(error);
}
};

get_user_image(user_id) {
return this.odoo
.get('res.users', {
ids: [user_id],
fields: ['image_small'],
})
.then(response => {
if (response.success === true) {
return response.data[0].image_small;
}
})
.catch(e => {
return false;
});
}
}
return {
getDatabases,
connect,
...parseUrl(url),
};
};

export default OdooApi;
export default createOdooService;
Loading

0 comments on commit 878b71a

Please sign in to comment.