-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathApp.js
125 lines (110 loc) · 3.89 KB
/
App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import React from 'react';
// For debugging
import env from './environment';
// Persistent storage
import AsyncStorage from '@react-native-async-storage/async-storage';
// Navigation
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
// UI
import AppMenu from './components/AppMenu';
import Login from './components/Login';
import Home from './components/Home';
import AllBoards from './components/AllBoards';
import BoardDetails from './components/BoardDetails';
import Card from './components/Card';
// Store
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { setServer } from './store/serverSlice';
import { setToken } from './store/tokenSlice';
// For creating an URL handler to retrieve the device token
import * as Linking from 'expo-linking';
// btoa isn't supported by android (and maybe also iOS)
import {encode as btoa} from 'base-64'
// Create Stack navigator
const Stack = createStackNavigator()
// Application
class App extends React.Component {
constructor(props) {
console.log('initialising app')
super(props)
// Register handler to catch Nextcloud's redirect after successfull login
Linking.addEventListener('url', (url) => {this.handleRedirect(url)})
}
componentDidMount() {
// Retrieve token from storage if available
if (!env.expoDebug) {
AsyncStorage.getItem('NCtoken').then(token => {
if (token !== null) {
console.log('token retrieved from asyncStorage', token)
this.props.setToken('Basic ' + token)
AsyncStorage.getItem('NCServer').then(server => {
if (server !== null) {
console.log('server retrieved from asyncStorage', server)
this.props.setServer(server)
}
})
}
})
} else {
// Expo doesn't support registering URL protocol handler so we hardcode
// authentication parameters in environment.js file
console.log('expo debug mode: setting token and server from hardcoded value')
this.props.setToken(env.token)
this.props.setServer(env.server)
}
}
// Function to retrieve the device's token and save it after user logged in
handleRedirect = async ({url}) => {
if (url.startsWith('nc://login/server')) {
console.log('Received the expected nc:// redirect', url)
user = url.substring(url.lastIndexOf('user:')+5, url.lastIndexOf('&'))
pwd = url.substring(url.lastIndexOf(':')+1)
token = btoa(user + ':' + pwd)
console.log('Persisting token in asyncStorage', token)
// TODO Use expo-secure-store to securely store the token
AsyncStorage.setItem('NCtoken', token);
console.log('Saving token in store')
this.props.setToken('Basic ' + token)
}
}
render() {
if (this.props.token.value === null) {
// No token is stored yet, we need to get one
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={{ title: 'Login' }}/>
<Stack.Screen name="Login" component={Login}/>
</Stack.Navigator>
</NavigationContainer>
)
} else {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="AllBoards" component={AllBoards} />
<Stack.Screen name="BoardDetails" component={BoardDetails} />
<Stack.Screen name="CardDetails" component={Card} />
<Stack.Screen name="NewCard" component={Card} />
</Stack.Navigator>
</NavigationContainer>
)
}
}
}
// Connect to store
const mapStateToProps = state => ({
token: state.token
})
const mapDispatchToProps = dispatch => (
bindActionCreators( {
setServer,
setToken
}, dispatch)
)
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)