Intro.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import React, { useEffect } from 'react';
  2. import { ImageBackground, StyleSheet, View, TouchableOpacity, Image } from 'react-native';
  3. import { ActivityIndicator, Text, } from 'react-native-paper'
  4. import 'react-native-get-random-values';
  5. import * as AuthSession from 'expo-auth-session';
  6. import * as WebBrowser from 'expo-web-browser';
  7. import { useAuthState } from '../contexts/AuthContext';
  8. import * as SecureStore from 'expo-secure-store';
  9. import axios from 'axios';
  10. import jwt_decode from 'jwt-decode';
  11. import { API_URL, OAUTH_CLIENT_ID } from '../globals';
  12. WebBrowser.maybeCompleteAuthSession();
  13. const issuer = API_URL + "/o";
  14. const discovery = {
  15. authorizationEndpoint: issuer + "/authorize",
  16. tokenEndpoint: issuer + "/token",
  17. revocationEndpoint: issuer + "/revoke",
  18. };
  19. const Intro = ({navigation}) => {
  20. const {authDispatch, authState} = useAuthState();
  21. const redirectUri = AuthSession.makeRedirectUri({
  22. scheme: OAUTH_CLIENT_ID,
  23. path: 'callback'
  24. });
  25. const goToRegistration = () => {
  26. navigation.navigate("Registration");
  27. }
  28. const login = async () => {
  29. const request = await AuthSession.loadAsync({
  30. clientId: OAUTH_CLIENT_ID,
  31. responseType: AuthSession.ResponseType.Code,
  32. usePKCE: true,
  33. redirectUri,
  34. scopes: ['openid'],
  35. },
  36. discovery)
  37. const result = await request.promptAsync();
  38. authDispatch({type: 'INITIATE_LOGIN'});
  39. if (result.type == "success") {
  40. const tokenParams = new URLSearchParams();
  41. tokenParams.append('grant_type', 'authorization_code');
  42. tokenParams.append('client_id', 'atlas.clicknpush');
  43. tokenParams.append('code', result.params.code);
  44. tokenParams.append('redirect_uri', redirectUri);
  45. tokenParams.append('code_verifier', request.codeVerifier);
  46. try {
  47. const response = await axios.post(`http://10.0.0.151:8000/o/token/`, tokenParams, {
  48. headers: {
  49. 'Content-Type': 'application/x-www-form-urlencoded'
  50. }
  51. });
  52. const tokenResponse = response.data;
  53. const idToken = jwt_decode(tokenResponse.id_token);
  54. const accessToken = tokenResponse.access_token;
  55. const refreshToken = tokenResponse.refresh_token;
  56. await SecureStore.setItemAsync('accessToken', accessToken);
  57. authDispatch({type: "SET_ACCESS_TOKEN", payload: accessToken});
  58. authDispatch({type: "SET_ID_TOKEN", payload: idToken});
  59. authDispatch({type: "SET_REFRESH_TOKEN", payload: refreshToken});
  60. }
  61. catch (error) {
  62. console.log(error.response.data);
  63. }
  64. }
  65. else {
  66. authDispatch({type: 'CANCEL_LOGIN'});
  67. console.log(result);
  68. }
  69. }
  70. return(
  71. <ImageBackground style={styles.container} source={require('../assets/cover.jpg')}>
  72. {!authState.isLoading ?
  73. <>
  74. <View style={[styles.brandContainer, styles.center]}>
  75. <Image style={styles.logo} source={require('../assets/logo-white.png')}></Image>
  76. <Text style={[styles.center, styles.title]} >Click & Push</Text>
  77. </View>
  78. <View style={styles.btnContainer}>
  79. <TouchableOpacity style={styles.loginBtn} onPress={login} >
  80. <Text style={{ color: 'white', fontSize: 15 }}>Login</Text>
  81. </TouchableOpacity>
  82. <TouchableOpacity style={styles.registerBtn} onPress={goToRegistration} >
  83. <Text style={{ color: 'white', fontSize: 15 }}>Create Account</Text>
  84. </TouchableOpacity>
  85. </View>
  86. </> :
  87. <View style={{alignContent: 'center', height: '100%', margin: 50}}>
  88. <Text style={{marginTop: 50, marginBottom: 100, color: 'white', fontSize: 20}}>Hang on a moment while we sign you in.</Text>
  89. <ActivityIndicator size={50} animating={true} color="white" />
  90. </View> }
  91. </ImageBackground>
  92. )
  93. }
  94. const styles = StyleSheet.create({
  95. container: {
  96. flex: 1,
  97. flexDirection: 'column',
  98. resizeMode: 'cover',
  99. justifyContent: 'space-between'
  100. },
  101. center: {
  102. alignItems: 'center',
  103. justifyContent: 'center',
  104. },
  105. brandContainer: {
  106. flex: 2,
  107. marginVertical: 50,
  108. flexDirection: 'column',
  109. justifyContent: 'space-between'
  110. },
  111. title: {
  112. fontFamily: 'RacingSansOne-Regular',
  113. marginTop: 30,
  114. color: 'white',
  115. fontSize: 30
  116. },
  117. textContainer: {
  118. marginHorizontal: 20,
  119. borderRadius: 50,
  120. },
  121. textInput: {
  122. marginBottom: 10,
  123. paddingLeft: 30,
  124. borderRadius: 50,
  125. overflow: 'hidden',
  126. backgroundColor: 'white',
  127. height: 50
  128. },
  129. loginBtn: {
  130. borderRadius: 50,
  131. width: '75%',
  132. justifyContent: 'center',
  133. backgroundColor: '#df3f3f',
  134. height: 60,
  135. marginBottom: 20,
  136. alignItems: 'center'
  137. },
  138. registerBtn: {
  139. width: '75%',
  140. borderColor: 'white',
  141. borderWidth: 2,
  142. borderRadius: 50,
  143. justifyContent: 'center',
  144. backgroundColor: 'transparent',
  145. height: 60,
  146. alignItems: 'center'
  147. },
  148. btnContainer: {
  149. flex: 1,
  150. alignItems: 'center',
  151. },
  152. })
  153. export default Intro;