├── App.js ├── assets ├── icon.png └── splash.png ├── babel.config.js ├── .expo-shared └── assets.json ├── .gitignore ├── src ├── Providers.js ├── Routes.js ├── AuthProvider.js ├── AppStack.js └── AuthStack.js ├── app.json └── package.json /App.js: -------------------------------------------------------------------------------- 1 | import { Providers } from './src/Providers'; 2 | 3 | export default Providers; 4 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drehimself/rn-airlock-example/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drehimself/rn-airlock-example/HEAD/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /.expo-shared/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true, 3 | "89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | web-report/ 12 | 13 | # macOS 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /src/Providers.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { AuthProvider } from './AuthProvider'; 3 | import Routes from './Routes'; 4 | 5 | export const Providers = ({}) => { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Blank Template", 4 | "slug": "rn-airlock-example", 5 | "privacy": "public", 6 | "sdkVersion": "36.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android", 10 | "web" 11 | ], 12 | "version": "1.0.0", 13 | "orientation": "portrait", 14 | "icon": "./assets/icon.png", 15 | "splash": { 16 | "image": "./assets/splash.png", 17 | "resizeMode": "contain", 18 | "backgroundColor": "#ffffff" 19 | }, 20 | "updates": { 21 | "fallbackToCacheTimeout": 0 22 | }, 23 | "assetBundlePatterns": [ 24 | "**/*" 25 | ], 26 | "ios": { 27 | "supportsTablet": true 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "@react-native-community/masked-view": "0.1.5", 12 | "@react-navigation/native": "^5.0.9", 13 | "@react-navigation/stack": "^5.1.1", 14 | "axios": "^0.19.2", 15 | "expo": "~36.0.0", 16 | "expo-secure-store": "~8.0.0", 17 | "react": "~16.9.0", 18 | "react-dom": "~16.9.0", 19 | "react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz", 20 | "react-native-gesture-handler": "~1.5.0", 21 | "react-native-reanimated": "~1.4.0", 22 | "react-native-safe-area-context": "0.6.0", 23 | "react-native-screens": "2.0.0-alpha.12", 24 | "react-native-web": "~0.11.7" 25 | }, 26 | "devDependencies": { 27 | "@babel/core": "^7.0.0", 28 | "babel-preset-expo": "~8.0.0" 29 | }, 30 | "private": true 31 | } 32 | -------------------------------------------------------------------------------- /src/Routes.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useContext } from "react"; 2 | import { StyleSheet, Text, View, Button, TextInput, ActivityIndicator, AsyncStorage } from 'react-native'; 3 | import { NavigationContainer } from '@react-navigation/native'; 4 | import { AuthContext } from './AuthProvider'; 5 | import { AuthStack } from './AuthStack'; 6 | import { AppStack } from './AppStack'; 7 | import * as SecureStore from 'expo-secure-store'; 8 | 9 | export default function Routes() { 10 | const { user, setUser, login, logout } = useContext(AuthContext) 11 | const [loading, setLoading] = useState(true); 12 | 13 | useEffect(() => { 14 | // check if the user is logged in or not 15 | SecureStore.getItemAsync('user') 16 | .then(userString => { 17 | if (userString) { 18 | // decode it 19 | // login(); 20 | userObject = JSON.parse(userString) 21 | setUser(userObject); 22 | } 23 | setLoading(false); 24 | }) 25 | .catch(err => { 26 | console.log(err); 27 | }) 28 | }, []); 29 | 30 | if (loading) { 31 | return ( 32 | 33 | 34 | 35 | ) 36 | } 37 | 38 | return ( 39 | 40 | {user ? : } 41 | 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /src/AuthProvider.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { AsyncStorage } from 'react-native'; 3 | import * as SecureStore from 'expo-secure-store'; 4 | import axios from 'axios'; 5 | 6 | axios.defaults.baseURL = 'http://airlock-example.test'; 7 | 8 | export const AuthContext = React.createContext({}); 9 | 10 | export const AuthProvider = ({children}) => { 11 | const [user, setUser] = useState(null); 12 | const [error, setError] = useState(null); 13 | 14 | return ( 15 | { 21 | axios.post('/api/airlock/token', { 22 | email, 23 | password, 24 | device_name: 'mobile', 25 | }) 26 | .then(response => { 27 | const userResponse = { 28 | email: response.data.user.email, 29 | token: response.data.token, 30 | } 31 | setUser(userResponse); 32 | setError(null); 33 | SecureStore.setItemAsync('user', JSON.stringify(userResponse)); 34 | }) 35 | .catch(error => { 36 | const key = Object.keys(error.response.data.errors)[0]; 37 | setError(error.response.data.errors[key][0]); 38 | }) 39 | }, 40 | logout: () => { 41 | axios.defaults.headers.common['Authorization'] = `Bearer ${user.token}`; 42 | 43 | axios.post('/api/logout') 44 | .then(response => { 45 | setUser(null); 46 | SecureStore.deleteItemAsync('user') 47 | }) 48 | .catch(error => { 49 | console.log(error.response); 50 | }) 51 | } 52 | }}> 53 | {children} 54 | 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /src/AppStack.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { useContext, useState, useEffect } from "react"; 3 | import { createStackNavigator } from "@react-navigation/stack"; 4 | import { AuthContext } from "./AuthProvider"; 5 | import { Button, Text, View } from "react-native"; 6 | import axios from 'axios'; 7 | 8 | axios.defaults.baseURL = 'http://airlock-example.test'; 9 | 10 | const Stack = createStackNavigator(); 11 | 12 | function DashboardScreen({ navigation }) { 13 | const { user, logout } = useContext(AuthContext) 14 | const [name, setName] = useState(null); 15 | 16 | useEffect(() => { 17 | axios.defaults.headers.common['Authorization'] = `Bearer ${user.token}`; 18 | 19 | axios.get('/api/user') 20 | .then(response => { 21 | setName(response.data.name); 22 | }) 23 | .catch(error => { 24 | console.log(error.response); 25 | }) 26 | 27 | }, []); 28 | 29 | return ( 30 | 31 | Dashboard Screen Logged In View 32 | User: {user.email} 33 | User from Server: {name} 34 |