dsteem authentication flow

This commit is contained in:
Hüseyin Terkir 2018-07-23 19:11:23 +03:00
parent 79eedc3917
commit 0fe4385a35
8 changed files with 198 additions and 106 deletions

View File

@ -1,7 +1,6 @@
import React, { Component } from 'react';
import { StyleSheet, Image } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { Button, Card, CardItem,
Left, Right, Thumbnail, View,
Icon, Body, Text, Badge } from 'native-base';

View File

@ -1,13 +1,105 @@
import * as dsteem from 'dsteem';
import { getAccount } from './Dsteem';
import { AsyncStorage } from 'react-native';
export const LoginWithPostingKey = (publicKey, privateKey) => {
if (publicKey == dsteem.PrivateKey.fromString(privateKey).createPublic()) {
return true;
}
export const Login = (username, password) => {
let account;
let publicKeys;
let privateKeys;
let isPassword;
let isPostingKey;
return new Promise((resolve,reject) => {
getAccount(username).then((result) => {
if (result.length < 1) {
reject(new Error('Wrong @username'));
}
account = result[0];
// Public keys of user
publicKeys = {
active: account['active'].key_auths.map(x => x[0]),
memo: account['memo_key'],
owner: account['owner'].key_auths.map(x => x[0]),
posting: account['posting'].key_auths.map(x => x[0])
};
}).then(() => {
try {
// Set private keys of user
privateKeys = {
active: dsteem.PrivateKey.fromLogin(username, password, 'active').toString(),
memo: dsteem.PrivateKey.fromLogin(username, password, 'memo').toString(),
owner: dsteem.PrivateKey.fromLogin(username, password, 'owner').toString(),
posting: dsteem.PrivateKey.fromLogin(username, password, 'posting').toString()
}
} catch (error) {
reject(new Error('Wrong Key/Password'));
}
}).then(() => {
try {
isPassword = (dsteem.PrivateKey.fromLogin(username, password, 'posting').createPublic()).toString() === (publicKeys.posting).toString()
if (isPassword) {
let authType = {
'username': username,
'auth_type': 'master_key',
'posting_key': privateKeys.posting,
'active_key': privateKeys.active,
'memo_key': privateKeys.memo,
'owner_key': privateKeys.owner
}
AsyncStorage.setItem('isLoggedIn', 'true', () => {
AsyncStorage.setItem('user', JSON.stringify(authType), () => {
resolve(isPassword);
});
})
} else {
isPostingKey = (publicKeys.posting).toString() === (dsteem.PrivateKey.fromString(password).createPublic()).toString();
let authType = {
'username': username,
'auth_type': 'posting_key',
'posting_key': password
}
try {
if (isPostingKey) {
AsyncStorage.setItem('isLoggedIn', 'true', () => {
AsyncStorage.setItem('user', JSON.stringify(authType), () => {
resolve(isPostingKey)
})
})
} else {
reject(new Error('Wrong Key/Password'));
}
} catch (error) {
reject(new Error('Wrong Key/Password'));
}
}
} catch (error) {
reject(new Error('Wrong Key/Password'));
}
}).catch((err) => {
reject(new Error('Check your username'));
});
})
}
export const LoginWithMasterKey = (username, publicKey, masterKey) => {
if (publicKey == dsteem.PrivateKey.fromLogin(username, masterKey, 'posting').createPublic()) {
return true;
}
}

View File

@ -32,8 +32,8 @@ class FeedPage extends React.Component {
}
}
async componentDidMount() {
await AsyncStorage.getItem('user').then((result) => {
componentDidMount() {
AsyncStorage.getItem('user').then((result) => {
let user = JSON.parse(result);
getAccount(user.username).then((result) => {
this.setState({

0
src/screens/home/hot.js Normal file
View File

View File

View File

@ -1,18 +1,16 @@
import React, { Component } from 'react';
import { AsyncStorage, View } from 'react-native';
import { Content, Card, CardItem, Form, Item, Input, Label, Button, Text, Switch, Left, Right } from 'native-base';
import { View, ActivityIndicator, Text, StyleSheet } from 'react-native';
import { Item, Label, Input, Card, Button, Container, Icon } from 'native-base';
import { LoginWithMasterKey, LoginWithPostingKey } from '../../providers/steem/Auth'
import { getAccount } from '../../providers/steem/Dsteem'
import { Login } from '../../providers/steem/Auth';
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
master_key: '',
posting_key: '',
advanced: false
password: '',
isLoading: false
}
}
static navigationOptions = ({ navigation }) => {
@ -20,101 +18,91 @@ class LoginPage extends Component {
title: 'Login',
};
}
doLogin = async () => {
let publicWif;
let privateWif;
let masterWif;
let username;
try {
await getAccount(this.state.username).then((result) => {
doLogin = () => {
this.setState({ isLoading: true });
let password = this.state.password;
let username = this.state.username;
publicWif = result[0].posting.key_auths[0][0];
privateWif = this.state.posting_key;
masterWif = this.state.master_key;
username = this.state.username;
Login(username, password).then((result) => {
}).catch((err) => {
console.log(err);
alert(err)
alert('Username is not valid!');
});
if (this.state.advanced) {
if (LoginWithPostingKey(publicWif, privateWif)) {
let authObject = {
'username': username,
'posting_key': privateWif
}
AsyncStorage.setItem('isLoggedIn', 'true', () => {
AsyncStorage.setItem('user', JSON.stringify(authObject), () => {
this.props.navigation.navigate('LoggedIn');
})
});
}
} else {
if (LoginWithMasterKey(username, publicWif, masterWif)) {
let authObject = {
'username': username,
'master_key': masterWif,
}
AsyncStorage.setItem('isLoggedIn', 'true', () => {
AsyncStorage.setItem('user', JSON.stringify(authObject), () => {
this.props.navigation.navigate('LoggedIn');
})
});
}
if (result === true) {
this.props.navigation.navigate('LoggedIn');
}
} catch (error) {
alert(error)
}
};
}).catch((err) => {
alert(err)
this.setState({ isLoading: false });
});
}
render() {
return (
<Content>
<View style={{ padding: 20 }}>
<Card>
<Form>
<Item floatingLabel>
<Label>Username</Label>
<Input autoCapitalize = 'none' onChangeText={(text) => this.setState({username: text})} value={this.state.username}/>
</Item>
{ this.state.advanced === true ? (
<Container style={styles.container}>
<Card style={styles.header}>
<Text>
Header
</Text>
</Card>
<Card style={{ padding: 20 }}>
<View>
<Item rounded style={{ margin: 5 }}>
<Icon name='at'/>
<Input autoCapitalize='none' placeholder='username' onChangeText={(text) => this.setState({username: text})} value={this.state.username}/>
</Item>
<Item rounded style={{ margin: 5 }}>
<Icon name='md-lock'/>
<Input secureTextEntry={true} placeholder='Password or WIF' onChangeText={(text) => this.setState({password: text})} value={this.state.password}/>
</Item>
<View>
<Item floatingLabel>
<Label>Private Posting Key</Label>
<Input secureTextEntry={true} onChangeText={(text) => this.setState({posting_key: text})} value={this.state.posting_key} />
</Item>
{ this.state.isLoading ? (
<Button block light>
<ActivityIndicator/>
</Button>
) : (
<Button block info
onPress={() => { this.doLogin() }}>
<Text>Sign In</Text>
</Button>
)}
</View>
</View>
<View style={{ borderBottomColor: 'lightgray', borderBottomWidth: 1, marginVertical: 20 }}/>
<View style={{ flexDirection: 'row' }}>
<Icon name='information-circle' style={{ flex: 0.2 }}/>
<Text style={{ flex: 0.8 }}>
Don't worry!
Your password is kept locally on your device and removed upon logout!
</Text>
</View>
) : (
<Item floatingLabel>
<Label>Master/ Main Password</Label>
<Input secureTextEntry={true} onChangeText={(text) => this.setState({master_key: text})} value={this.state.master_key}/>
</Item>
) }
<CardItem>
<Left>
<Text>Advanced</Text>
</Left>
<Right>
<Switch value={this.state.advanced}
onValueChange={(value) => { this.setState({ advanced: value }) }}
/>
</Right>
</CardItem>
<Button style={{ alignSelf: 'center', margin: 5 }}
block info onPress={() => { this.doLogin() }}>
<Text>Sign In</Text>
</Button>
</Form>
</Card>
</View>
</Content>
<Card style={styles.footer}>
<Text>
Footer
</Text>
</Card>
</Container>
)
}
}
const styles = StyleSheet.create({
container: {
margin: 0,
padding: 0,
backgroundColor: '#f1f1f1',
},
header: {
flex: 1,
padding: 5
},
footer: {
bottom: 0,
flex: 1
}
});
export default LoginPage;

View File

@ -19,7 +19,7 @@ export class AuthLoadingScreen extends React.Component {
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
this.props.navigation.navigate(isLoggedIn ? 'LoggedIn' : 'LoggedOut');
}
// Render any loading content that you like here
@ -27,7 +27,6 @@ export class AuthLoadingScreen extends React.Component {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}

View File

@ -156,10 +156,10 @@ export class LoggedInSideBar extends Component {
};
}
async componentDidMount() {
componentDidMount() {
AsyncStorage.getItem('user').then((result) => {
let res = JSON.parse(result);
if (res.master_key) {
if (res.auth_type === 'master_key') {
this.setState({ loginType: 'master_key' });
} else {
this.setState({ loginType: 'posting_key' });
@ -180,6 +180,12 @@ export class LoggedInSideBar extends Component {
});
}
Logout = () => {
AsyncStorage.clear().then(() => {
this.props.navigation.navigate('LoggedOut');
});
}
render() {
return (
<Container>
@ -228,6 +234,14 @@ export class LoggedInSideBar extends Component {
</Right>}
</ListItem>}
/>
<ListItem noBorder onPress={() => this.Logout() }>
<Left>
<Icon active name="log-out" style={{ color: "#777", fontSize: 26, width: 30 }}/>
<Text style={styles.text}>
Logout
</Text>
</Left>
</ListItem>
</Content>
</Container>
);