aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorIvan Chen <ivan@thetaggid.com>2020-10-19 14:09:01 -0400
committerGitHub <noreply@github.com>2020-10-19 14:09:01 -0400
commitf5853b77ef9506df056029282c475e5628fb6ab0 (patch)
treefd6c50c0ef7b8c133897b6a5f8cac64ac5e6aa2b /src/components
parentab7fa09af967e0a8cf2ca53dfb24f8bc8a6886f7 (diff)
[TMA-272] Add browser login flow to Instagram social linking (#56)
* added in-app browser package and added social link for instagram * added comments and improved code clarity * added more skeleton code * Finished FB linking * updated facebook oauth to request for permission * finished twitter sign on * minor fixes
Diffstat (limited to 'src/components')
-rw-r--r--src/components/onboarding/SocialMediaLinker.tsx114
1 files changed, 108 insertions, 6 deletions
diff --git a/src/components/onboarding/SocialMediaLinker.tsx b/src/components/onboarding/SocialMediaLinker.tsx
index fc823979..e7f78834 100644
--- a/src/components/onboarding/SocialMediaLinker.tsx
+++ b/src/components/onboarding/SocialMediaLinker.tsx
@@ -1,12 +1,23 @@
+import AsyncStorage from '@react-native-community/async-storage';
import React from 'react';
import {
+ Alert,
+ Image,
StyleSheet,
- TouchableOpacityProps,
Text,
TouchableOpacity,
- Image,
+ TouchableOpacityProps,
} from 'react-native';
+import InAppBrowser from 'react-native-inappbrowser-reborn';
import {LinkerType} from 'src/types';
+import {
+ LINK_FB_ENDPOINT,
+ LINK_FB_OAUTH,
+ LINK_IG_ENDPOINT,
+ LINK_IG_OAUTH,
+ LINK_TWITTER_ENDPOINT,
+ LINK_TWITTER_OAUTH,
+} from '../../constants';
import {SOCIAL_FONT_COLORS} from '../../constants/constants';
import SocialIcon from '../common/SocialIcon';
@@ -17,15 +28,106 @@ interface SocialMediaLinkerProps extends TouchableOpacityProps {
const SocialMediaLinker: React.FC<SocialMediaLinkerProps> = ({
social: {label},
}) => {
+
const [state, setState] = React.useState({
authenticated: false,
});
- const handlePress = () => {
- setState({
- ...state,
- authenticated: !state.authenticated,
+ const integrated_endpoints: {[label: string]: [string, string]} = {
+ Instagram: [LINK_IG_OAUTH, LINK_IG_ENDPOINT],
+ Facebook: [LINK_FB_OAUTH, LINK_FB_ENDPOINT],
+ Twitter: [LINK_TWITTER_OAUTH, LINK_TWITTER_ENDPOINT]
+ };
+
+ const registerSocialLink: (token: string) => Promise<boolean> = async (
+ callback_url,
+ ) => {
+ if (!(label in integrated_endpoints)) {
+ // This error is already handled earlier, more of a safety check here
+ return false;
+ }
+ const user_token = await AsyncStorage.getItem('token');
+ const response = await fetch(integrated_endpoints[label][1], {
+ method: 'POST',
+ headers: {
+ Authorization: `Token ${user_token}`,
+ },
+ body: JSON.stringify({
+ callback_url: callback_url,
+ }),
});
+ if (!(response.status === 201)) {
+ console.log(await response.json());
+ }
+ return response.status === 201;
+ };
+
+ const handlePress = async () => {
+ try {
+ const isAvailable = await InAppBrowser.isAvailable();
+ if (!(label in integrated_endpoints)) {
+ // TODO handle non-integrated social links with a modal
+ // TODO remove the alert below
+ Alert.alert('Coming soon!');
+ return;
+ }
+ let url = integrated_endpoints[label][0]
+
+ // We will need to do an extra step for twitter sign-in
+ if (label === 'Twitter') {
+ const user_token = await AsyncStorage.getItem('token');
+ const response = await fetch(url, {
+ method: 'GET',
+ headers: {
+ Authorization: `Token ${user_token}`
+ }
+ });
+ url = response.url
+ }
+
+ if (isAvailable) {
+ InAppBrowser.openAuth(url, 'taggid://callback', {
+ ephemeralWebSession: true,
+ })
+ .then(async (response) => {
+ console.log(response)
+ if (response.type === 'success' && response.url) {
+ const success = await registerSocialLink(response.url);
+ if (!success) {
+ throw new Error('Unable to register with backend');
+ }
+ setState({
+ ...state,
+ authenticated: true,
+ });
+ Alert.alert(`Successfully linked ${label} 🎉`);
+ } else {
+ throw new Error(`Unable to link with ${label} API`);
+ }
+ })
+ .catch((error) => {
+ console.log(error);
+ Alert.alert(
+ `Something went wrong, we can't link with ${label} 😔`,
+ );
+ });
+ } else {
+ // Okay... to open an external browser and have it link back to
+ // the app is a bit tricky, we will need to have navigation routes
+ // setup for this screen and have it hooked up.
+ // See https://github.com/proyecto26/react-native-inappbrowser#authentication-flow-using-deep-linking
+ // Though this isn't the end of the world, from the documentation,
+ // the in-app browser should be supported from iOS 11, which
+ // is about 98.5% of all iOS devices in the world.
+ // See https://support.apple.com/en-gb/HT209574
+ Alert.alert(
+ 'Sorry! Your device was unable to open a browser to let you sign-in! 😔',
+ );
+ }
+ } catch (error) {
+ console.log(error);
+ Alert.alert(`Something went wrong, we can't link with ${label} 😔`);
+ }
};
switch (label) {