diff --git a/package-lock.json b/package-lock.json index 03cd7b54a..bbe4554fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2455,7 +2455,7 @@ }, "buffer": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", @@ -3021,6 +3021,22 @@ "gud": "^1.0.0" } }, + "cross-fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-1.1.1.tgz", + "integrity": "sha512-+VJE04+UfxxmBfcnmAu/lKor53RUCx/1ilOti4p+JgrnLQ4AZZIRoe2OEd76VaHyWQmQxqKnV+TaqjHC4r0HWw==", + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + }, + "dependencies": { + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + } + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -9915,6 +9931,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "sc2-sdk": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sc2-sdk/-/sc2-sdk-1.0.2.tgz", + "integrity": "sha512-QADFzQYCsm6OOQE3cxd/NEhSTEtcohzJ6KQN4E5YaEO/bl2WgWy1Dgz4SFRhjIwTh5luzad2TqfUN7uF4IL8xg==", + "requires": { + "cross-fetch": "^1.1.1", + "debug": "^2.2.0" + } + }, "secp256k1": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", @@ -9940,7 +9965,7 @@ "dependencies": { "commander": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { "graceful-readlink": ">= 1.0.0" diff --git a/package.json b/package.json index 9e047ea51..a808ed538 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "redux-promise": "^0.6.0", "redux-thunk": "^2.3.0", "remarkable": "^1.7.1", - "rn-placeholder": "^1.2.0" + "rn-placeholder": "^1.2.0", + "sc2-sdk": "^1.0.2" }, "devDependencies": { "babel-eslint": "^8.2.6", diff --git a/src/providers/steem/auth.js b/src/providers/steem/auth.js index 381feb838..676f9455f 100644 --- a/src/providers/steem/auth.js +++ b/src/providers/steem/auth.js @@ -1,170 +1,181 @@ +/*eslint-disable no-unused-vars*/ +/*eslint-disable no-console*/ import * as dsteem from "dsteem"; import { getAccount } from "./dsteem"; import { setUserData, setAuthStatus } from "../../realm/realm"; -/*eslint-disable-next-line no-unused-vars*/ -import { encryptKey, decryptKey } from "../../utils/crypto"; +import * as sc2 from "sc2-sdk"; +import steemConnect from "./steemConnectAPI"; +/*eslint-enable no-unused-vars*/ export const Login = (username, password) => { - let account; - let publicKeys; - let privateKeys; - let isPassword; - let isPostingKey; - let pinCode = "pinCode"; + let account; + let publicKeys; + let privateKeys; + let isPassword; + let isPostingKey; + let pinCode = "pinCode"; - return new Promise((resolve, reject) => { - // Get user account data from STEEM Blockchain - getAccount(username) - .then(result => { - if (result.length < 1) { - reject(new Error("Wrong @username")); - } + return new Promise((resolve, reject) => { + // Get user account data from STEEM Blockchain + getAccount(username) + .then(result => { + if (result.length < 1) { + reject(new Error("Wrong @username")); + } - account = result[0]; + 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(() => { - // Validate Pasword/Key - try { - // Validate Master Key - /*eslint-disable no-mixed-spaces-and-tabs*/ - isPassword = + // 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(() => { + // Validate Pasword/Key + try { + // Validate Master Key + /*eslint-disable no-mixed-spaces-and-tabs*/ + isPassword = dsteem.PrivateKey.fromLogin( - username, - password, - "posting" + username, + password, + "posting" ) - .createPublic() - .toString() === publicKeys.posting.toString(); + .createPublic() + .toString() === publicKeys.posting.toString(); - if (isPassword) { - /** + if (isPassword) { + /** * User data * TODO: Encryption */ - let userData = { - username: username, - authType: "masterKey", - masterKey: encryptKey(password, pinCode), - postingKey: encryptKey( - privateKeys.posting, - pinCode - ), - activeKey: encryptKey(privateKeys.active, pinCode), - memoKey: encryptKey(privateKeys.memo, pinCode), - }; - let authData = { - isLoggedIn: true, - }; + let userData = { + username: username, + authType: "masterKey", + masterKey: encryptKey(password, pinCode), + postingKey: encryptKey( + privateKeys.posting, + pinCode + ), + activeKey: encryptKey(privateKeys.active, pinCode), + memoKey: encryptKey(privateKeys.memo, pinCode), + }; + let authData = { + isLoggedIn: true, + }; - // Set auth state to true - setAuthStatus(authData) - .then(() => { - // Save user data to Realm DB - setUserData(userData) - .then(() => { - resolve(isPassword); - }) - .catch(err => { - reject(err); - }); - }) - .catch(err => { - reject(err); - }); - } else { - // Validate Posting Key - isPostingKey = + // Set auth state to true + setAuthStatus(authData) + .then(() => { + // Save user data to Realm DB + setUserData(userData) + .then(() => { + resolve(isPassword); + }) + .catch(err => { + reject(err); + }); + }) + .catch(err => { + reject(err); + }); + } else { + // Validate Posting Key + isPostingKey = publicKeys.posting.toString() === dsteem.PrivateKey.fromString(password) - .createPublic() - .toString(); + .createPublic() + .toString(); - /** + /** * User data * TODO: Encryption */ - let userData = { - username: username, - authType: "postingKey", - postingKey: privateKeys.posting, - masterKey: "", - activeKey: "", - memoKey: "", - }; + let userData = { + username: username, + authType: "postingKey", + postingKey: privateKeys.posting, + masterKey: "", + activeKey: "", + memoKey: "", + }; - let authData = { - isLoggedIn: true, - }; + let authData = { + isLoggedIn: true, + }; - try { - if (isPostingKey) { - // Set auth state to true - setAuthStatus(authData) - .then(() => { - // Save user data to Realm DB - setUserData(userData) - .then(() => { - resolve(isPostingKey); - }) - .catch(err => { - reject(err); - }); - }) - .catch(err => { - reject(err); - }); - } 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 => { - // eslint-disable-next-line + try { + if (isPostingKey) { + // Set auth state to true + setAuthStatus(authData) + .then(() => { + // Save user data to Realm DB + setUserData(userData) + .then(() => { + resolve(isPostingKey); + }) + .catch(err => { + reject(err); + }); + }) + .catch(err => { + reject(err); + }); + } 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 => { + // eslint-disable-next-line console.log(err); - reject(new Error("Check your username")); - }); - }); + reject(new Error("Check your username")); + }); + }); }; + +export const loginWithSC2 = async (access_token) => { + await steemConnect.setAccessToken(access_token); + steemConnect.me((error, result) => { + console.log(error, result); + return result; + }); +}; \ No newline at end of file diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js index 1ae3dcb0f..e0c699dda 100644 --- a/src/providers/steem/dsteem.js +++ b/src/providers/steem/dsteem.js @@ -9,7 +9,7 @@ import { parsePosts, parseComments } from "../../utils/postParser"; let rewardFund = null; let medianPrice = null; -let client; +let client = new Client("https://api.steemit.com"); getClient = async () => { let server = await AsyncStorage.getItem("server"); diff --git a/src/providers/steem/steemConnectAPI.js b/src/providers/steem/steemConnectAPI.js new file mode 100644 index 000000000..a8c62928a --- /dev/null +++ b/src/providers/steem/steemConnectAPI.js @@ -0,0 +1,8 @@ +import sc2 from "sc2-sdk"; + +const api = sc2.Initialize({ + app: "esteem-app", + callbackURL: "http://localhost:3415", +}); + +export default api; \ No newline at end of file diff --git a/src/screens/index.js b/src/screens/index.js index b883dfc3e..2303b87da 100755 --- a/src/screens/index.js +++ b/src/screens/index.js @@ -14,6 +14,7 @@ import Editor from "./editor/editor"; import Discover from "./discover/discover"; import Settings from "./settings/settings"; import Notifications from "./notifications/notification"; +import SteemConnect from "./steem-connect/steemConnect"; import PostCard from "../components/post-card/postCard"; import Search from "../components/search/search"; @@ -40,6 +41,7 @@ function registerScreens() { Navigation.registerComponent("navigation.eSteem.Author", () => Author); Navigation.registerComponent("navigation.eSteem.PostCard", () => PostCard); Navigation.registerComponent("navigation.eSteem.Search", () => Search); + Navigation.registerComponent("navigation.eSteem.SteemConnect", () => SteemConnect); } module.exports = { diff --git a/src/screens/login/login.js b/src/screens/login/login.js index 3f1204517..e255cbbac 100644 --- a/src/screens/login/login.js +++ b/src/screens/login/login.js @@ -9,7 +9,8 @@ import { Linking, BackHandler, Dimensions, - TextInput + TextInput, + WebView } from "react-native"; import Ionicons from "react-native-vector-icons/Ionicons"; @@ -75,12 +76,15 @@ class LoginPage extends Component { Navigation.pop(this.props.componentId); return true; }); + Linking.getInitialURL().then((url) => { + console.log(url); + }); } componentWillUnmount() { BackHandler.removeEventListener("hardwareBackPress"); } - + doLogin = () => { this.setState({ isLoading: true }); @@ -112,6 +116,26 @@ class LoginPage extends Component { } } + loginwithSc2 = () => { + Navigation.showModal({ + stack: { + children: [{ + component: { + name: "navigation.eSteem.SteemConnect", + passProps: {}, + options: { + topBar: { + title: { + text: "Login via SC2" + } + } + } + } + }] + } + }); + } + render() { return ( @@ -315,7 +339,37 @@ class LoginPage extends Component { - + + + + + LOGIN + + + diff --git a/src/screens/steem-connect/steemConnect.js b/src/screens/steem-connect/steemConnect.js new file mode 100644 index 000000000..a7bf5d5ef --- /dev/null +++ b/src/screens/steem-connect/steemConnect.js @@ -0,0 +1,29 @@ +import React, { Component } from "react"; +import { View, Text, WebView } from "react-native"; +import { loginWithSC2 } from "../../providers/steem/auth"; + +export default class SteemConnect extends Component { + constructor(props) { + super(props); + this.state = { + }; + } + + onNavigationStateChange(event){ + console.log(event.url); + let access_token = event.url.match(/\?(?:access_token)\=([\S\s]*?)\&/)[1]; + console.log(access_token); + loginWithSC2(access_token); + } + + render() { + return ( + + this.onNavigationStateChange(state)} + // TODO: Move it to constants as a object + source={{ uri: "https://steemconnect.com/oauth2/authorize?client_id=esteem-app&redirect_uri=http%3A%2F%2F127.0.0.1%3A3415%2F&scope=vote%2Ccomment%2Cdelete_comment%2Ccomment_options%2Ccustom_json%2Cclaim_reward_balance" }}/> + + ); + } +}