Skip to content

Commit f6ecd7c

Browse files
committed
Complete oauth functionality for coinbase
1 parent a33f851 commit f6ecd7c

File tree

7 files changed

+88
-37
lines changed

7 files changed

+88
-37
lines changed

src/components/Register/CoinbaseLogin.js

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
import React, { Component } from 'react'
2-
import { WebView, Linking } from 'react-native';
2+
import { WebView } from 'react-native';
33
import { NavigationActions } from 'react-navigation';
44
import { connect } from 'react-redux';
5+
import { COINBASE_CLIENT_ID as ID, COINBASE_REDIRECT_URI as URI } from '../../config'
56

6-
class CoinbaseConnect extends Component {
7-
render () {
8-
const uri = 'https://www.coinbase.com/oauth/authorize?client_id=030e132992e00eb796fcbf4eb1de09860ebd4fd865d462ff78265497dfef4842&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&response_type=code&scope=wallet%3Auser%3Aemail'
9-
const { navigate, navigation } = this.props
10-
const { showWebview } = navigation.state.params
7+
const coinbaseConnectUri = 'https://www.coinbase.com/oauth/authorize'
8+
const uri = `${coinbaseConnectUri}?client_id=${ID}&redirect_uri=${encodeURIComponent(URI)}&response_type=code&scope=wallet%3Auser%3Aemail`
119

12-
console.log(showWebview, "coinbase connect thingy")
13-
return (
14-
<WebView
15-
ref={(ref) => { this.webview = ref; }}
16-
source={{ uri }}
17-
style={{marginTop: 30}}
18-
onNavigationStateChange={(event) => {
19-
if (event.url.includes('?code=')) {
20-
let code = event.url.split('?code=').pop()
21-
console.log(code, true);
22-
this.webview.stopLoading();
23-
navigate('SignUp', { oauth: true, oauthProvider: 'coinbase' })
24-
}
25-
}}
26-
/>
27-
);
28-
}
29-
}
10+
const CoinbaseConnect = ({ navigate }) =>
11+
<WebView
12+
ref={(ref) => { this.webview = ref; }}
13+
source={{ uri }}
14+
style={{marginTop: 30}}
15+
onNavigationStateChange={(event) => {
16+
if (event.url.includes('?code=')) {
17+
let code = event.url.split('?code=').pop()
18+
this.webview.stopLoading();
19+
20+
navigate('SignUp', { oauth: true, oauthProvider: 'coinbase', code })
21+
}
22+
}}
23+
/>
3024

3125
const mapDispatchToProps = (dispatch) => {
3226
return {

src/components/Register/SignUp.js

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import _platform from '../../../native-base-theme/variables/platform';
1414
import styles from './styles'
1515
import { login as _login, registerAccount as _registerAccount } from '../../reducers/account'
1616
import { setLoading as _setLoading, showToast as _showToast } from '../../reducers/ui'
17-
import { getErrorMsg } from '../../helpers/functions'
17+
import { getErrorMsg, exchangeCoinbaseCodeForCredentials } from '../../helpers/functions'
1818

1919
const customStyles = {
2020
header: {
@@ -155,9 +155,33 @@ class SignUp extends Component {
155155
})
156156
}
157157

158+
async useCoinbaseAuth(indicateLoading, loginFn, oauth, oauthProvider, code) {
159+
const {
160+
access_token: accessToken,
161+
refresh_token: refreshToken,
162+
email
163+
} = await exchangeCoinbaseCodeForCredentials(code)
164+
indicateLoading(true, 'Connecting To Coinbase')
165+
const success = await loginFn(
166+
{ email, oauth, oauthProvider },
167+
{ failureRedirect: false, suppressToast: true }
168+
)
169+
indicateLoading(false)
170+
if (success) {
171+
console.log('logged in with Coinbase')
172+
return
173+
}
174+
this.setState({
175+
showForm: true,
176+
email,
177+
accessToken,
178+
refreshToken
179+
})
180+
}
181+
158182
submit = async () => {
159183
const { registerAccount, navigate, navigation, login, showToast } = this.props
160-
const { withGoogle } = navigation.state.params
184+
const { oauth, oauthProvider } = navigation.state.params
161185
const {
162186
username,
163187
email,
@@ -173,10 +197,10 @@ class SignUp extends Component {
173197
} else if (!email) {
174198
Alert.alert('Email is required')
175199
return
176-
} else if (!withGoogle && !password) {
200+
} else if (!oauth && !password) {
177201
Alert.alert('Password is required')
178202
return
179-
} else if (!withGoogle && password.length < 6) {
203+
} else if (!oauth && password.length < 6) {
180204
Alert.alert('Password must be 6 char min')
181205
return
182206
}
@@ -188,19 +212,20 @@ class SignUp extends Component {
188212
accessToken,
189213
refreshToken,
190214
serverAuthCode,
191-
withGoogle,
215+
oauth,
216+
oauth_provider: oauthProvider,
192217
invite_code: inviteCode
193218
})
194219
showToast('Account Created')
195220
} catch (err) {
196221
logger.error('submit, registerAccount', err)
197222
showToast(getErrorMsg(err))
198223
}
199-
if (withGoogle) {
224+
if (oauth) {
200225
try {
201-
await login({ username, accessToken, withGoogle })
226+
await login({ email, username, accessToken, oauth, oauthProvider })
202227
} catch (err) {
203-
logger.error('SignUp withGoogle', err)
228+
logger.error(`SignUp with oauth provider: ${oauthProvider}`, err)
204229
showToast(getErrorMsg(err))
205230
}
206231
} else {

src/components/Register/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class Register extends Component {
108108
title={"Continue With Coinbase"}
109109
block
110110
onPress={() => navigate('Coinbase Connect')}>
111-
<FontAwesome style={{flex: .1, padding: 10, paddingRight: 0}} color={baseColor} name={'google'} size={30} />
111+
<FontAwesome style={{flex: .1, padding: 10, paddingRight: 0}} color={baseColor} name={'shield'} size={30} />
112112
<Text style={customStyles.buttonText}>CONTINUE WITH COINBASE</Text>
113113
</Button>
114114
</View>

src/config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@ export const FIREBASE_DATABASE_URL = 'https://tokens-express-200615.firebaseio.c
1919
export const FIREBASE_PROJECT_ID = 'tokens-express-200615'
2020
export const FIREBASE_STORAGE_BUCKET = 'tokens-express-200615.appspot.com'
2121
export const FIREBASE_MESSAGING_SENDER_ID = '947782058234'
22+
export const COINBASE_CLIENT_ID = '030e132992e00eb796fcbf4eb1de09860ebd4fd865d462ff78265497dfef4842'
23+
export const COINBASE_CLIENT_SECRET = '5f160e92f4c3f5b45238eadecdb0a4e1b12150cce3283f38d84d45e3c15263d6'
24+
export const COINBASE_REDIRECT_URI = `${baseURL}/api/accounts/oauth/coinbase`
2225

2326
console.log({ baseURL })

src/helpers/api.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ export const googleLogin = async (params) => {
5959
return res.data
6060
}
6161

62+
export const coinbaseLogin = async (params) => {
63+
const res = await instance.post(`/accounts/coinbase-signin`, { ...params })
64+
return res.data
65+
}
66+
67+
export const fetchCoinbaseCredentials = async (code) => {
68+
const res = await instance.get(`/accounts/fetch-coinbase-credentials?code=${code}`)
69+
return res.data
70+
}
71+
6272
export const logoutAccount = async (notification_token) => {
6373
await instance.post(`/accounts/logout`, { notification_token })
6474
}

src/helpers/functions.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { NavigationActions } from 'react-navigation';
55
import {
66
setAuthHeader,
77
registerUserForPushNotifications,
8-
verifyTwoFactorAuth
8+
verifyTwoFactorAuth,
9+
fetchCoinbaseCredentials,
10+
googleLogin,
11+
coinbaseLogin
912
} from './api';
1013
import { setLoading } from '../reducers/ui'
1114
import { baseURL } from '../config'
@@ -156,7 +159,7 @@ export const get2FA = async function (id, dispatch) {
156159
}
157160
}
158161
}))
159-
})
162+
})
160163
}
161164

162165
export const asyncFilter = async (items, iter) => {
@@ -197,3 +200,17 @@ export const visitDeepLink = (url) => {
197200
// }))
198201
// }
199202
}
203+
204+
export const exchangeCoinbaseCodeForCredentials = async (code) => {
205+
const credentials = await fetchCoinbaseCredentials(code)
206+
return credentials
207+
}
208+
209+
export const oauthLogin = (provider) => {
210+
switch(provider.toLowerCase()) {
211+
case 'google':
212+
return googleLogin;
213+
case 'coinbase':
214+
return coinbaseLogin;
215+
}
216+
}

src/reducers/account.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,12 @@ async function configureSession(accessToken, userId, account, dispatch) {
190190
export const login = (params, options={}) => async (dispatch, getState) => {
191191
const { suppressToast, failureRedirect=true } = options
192192
const usingOauth = params && params.oauth
193+
let id
194+
let token
193195
try {
196+
id = await SecureStore.getItemAsync('id')
197+
token = await SecureStore.getItemAsync('token')
194198
let account = null
195-
let id = await SecureStore.getItemAsync('id')
196-
let token = await SecureStore.getItemAsync('token')
197199
const loginFn = usingOauth ? oauthLogin(params.oauthProvider) : loginAccount
198200
if (params) {
199201
dispatch(setLoading(true, 'Authorizing'))

0 commit comments

Comments
 (0)