import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:provider/provider.dart'; import 'package:sign_in_with_apple/sign_in_with_apple.dart'; import 'package:teso/Classes/API%20Clasess/FacebookUser.dart'; import 'package:teso/Classes/API%20Clasess/GoogleUser.dart'; import 'package:teso/Classes/API%20Clasess/TokenHandler.dart'; import 'package:teso/Classes/API%20Clasess/UserAuth.dart'; import 'package:camera/camera.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:teso/Classes/customLoginButton.dart'; import 'package:teso/Classes/customTesoButton.dart'; import 'package:teso/Pages/PageWidgets/Login/forgotPassword.dart'; import 'package:teso/Pages/PageWidgets/Login/password.dart'; import 'package:teso/Pages/PageWidgets/Login/username.dart'; import 'package:teso/Pages/Sub_Pages/LandingPage/SignUp.dart'; import 'package:teso/main_screen.dart'; import 'package:teso/providers/referral_provider.dart'; import 'package:teso/providers/user_provider.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:flutter/cupertino.dart'; import 'package:teso/util/consts.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:firebase_messaging/firebase_messaging.dart'; import 'facebookRedirect.dart'; class LoginPage extends StatefulWidget { final List connectedCameras; final String referrer; const LoginPage({Key key, this.connectedCameras, this.referrer}) : super(key: key); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State { TextEditingController usern = new TextEditingController(); TextEditingController password = new TextEditingController(); UserProvider user = UserProvider(); User _user; bool loading = false; bool gloading = false; bool ios = false; bool error = false; String errorMessage = "An error occurred while verifying account try again!!"; String deviceToken; FirebaseAuth _auth; GoogleSignIn _googleSignIn; FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; Locale myLocale; void signIn() async { if (deviceToken == null) firebaseCloudMessaging_Listeners(); SharedPreferences prefs = await SharedPreferences.getInstance(); setState(() { loading = true; }); Map requestHeaders = { 'Content-type': 'application/json', }; UserAuth auth = new UserAuth(); auth.username = usern.text; auth.password = password.text; auth.deviceToken = deviceToken; var register2 = serverLocation + 'api/tokens'; var client1 = await http.post(Uri.parse(register2), body: json.encode(auth), headers: requestHeaders); if (client1.statusCode == 200) { Map handler = jsonDecode(client1.body); TokenHandler tokenHandler = TokenHandler.fromJSON(handler); _auth = FirebaseAuth.instance; await _auth.signInWithCustomToken(tokenHandler.tokenFirebase); prefs.setString("tokensTeso", "Bearer " + tokenHandler.tokenTeso); prefs.setString("tokensFirebase", tokenHandler.tokenFirebase); prefs.setString("accountType", "email"); prefs.setString("id", _auth.currentUser.uid); prefs.setString("currentUser", tokenHandler.user.toString()); prefs.setBool("password", true); user.setUser(tokenHandler.user); final QuerySnapshot result = await FirebaseFirestore.instance .collection('users') .where('id', isEqualTo: _auth.currentUser.uid) .get(); final List documents = result.docs; if (documents.length == 0) { // Update data to server if new user FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .set({ 'firstname': tokenHandler.user.firstname, 'surname': tokenHandler.user.lastname, 'id': _auth.currentUser.uid }); } FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .update({'deviceToken': deviceToken}); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => MainScreens( // connectedCameras: widget.connectedCameras )), (Route route) => false); } else { setState(() { loading = false; error = true; }); } setState(() { loading = false; }); } void signup(context) { Provider.of(context, listen: false) .setReferral(widget.referrer); showModalBottomSheet( context: context, isScrollControlled: true, enableDrag: true, shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(30.0)), ), builder: (BuildContext bc) { return SignUpPage(); }); } signInWithGoogle() async { try { setState(() { gloading = true; error = false; }); if (deviceToken == null) firebaseCloudMessaging_Listeners(); _auth = FirebaseAuth.instance; _googleSignIn = GoogleSignIn(); GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn(); GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication; AuthCredential credential = GoogleAuthProvider.credential( accessToken: googleSignInAuthentication.accessToken, idToken: googleSignInAuthentication.idToken, ); var authResult = await _auth.signInWithCredential(credential); _user = authResult.user; assert(!_user.isAnonymous); assert(await _user.getIdToken() != null); User currentUser = _auth.currentUser; assert(_user.uid == currentUser.uid); var names = googleSignInAccount.displayName.split(' '); GoogleUser googleUser = new GoogleUser(); googleUser.userGUID = currentUser.uid; googleUser.firstname = names[0]; googleUser.surname = names[1]; googleUser.email = _user.email; googleUser.pictureUri = _user.photoURL; googleUser.deviceToken = deviceToken; if (widget.referrer != null) googleUser.referralCode = widget.referrer; final QuerySnapshot result = await FirebaseFirestore.instance .collection('users') .where('id', isEqualTo: _auth.currentUser.uid) .orderBy('surname', descending: true) .get(); final List documents = result.docs; if (documents.length == 0) { // Update data to server if new user FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .set({ 'firstname': googleUser.firstname, 'surname': googleUser.surname, 'id': _auth.currentUser.uid }); } FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .update({'deviceToken': deviceToken}); googleSignInAccount = await _googleSignIn.signOut(); SharedPreferences prefs = await SharedPreferences.getInstance(); Map requestHeaders = { 'Content-type': 'application/json', }; var register2 = serverLocation + 'api/googleauth'; var client1 = await http.post(Uri.parse(register2), body: json.encode(googleUser), headers: requestHeaders); if (client1.statusCode == 200) { Map handler = jsonDecode(client1.body); TokenHandler tokenHandler = TokenHandler.fromJSON(handler); prefs.setString("tokensTeso", "Bearer " + tokenHandler.tokenTeso); prefs.setString("id", _auth.currentUser.uid); _user .getIdToken() .then((value) => prefs.setString("tokensFirebase", value)); prefs.setString("currentUser", tokenHandler.user.toString()); prefs.setBool("password", false); user.setUser(tokenHandler.user); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => MainScreens( // connectedCameras: widget.connectedCameras )), (Route route) => false); } else { setState(() { gloading = false; error = true; }); } setState(() { gloading = false; }); } catch (e) { setState(() { gloading = false; error = true; }); } } String generateNonce([int length = 32]) { final charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._'; final random = Random.secure(); return List.generate(length, (_) => charset[random.nextInt(charset.length)]) .join(); } /// Returns the sha256 hash of [input] in hex notation. String sha256ofString(String input) { final bytes = utf8.encode(input); final digest = sha256.convert(bytes); return digest.toString(); } signInWithApple() async { try { setState(() { gloading = true; error = false; }); final scopes = [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ]; final rawNonce = generateNonce(); final nonce = sha256ofString(rawNonce); final appleCredential = await SignInWithApple.getAppleIDCredential( scopes: scopes, nonce: nonce, webAuthenticationOptions: WebAuthenticationOptions( clientId: "com.tesoapp.teso", redirectUri: Uri.parse( "https://tesoappleauth.glitch.me/callbacks/sign_in_with_apple")), ); final oauthCredential = OAuthProvider("apple.com").credential( idToken: appleCredential.identityToken, accessToken: appleCredential.authorizationCode, rawNonce: rawNonce, ); _auth = FirebaseAuth.instance; final authResult = await _auth.signInWithCredential(oauthCredential); _user = authResult.user; assert(!_user.isAnonymous); assert(await _user.getIdToken() != null); User currentUser = _auth.currentUser; assert(_user.uid == currentUser.uid); GoogleUser googleUser = new GoogleUser(); googleUser.userGUID = currentUser.uid; googleUser.firstname = appleCredential.givenName != null ? appleCredential.givenName : ""; googleUser.surname = appleCredential.familyName != null ? appleCredential.familyName : ""; googleUser.email = _user.email; googleUser.deviceToken = deviceToken; if (widget.referrer != null) googleUser.referralCode = widget.referrer; final QuerySnapshot result = await FirebaseFirestore.instance .collection('users') .where('id', isEqualTo: _auth.currentUser.uid) .get(); final List documents = result.docs; if (documents.length == 0) { // Update data to server if new user FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .set({ 'firstname': googleUser.firstname, 'surname': googleUser.surname, 'id': _auth.currentUser.uid }); } FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .update({'deviceToken': deviceToken}); SharedPreferences prefs = await SharedPreferences.getInstance(); Map requestHeaders = { 'Content-type': 'application/json', }; var register2 = serverLocation + 'api/apple'; var client1 = await http.post(Uri.parse(register2), body: json.encode(googleUser), headers: requestHeaders); if (client1.statusCode == 200) { Map handler = jsonDecode(client1.body); TokenHandler tokenHandler = TokenHandler.fromJSON(handler); prefs.setString("tokensTeso", "Bearer " + tokenHandler.tokenTeso); prefs.setString("id", _auth.currentUser.uid); _user .getIdToken() .then((value) => prefs.setString("tokensFirebase", value)); prefs.setString("currentUser", tokenHandler.user.toString()); prefs.setBool("password", false); user.setUser(tokenHandler.user); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => MainScreens( // connectedCameras: widget.connectedCameras )), (Route route) => false); } else { setState(() { gloading = false; error = true; }); } // } else { // // errorMessage = "Unable to " // } setState(() { gloading = false; }); } catch (e) { print(e); setState(() { gloading = false; error = true; }); } } loginWithFacebook() async { setState(() { gloading = true; error = false; }); String results = await Navigator.push( context, MaterialPageRoute( builder: (context) => CustomWebView( selectedUrl: 'https://www.facebook.com/dialog/oauth?client_id=$your_client_id&redirect_uri=$your_redirect_url&response_type=token&scope=email,public_profile,', ), maintainState: true), ); if (results != null) { try { _auth = FirebaseAuth.instance; final facebookAuthCred = FacebookAuthProvider.credential(results); UserCredential user = await _auth.signInWithCredential(facebookAuthCred); FacebookUser facebookUser = new FacebookUser(); facebookUser.userGUID = _auth.currentUser.uid; facebookUser.firstname = user.user.displayName; facebookUser.surname = ""; facebookUser.email = user.user.email; facebookUser.pictureUri = user.user.photoURL; facebookUser.deviceToken = deviceToken; facebookUser.username = user.user.displayName.replaceAll(' ', ''); if (widget.referrer != null) facebookUser.referralCode = widget.referrer; _user = user.user; assert(!_user.isAnonymous); assert(await _user.getIdToken() != null); User currentUser = _auth.currentUser; assert(_user.uid == currentUser.uid); final QuerySnapshot result = await FirebaseFirestore.instance .collection('users') .where('id', isEqualTo: _auth.currentUser.uid) .get(); final List documents = result.docs; if (documents.length == 0) { // Update data to server if new user FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .set({ 'firstname': facebookUser.firstname, 'surname': facebookUser.surname, 'id': _auth.currentUser.uid }); } FirebaseFirestore.instance .collection('users') .doc(_auth.currentUser.uid) .update({'deviceToken': deviceToken}); SharedPreferences prefs = await SharedPreferences.getInstance(); Map requestHeaders = { 'Content-type': 'application/json', }; var register2 = serverLocation + 'api/facebookauth'; var client1 = await http.post(Uri.parse(register2), body: json.encode(facebookUser), headers: requestHeaders); if (client1.statusCode == 200) { Map handler = jsonDecode(client1.body); TokenHandler tokenHandler = TokenHandler.fromJSON(handler); _user .getIdToken() .then((value) => prefs.setString("tokensFirebase", value)); prefs.setString("id", _auth.currentUser.uid); prefs.setString("currentUser", tokenHandler.user.toString()); prefs.setString("tokensTeso", "Bearer " + tokenHandler.tokenTeso); prefs.setBool("password", false); this.user.setUser(tokenHandler.user); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => MainScreens(connectedCameras: widget.connectedCameras)), (Route route) => false); } else { setState(() { gloading = false; error = true; }); } setState(() { gloading = false; }); } catch (e) { print(e); setState(() { gloading = false; error = true; }); } } else { gloading = false; } } @override void dispose() { super.dispose(); } @override void initState() { ios = Platform.isIOS; SharedPreferences.getInstance().then((value) { String current = value.getString("api-version"); value.clear(); if (current != null) value.setString("api-version", current); }); super.initState(); firebaseCloudMessaging_Listeners(); } // ignore: non_constant_identifier_names void firebaseCloudMessaging_Listeners() async { try { if (Platform.isIOS) iOS_Permission(); await _firebaseMessaging.getToken().then((token) { deviceToken = token; }); } catch (e) { print(e); } } // ignore: non_constant_identifier_names void iOS_Permission() { _firebaseMessaging.requestPermission( sound: true, badge: true, alert: true, provisional: false); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: AnnotatedRegion( value: SystemUiOverlayStyle.light, child: GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Stack( children: [ Container( height: double.infinity, child: SingleChildScrollView( // physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.symmetric(horizontal: 40.00, vertical: 50), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: MediaQuery.of(context).size.height * 0.10, width: double.infinity, child: Align( alignment: Alignment.topCenter, child: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage( "assets/images/tesoCouponInsignia.png")), ), ), ), ), Container( width: double.infinity, child: Center( child: Text( "Sign In", style: TextStyle( color: Colors.black87, fontFamily: 'OpenSans', fontWeight: FontWeight.bold, fontSize: 22.0, //fontWeight: FontWeight.bold, ), ), ), ), SizedBox(height: 20.0), username(context, "Username", usern), SizedBox(height: 5.0), passwordBuilder( context, "Enter your password here", password), buildForgotPasswordBtn(context), Visibility( visible: loading, child: Center( child: CupertinoActivityIndicator( animating: true, radius: 15, ), ), ), Visibility( visible: error, child: Container( margin: EdgeInsets.only(top: 20), width: MediaQuery.of(context).size.width * 0.9, child: Center( child: Text( errorMessage, textAlign: TextAlign.center, style: TextStyle( color: Colors.red, ), ), ), ), ), SizedBox( height: MediaQuery.of(context).size.height * 0.001), RaisedGradientButton( onPressed: signIn, child: Text( "Sign In", style: TextStyle( fontSize: 18, color: Colors.white, ), ), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ accentMain, darkAccent, ], // stops: [0.1, 0.4, 0.7, 0.8], ), ), SizedBox(height: 20.0), Container( width: double.infinity, child: Center( child: Text( "or", style: TextStyle( fontSize: 15, color: Colors.black87, ), ), ), ), SizedBox(height: 20.0), // !ios // ? buildThirdAuth(context) buildIOSThirdAuth(context), SizedBox( height: MediaQuery.of(context).size.height * 0.05), InkWell( onTap: () => signup(context), child: new Wrap( direction: Axis.horizontal, spacing: 5, children: [ Text( "Don't have an account ?", style: TextStyle( fontSize: 14.5, color: Colors.black87, ), ), Text("Sign Up", style: TextStyle( fontSize: 16, color: Colors.blue, )), ], ), ) ], ), ), ), Visibility( visible: gloading, child: Container( color: Theme.of(context).backgroundColor, height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: Center( child: CupertinoActivityIndicator( animating: true, radius: 15, ), ), ), ), ], ), ), ), ); } buildThirdAuth(BuildContext context) { return Wrap( direction: Axis.horizontal, children: [ MaterialButton( onPressed: signInWithGoogle, color: Colors.white, padding: EdgeInsets.all(10), shape: CircleBorder(), child: Image( image: AssetImage("assets/images/google.png"), height: MediaQuery.of(context).size.height * 0.045, ), ), MaterialButton( onPressed: loginWithFacebook, color: Colors.white, padding: EdgeInsets.all(10), shape: CircleBorder(), child: Image( image: AssetImage("assets/images/facebook.png"), height: MediaQuery.of(context).size.height * 0.045, ), ), ], ); } buildIOSThirdAuth(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SignInWithAppleButton( style: SignInWithAppleButtonStyle.black, borderRadius: BorderRadius.only( topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0), bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), ), iconAlignment: IconAlignment.left, onPressed: signInWithApple, ), SizedBox( height: 10, ), CustomLoginButton( child: Text( "Sign in with Google ", style: TextStyle( fontSize: 44 * 0.43, color: Colors.black, ), ), color: Colors.white, icon: "assets/images/google.png", onPressed: signInWithGoogle, ), SizedBox( height: 10, ), CustomLoginButton( child: Text( "Sign in with Facebook", style: TextStyle( fontSize: 44 * 0.43, color: Colors.white, ), ), color: Color(0XFF4267B2), icon: "assets/images/facebook_new.png", onPressed: signInWithGoogle, ), ], ); } }