From 45e394549c5f4eee12c9e5077445c7e9557f6e84 Mon Sep 17 00:00:00 2001 From: fabien0102 Date: Thu, 21 Sep 2017 23:00:33 +0200 Subject: [PATCH 1/5] Fix auth0 API requirements --- main.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index a073c8b..257c166 100644 --- a/main.js +++ b/main.js @@ -34,7 +34,8 @@ class App extends React.Component { _loginWithAuth0 = async () => { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, - response_type: 'token', + response_type: 'id_token', + nonce: 'alongrandomstringtopreventtokenreplayattacks', scope: 'openid name', redirect_uri: redirectUri, state: redirectUri, @@ -45,7 +46,8 @@ class App extends React.Component { _loginWithAuth0Twitter = async () => { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, - response_type: 'token', + response_type: 'id_token', + nonce: 'alongrandomstringtopreventtokenreplayattacks', scope: 'openid name', redirect_uri: redirectUri, connection: 'twitter', From 887db9b5a7a2db95c6cfd339c646e284d821e443 Mon Sep 17 00:00:00 2001 From: fabien0102 Date: Thu, 21 Sep 2017 23:02:37 +0200 Subject: [PATCH 2/5] Fix context into _handleAuth0Redirect `this.setState` can't work without the component context --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index 257c166..00bef6b 100644 --- a/main.js +++ b/main.js @@ -28,7 +28,7 @@ class App extends React.Component { username: undefined, }; componentDidMount() { - Linking.addEventListener('url', this._handleAuth0Redirect); + Linking.addEventListener('url', this._handleAuth0Redirect.bind(this)); } _loginWithAuth0 = async () => { From 3059d1a6d40888eaef2d4faf98fc8cb40f548545 Mon Sep 17 00:00:00 2001 From: fabien0102 Date: Wed, 4 Oct 2017 11:01:56 +0200 Subject: [PATCH 3/5] Use a real generated random string for nonce --- main.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index 00bef6b..77d53d3 100644 --- a/main.js +++ b/main.js @@ -6,6 +6,7 @@ import { View, Button, Linking, + AsyncStorage, } from 'react-native'; import jwtDecoder from 'jwt-decode'; @@ -35,7 +36,7 @@ class App extends React.Component { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', - nonce: 'alongrandomstringtopreventtokenreplayattacks', + nonce: await this._getNonce(), scope: 'openid name', redirect_uri: redirectUri, state: redirectUri, @@ -47,7 +48,7 @@ class App extends React.Component { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', - nonce: 'alongrandomstringtopreventtokenreplayattacks', + nonce: await this._getNonce(), scope: 'openid name', redirect_uri: redirectUri, connection: 'twitter', @@ -74,6 +75,26 @@ class App extends React.Component { this.setState({ username }); } + /** + * Generate a cryptographically random nonce. + * @param {Number} length + */ + _generateRandomString(length) { + const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._~'; + return [...Array(length)] + .map(() => charset.charAt(Math.floor(Math.random() * charset.length))) + .join(''); + } + + async _getNonce() { + let nonce = await AsyncStorage.getItem('nonce'); + if (!nonce) { + nonce = this._generateRandomString(16); + await AsyncStorage.setItem('nonce', nonce); + } + return nonce; + } + /** * Converts an object to a query string. */ From 2bbee5297df8e38559eb61a4426ba44ceba86d3d Mon Sep 17 00:00:00 2001 From: fabien0102 Date: Wed, 4 Oct 2017 11:02:42 +0200 Subject: [PATCH 4/5] Refactor signatures to have same format everywhere --- main.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.js b/main.js index 77d53d3..4ad2df5 100644 --- a/main.js +++ b/main.js @@ -28,11 +28,12 @@ class App extends React.Component { state = { username: undefined, }; + componentDidMount() { Linking.addEventListener('url', this._handleAuth0Redirect.bind(this)); } - _loginWithAuth0 = async () => { + async _loginWithAuth0() { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', @@ -44,7 +45,7 @@ class App extends React.Component { Expo.WebBrowser.openBrowserAsync(redirectionURL); } - _loginWithAuth0Twitter = async () => { + async _loginWithAuth0Twitter() { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', @@ -57,8 +58,7 @@ class App extends React.Component { Expo.WebBrowser.openBrowserAsync(redirectionURL); } - _handleAuth0Redirect = async (event) => { - console.log('yo'); + async _handleAuth0Redirect(event) { if (!event.url.includes('+/redirect')) { return; } From 12e4f191b33b7ff41909b5347f8a68ed64eff97d Mon Sep 17 00:00:00 2001 From: fabien0102 Date: Wed, 4 Oct 2017 15:11:13 +0200 Subject: [PATCH 5/5] Use arrow function style --- main.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.js b/main.js index 4ad2df5..e4ef2f3 100644 --- a/main.js +++ b/main.js @@ -33,7 +33,7 @@ class App extends React.Component { Linking.addEventListener('url', this._handleAuth0Redirect.bind(this)); } - async _loginWithAuth0() { + _loginWithAuth0 = async () => { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', @@ -45,7 +45,7 @@ class App extends React.Component { Expo.WebBrowser.openBrowserAsync(redirectionURL); } - async _loginWithAuth0Twitter() { + _loginWithAuth0Twitter = async () => { const redirectionURL = `${auth0Domain}/authorize` + this._toQueryString({ client_id: auth0ClientId, response_type: 'id_token', @@ -58,7 +58,7 @@ class App extends React.Component { Expo.WebBrowser.openBrowserAsync(redirectionURL); } - async _handleAuth0Redirect(event) { + _handleAuth0Redirect = async (event) => { if (!event.url.includes('+/redirect')) { return; } @@ -79,14 +79,14 @@ class App extends React.Component { * Generate a cryptographically random nonce. * @param {Number} length */ - _generateRandomString(length) { + _generateRandomString = (length) => { const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._~'; return [...Array(length)] .map(() => charset.charAt(Math.floor(Math.random() * charset.length))) .join(''); } - async _getNonce() { + _getNonce = async () => { let nonce = await AsyncStorage.getItem('nonce'); if (!nonce) { nonce = this._generateRandomString(16); @@ -98,7 +98,7 @@ class App extends React.Component { /** * Converts an object to a query string. */ - _toQueryString(params) { + _toQueryString = (params) => { return '?' + Object.entries(params) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) .join('&');