Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Basic auth works, forms is going to cause some troubles #40

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/actions/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,10 @@ export function setHostname(host) {
export function getHostName() {
return HOSTNAME;
}

export function addBrowserAuthToHostname(user, pass) {
// const hostname = `http://test:[email protected]:8989`;
const split = HOSTNAME.split('//');
const newHost = `${split[0]}//${user}:${pass}@${split[1]}`;
HOSTNAME = newHost;
}
2 changes: 1 addition & 1 deletion app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class App extends Component {
componentDidMount() {
// this.setState({initialLoad: false}); // eslint-disable-line
AsyncStorage.getItem(STORAGE_KEY).then((data) => {
console.log(STORAGE_KEY);
console.log('AsyncStorage', STORAGE_KEY, data);
this.setState({initialLoad: false}); // eslint-disable-line
if (data) {
const {hostname, apiKey} = JSON.parse(data);
Expand Down
110 changes: 110 additions & 0 deletions app/components/InitialSetup/AuthenticationPrompt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React, {Component, PropTypes} from 'react';
import {
View,
Text,
AsyncStorage,
StyleSheet,
TextInput,
TouchableOpacity,
} from 'react-native';
import * as apiActions from '../../actions/api';
import {STORAGE_KEY} from '../../constants/variables';
import {BLUE, BORDER_COLOR} from '../../constants/brand';

const styles = StyleSheet.create({
root: {
flex: 1,
marginTop: 40,
padding: 20,
},
headline: {
alignSelf: 'center',
marginBottom: 40,
textAlign: 'center',
},
label: {
marginBottom: 5,
color: 'black',
},
textInput: {
height: 40,
borderColor: BORDER_COLOR,
borderWidth: 1,
borderRadius: 4,
padding: 4,
marginBottom: 20,
},
saveBtn: {
backgroundColor: BLUE,
borderRadius: 4,
padding: 20,
color: 'white',
textAlign: 'center',
},

});

class AuthenticationPrompt extends Component {

static propTypes = {
onSuccess: PropTypes.func.isRequired,
}

constructor() {
super();
this.state = {
username: '',
password: '',
};
}

onPressButton() {
AsyncStorage.getItem(STORAGE_KEY).then((data) => {
console.log('AsyncStorage', STORAGE_KEY, data);
if (data) {
apiActions.addBrowserAuthToHostname(this.state.username, this.state.password);
const {apiKey} = JSON.parse(data);
const newData = {
hostname: apiActions.getHostName(),
apiKey,
};
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(newData));
this.props.onSuccess();
}
});
}

render() {
return (
<View style={styles.root}>
<Text style={styles.headline}>To be able to view Images you need to provide username and password</Text>
<View>
<Text style={styles.label}>Username</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
style={styles.textInput}
onChangeText={(username) => this.setState({username})}
value={this.state.username}
/>

<Text style={styles.label}>Password</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
style={styles.textInput}
onChangeText={(password) => this.setState({password})}
value={this.state.password}
secureTextEntry
/>

<TouchableOpacity onPress={() => this.onPressButton()}>
<Text style={styles.saveBtn}>Save</Text>
</TouchableOpacity>
</View>
</View>
);
}
}

export default AuthenticationPrompt;
14 changes: 12 additions & 2 deletions app/components/InitialSetup/ConfigureApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ const styles = StyleSheet.create({

});

const withoutAuthStuff = (host) => {
if (host && host.indexOf('@') > 0) {
const split = host.split('//');
const rest = split[1].split('@');
return `${split[0]}//${rest[1]}`;
}
return host;
};

class ConfigureApp extends Component {

static propTypes = {
Expand Down Expand Up @@ -68,7 +77,8 @@ class ConfigureApp extends Component {
// save to async storage
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(this.state));
if (this.props.onSuccess) {
this.props.onSuccess();
console.log('success');
this.props.onSuccess(); // TODO hmm not called ?
}
} else {
Alert.alert('Error', 'Unable to save, please try again');
Expand Down Expand Up @@ -103,7 +113,7 @@ class ConfigureApp extends Component {
onEndEditing={() => this.isValidURL()}
onChangeText={(hostname) => this.setState({hostname})}
value={this.state.hostname}
placeholder={apiActions.getHostName() || 'http://123.1.2.4:8989'}
placeholder={withoutAuthStuff(apiActions.getHostName()) || 'http://123.1.2.4:8989'}
/>

<Text style={styles.label}>Sonarr API key</Text>
Expand Down
24 changes: 16 additions & 8 deletions app/components/Navigation/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {Component, PropTypes} from 'react';
import {Alert, StyleSheet, View} from 'react-native';
import {StyleSheet, View} from 'react-native';
import TabNavigator from 'react-native-tab-navigator';
import Icon from 'react-native-vector-icons/FontAwesome';
import {connect} from 'react-redux';
Expand All @@ -11,6 +11,7 @@ import {BLUE} from '../../constants/brand';
import SeriesNavigation from './SeriesNavigation';
import ActivityNavigation from './ActivityNavigation';
import ConfigureApp from '../InitialSetup/ConfigureApp';
import AuthenticationPrompt from '../InitialSetup/AuthenticationPrompt';
import ModalWrapper from '../Modal/ModalWrapper';

const styles = StyleSheet.create({
Expand All @@ -34,6 +35,7 @@ class Navigation extends Component {
this.state = {
selectedTab: 'series',
loaded: false,
authProblems: false,
};
}

Expand Down Expand Up @@ -64,14 +66,13 @@ class Navigation extends Component {

this.props.getSystemStatus().then((statusResponse) => {
console.log('system status', statusResponse);
if (statusResponse.payload.authentication === 'basic' || statusResponse.payload.authentication === 'forms') {
axios.get(apiActions.getHostName()).then(() => {}).catch((error) => {
if (statusResponse.payload &&
(statusResponse.payload.authentication === 'basic' || statusResponse.payload.authentication === 'forms')) {
axios.get(apiActions.getHostName())
.then(() => { console.log('authenticated'); })
.catch((error) => {
if (error.status === 401) {
Alert.alert(
'Error',
'Unauthorized, App will work but no images are displayed...sorry ' +
'(turn of authentication) or help out at https://github.com/arnif/sonarr-native'
);
this.setState({authProblems: true});
}
});
}
Expand All @@ -82,6 +83,13 @@ class Navigation extends Component {
if (!this.state.loaded) {
return null;
}
if (this.state.authProblems) {
return (
<AuthenticationPrompt
onSuccess={() => this.setState({authProblems: false})}
/>
);
}
return (
<View style={{flex: 1}}>
<ModalWrapper />
Expand Down
3 changes: 3 additions & 0 deletions app/components/Widgets/SmartImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import * as apiActions from '../../actions/api';

export const getImageUrl = (item, type) => {
const hostname = apiActions.getHostName();
// const hostname = `http://test:[email protected]:8989`;
console.log('hostname', hostname);
const hasPosterImage = item.get('images').find((i) => i.get('coverType') === type);
const posterImage = hasPosterImage && hasPosterImage.get('url');
if (!posterImage) {
Expand All @@ -17,6 +19,7 @@ export const getImageUrl = (item, type) => {

const SmartImage = ({item, type, style}) => {
const imageUrl = getImageUrl(item, type);
console.log(imageUrl);
return (
<Image source={{uri: imageUrl}} style={style} />
);
Expand Down
6 changes: 3 additions & 3 deletions wrapper.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import {applyMiddleware, combineReducers, createStore} from 'redux';
import {Provider} from 'react-redux';
import createLogger from 'redux-logger';
// import createLogger from 'redux-logger';
import App from './app/app';
import * as reducers from './app/reducers';
import promiseMiddleware from './app/lib/promiseMiddleware';
Expand All @@ -10,8 +10,8 @@ import inAppNotificationMiddleware from './app/lib/inAppNotificationMiddleware';

const middlewares = [promiseMiddleware, inAppNotificationMiddleware];
if (process.env.NODE_ENV === 'development') {
const logger = createLogger();
middlewares.push(logger);
// const logger = createLogger();
// middlewares.push(logger);
}
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
const rootReducer = combineReducers({...reducers});
Expand Down