diff --git a/api/qrCodeAPI.tsx b/api/qrCodeAPI.tsx new file mode 100644 index 0000000..45a50bb --- /dev/null +++ b/api/qrCodeAPI.tsx @@ -0,0 +1,31 @@ +import axios from 'axios'; + +const API_BASE_URL = 'http://192.168.10.247:8080/v1/api/qrcodetypes'; + +export const detectQRCodeType = async (data: string) => { + console.log('API Call - Detect QR Code Type:', data); + const response = await axios.post(`${API_BASE_URL}/detect`, { data }); + console.log('API Response - QR Code Type:', response.data); + return response.data; +}; + +export const verifyURL = async (data: string) => { + console.log('API Call - Verify URL:', data); + const response = await axios.post(`${API_BASE_URL}/verifyURL`, { data }); + console.log('API Response - Verify URL:', response.data); + return response.data; +}; + +export const virusTotalCheck = async (data: string) => { + console.log('API Call - Virus Total Check:', data); + const response = await axios.post(`${API_BASE_URL}/virusTotalCheck`, { data }); + console.log('API Response - Virus Total Check:', response.data); + return response.data; +}; + +export const checkRedirects = async (data: string) => { + console.log('API Call - Check Redirects:', data); + const response = await axios.post(`${API_BASE_URL}/checkRedirects`, { data }); + console.log('API Response - Check Redirects:', response.data); + return response.data; +}; diff --git a/components/ScannedDataBox.tsx b/components/ScannedDataBox.tsx index 1889d6b..afcd238 100644 --- a/components/ScannedDataBox.tsx +++ b/components/ScannedDataBox.tsx @@ -1,47 +1,34 @@ import React, { useEffect, useState } from 'react'; -import { View, Text, StyleSheet, Image, TouchableOpacity, Modal, Share } from 'react-native'; +import { View, Text, StyleSheet, Image, TouchableOpacity, Modal } from 'react-native'; import QRCode from 'react-native-qrcode-svg'; import { Ionicons } from '@expo/vector-icons'; -import SecureWebView from './SecureWebView'; // Import the SecureWebView component +import * as Sharing from 'expo-sharing'; +import { WebView } from 'react-native-webview'; // Define Props for ScannedDataBox component interface ScannedDataBoxProps { data: string; dataType: string; clearScanData: () => void; + scanResult: { + secureConnection: boolean; + virusTotalCheck: boolean; + redirects: number; + }; } -// Define ScanResult interface -interface ScanResult { - secureConnection: boolean; - virusTotalCheck: boolean; - redirects: number; -} - -const ScannedDataBox: React.FC = ({ data, dataType, clearScanData }) => { - const [scanResult, setScanResult] = useState(null); +const ScannedDataBox: React.FC = ({ data, dataType, clearScanData, scanResult }) => { const [isModalVisible, setIsModalVisible] = useState(false); - const [isWebViewVisible, setIsWebViewVisible] = useState(false); // State to control WebView modal visibility - + const [isWebViewVisible, setIsWebViewVisible] = useState(false); console.log("ScannedDataBox -> Data", data); console.log("DataType", dataType); - // Set scan result based on data useEffect(() => { - // Assuming scanResult is directly related to data - setScanResult({ - secureConnection: data.includes('https'), // Example logic - virusTotalCheck: !data.includes('danger'), // Example logic - redirects: data.includes('redirect') ? 1 : 0, // Example logic - }); console.log("Scan result set:", scanResult); }, [data]); // Determine the result text based on scan result const getResultText = () => { - if (!scanResult) { - return 'UNKNOWN'; - } if (!scanResult.secureConnection && !scanResult.virusTotalCheck) { return 'DANGEROUS'; } else if (scanResult.redirects > 0) { @@ -65,22 +52,16 @@ const ScannedDataBox: React.FC = ({ data, dataType, clearSc } }; - // Handle sharing the data - const handleShare = async () => { + const shareQRCodeData = async () => { try { - await Share.share({ - message: data, - }); - console.log('Data shared:', data); + await Sharing.shareAsync(data); } catch (error) { - console.error('Error sharing the data:', error); + console.error('Error sharing QR code data:', error); } }; - // Handle opening the data in a sandboxed WebView - const handleOpen = () => { + const openWebView = () => { setIsWebViewVisible(true); - console.log('Opening data in WebView:', data); }; return ( @@ -111,17 +92,17 @@ const ScannedDataBox: React.FC = ({ data, dataType, clearSc {/* Display scan checks */} Checks - Secure Connection: {scanResult?.secureConnection ? '✔️' : '✘'} - Virus Total Check: {scanResult?.virusTotalCheck ? '✔️' : '✘'} - Redirects: {scanResult ? scanResult.redirects : 'N/A'} + Secure Connection: {scanResult.secureConnection ? '✔️' : '✘'} + Virus Total Check: {scanResult.virusTotalCheck ? '✔️' : '✘'} + Redirects: {scanResult.redirects} {/* Action buttons */} - + Share - + Open @@ -160,19 +141,26 @@ const ScannedDataBox: React.FC = ({ data, dataType, clearSc - - {/* Modal for SecureWebView */} setIsWebViewVisible(false)} > - - setIsWebViewVisible(false)}> - - - + + + true} + /> + setIsWebViewVisible(false)}> + Close + + @@ -316,18 +304,11 @@ const styles = StyleSheet.create({ color: '#fff', }, webViewContainer: { - flex: 1, - backgroundColor: 'rgba(0, 0, 0, 0.5)', - }, - webView: { - flex: 1, - marginTop: 40, - }, - closeWebViewButton: { - position: 'absolute', - top: 10, - right: 10, - zIndex: 1, + width: '100%', + height: '80%', + backgroundColor: 'white', + borderRadius: 7.5, + overflow: 'hidden' }, }); diff --git a/package-lock.json b/package-lock.json index 3650bac..88be649 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "expo-camera": "~15.0.10", "expo-image-manipulator": "^12.0.5", "expo-image-picker": "~15.0.5", + "expo-sharing": "~12.0.1", "expo-status-bar": "~1.12.1", "react": "18.2.0", "react-native": "0.74.2", @@ -7882,6 +7883,14 @@ "invariant": "^2.2.4" } }, + "node_modules/expo-sharing": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/expo-sharing/-/expo-sharing-12.0.1.tgz", + "integrity": "sha512-wBT+WeXwapj/9NWuLJO01vi9bdlchYu/Q/xD8slL/Ls4vVYku8CPqzkTtDFcjLrjtlJqyeHsdQXwKLvORmBIew==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-status-bar": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.12.1.tgz", diff --git a/package.json b/package.json index 5c27346..7915f16 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "react-native-safe-area-context": "^4.10.4", "react-native-webview": "^13.10.4", "react-redux": "^9.1.2", - "redux": "^5.0.1" + "redux": "^5.0.1", + "expo-sharing": "~12.0.1" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/screens/QRScannerScreen.tsx b/screens/QRScannerScreen.tsx index 7e2d5d4..f4d795b 100644 --- a/screens/QRScannerScreen.tsx +++ b/screens/QRScannerScreen.tsx @@ -1,23 +1,24 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, Image } from 'react-native'; import { Camera, CameraView, scanFromURLAsync } from 'expo-camera'; -import { useDispatch } from 'react-redux'; +import { QRCodeContext } from '../types'; import axios from 'axios'; // For URL calls import { Ionicons } from '@expo/vector-icons'; // For icons import { useNavigation } from '@react-navigation/native'; import * as ImagePicker from 'expo-image-picker'; import ScannedDataBox from '../components/ScannedDataBox'; -import { addQRCode } from '../actions/qrCodeActions'; - -interface QRScannerScreenProps { - clearScanData: () => void; -} +import { useDispatch } from 'react-redux'; +import { addQRCode } from '../actions/qrCodeActions'; // Assuming you have actions defined for Redux +import { detectQRCodeType, verifyURL, checkRedirects } from '../api/qrCodeAPI'; // Import utility functions // Main Function -const QRScannerScreen: React.FC = ({ clearScanData }) => { +const QRScannerScreen: React.FC<{ clearScanData: () => void }> = ({ clearScanData }) => { const navigation = useNavigation(); // call Navigation bar + const dispatch = useDispatch(); // Use dispatch for Redux actions + const [showSplash, setShowSplash] = useState(true); // call splash screen - const dispatch = useDispatch(); + const qrCodeContext = useContext(QRCodeContext); // From ./types.ts + const { qrCodes, setQrCodes } = qrCodeContext || { qrCodes: [], setQrCodes: () => {} }; const [hasPermission, setHasPermission] = useState(null); const [scanned, setScanned] = useState(false); @@ -25,6 +26,11 @@ const QRScannerScreen: React.FC = ({ clearScanData }) => { const [dataType, setDataType] = useState(''); // State for data type const [enableTorch, setEnableTorch] = useState(false); // State for torch + // Add state variables for scan results + const [secureConnection, setSecureConnection] = useState(null); + const [virusTotalCheck, setVirusTotalCheck] = useState(null); + const [redirects, setRedirects] = useState(null); + // Request Camera Permission and initialize the app useEffect(() => { const initializeApp = async () => { @@ -49,17 +55,24 @@ const QRScannerScreen: React.FC = ({ clearScanData }) => { const handlePayload = async (payload: string) => { setScanned(true); console.log("Scanning Completed. Payload is:", payload); - const type = await sendToAPIServer(payload); + + const type = await detectQRCodeType(payload); + const secureConnectionResult = await verifyURL(payload); + const redirectResult = await checkRedirects(payload); + + setSecureConnection(secureConnectionResult.isSecure); + setVirusTotalCheck(!secureConnectionResult.isMalicious); // Assuming you have virusTotalCheck logic integrated here + setRedirects(redirectResult.redirects); const qrCode = { data: payload, type, scanResult: { - secureConnection: true, // Placeholder, replace with actual logic - virusTotalCheck: true, // Placeholder, replace with actual logic - redirects: 0 // Placeholder, replace with actual logic + secureConnection: secureConnectionResult.isSecure, + virusTotalCheck: !secureConnectionResult.isMalicious, + redirects: redirectResult.redirects }, - bookmarked: false, // Add the bookmarked property + bookmarked: false // by default }; setScannedData(payload); @@ -185,7 +198,16 @@ const QRScannerScreen: React.FC = ({ clearScanData }) => { {scannedData !== '' && ( - + )}