diff --git a/App.tsx b/App.tsx index 05a66d0..c9dd8ec 100644 --- a/App.tsx +++ b/App.tsx @@ -4,37 +4,97 @@ import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { CameraView, Camera } from 'expo-camera'; import { Ionicons } from '@expo/vector-icons'; +import axios from 'axios'; // Import Axios for HTTP requests // Create a Context for QR code data const QRCodeContext = createContext(); const Tab = createBottomTabNavigator(); +// Component for QR Scanner Screen function QRScannerScreen() { const { qrCodes, setQrCodes } = useContext(QRCodeContext); // Access context - const [hasPermission, setHasPermission] = useState(null); - const [scanned, setScanned] = useState(false); - const [showSplash, setShowSplash] = useState(true); - const [scannedData, setScannedData] = useState(''); + const [hasPermission, setHasPermission] = useState(null); // State for camera permission + const [scanned, setScanned] = useState(false); // State for scanned status + const [showSplash, setShowSplash] = useState(true); // State for splash screen + const [scannedData, setScannedData] = useState(''); // State for scanned data + const [scanResult, setScanResult] = useState(null); // State for VirusTotal scan result useEffect(() => { const initializeApp = async () => { - const { status } = await Camera.requestCameraPermissionsAsync(); - setHasPermission(status === 'granted'); - setShowSplash(false); // Hide splash screen after initializing + const { status } = await Camera.requestCameraPermissionsAsync(); // Request camera permissions + setHasPermission(status === 'granted'); // Set permission status + setShowSplash(false); // Hide splash screen }; - initializeApp(); + initializeApp(); // Initialize app }, []); - const handleBarCodeScanned = ({ type, data }) => { - setScanned(true); // Mark as scanned - const newScannedData = `Type: ${type}\nData: ${data}`; - setScannedData(newScannedData); // Save scanned data - setQrCodes([...qrCodes, newScannedData]); // Add scanned data to history - alert(`Bar code with type ${type} and data ${data} has been scanned!`); // Show an alert +// Function to handle barcode scanned event +const handleBarCodeScanned = async ({ type, data }) => { + setScanned(true); // Mark as scanned + + // Determine the type of data (URL, text, or just numbers) + let dataType; + if (/^(http|https):\/\//.test(data)) { + dataType = 'URL'; + } else if (/^[0-9]+$/.test(data)) { + dataType = 'Numbers'; + } else { + dataType = 'Text'; + } + + // Construct the scanned data with the data type + let newScannedData = `Type: ${dataType}\nData: ${data}`; // Initialize with type and data + + try { + const scanId = await scanWithVirusTotal(data); // Send data to VirusTotal and get scan ID + const positive = await getScanResult(scanId); // Get scan result and extract positive score + newScannedData += `\nScore: ${positive}`; // Append positive score to newScannedData + } catch (error) { + console.error('Error handling barcode scan:', error); // Handle error + } + + setScannedData(newScannedData); // Save scanned data + setQrCodes([...qrCodes, newScannedData]); // Add scanned data to history +}; + +// Function to send data to VirusTotal and get the scan ID +const scanWithVirusTotal = async (data) => { + const apiKey = '3566a17933bb36dd97cb35e84d0446e5ab8ad623e6de968d34b655c79485251e'; // Replace with your VirusTotal API key + const url = 'https://www.virustotal.com/vtapi/v2/url/scan'; + const params = { + apikey: apiKey, + url: data }; + try { + const response = await axios.post(url, null, { params }); // Send URL scan request + return response.data.scan_id; // Return scan ID + } catch (error) { + console.error('Error scanning with VirusTotal:', error); // Handle error + throw error; // Propagate error + } +}; + +// Function to get scan result from VirusTotal and return the positive score +const getScanResult = async (scanId) => { + const apiKey = '3566a17933bb36dd97cb35e84d0446e5ab8ad623e6de968d34b655c79485251e'; // Replace with your VirusTotal API key + const url = 'https://www.virustotal.com/vtapi/v2/url/report'; + const params = { + apikey: apiKey, + resource: scanId + }; + + try { + const response = await axios.get(url, { params }); // Get scan result + return response.data.positives; // Return positive score + } catch (error) { + console.error('Error getting scan result:', error); // Handle error + throw error; // Propagate error + } +}; + if (showSplash) { return ( @@ -67,21 +127,19 @@ function QRScannerScreen() { style={styles.camera} // Apply styles /> - - {/* Display scanned data */} - {scannedData !== '' && ( + {/* Display scanned data */} + {scannedData !== '' && ( {scannedData} + {scanResult && {JSON.stringify(scanResult)}} )} - {/* Button to scan again */} {scanned && ( setScanned(false)}> Tap to Scan Again )} - {/* Menu (Placeholder for additional menu items) */} {/* Your existing menu items */} @@ -90,6 +148,7 @@ function QRScannerScreen() { ); } +// Component for History Screen function HistoryScreen() { const { qrCodes } = useContext(QRCodeContext); // Access context @@ -97,26 +156,38 @@ function HistoryScreen() { History Screen ( {item} )} - keyExtractor={(item, index) => index.toString()} + keyExtractor={(item, index) => index.toString()} // Key extractor for FlatList /> ); } +// Component for Settings Screen function SettingsScreen() { + const { setQrCodes } = useContext(QRCodeContext); // Access context + + // Function to clear history + const clearHistory = () => { + setQrCodes([]); + }; + return ( Settings Screen + + Clear History + ); } +// Component for Profile Screen function ProfileScreen() { return ( @@ -235,4 +306,13 @@ const styles = StyleSheet.create({ backgroundColor: "#ff69b4", // pink background paddingVertical: 10, }, + + + // Additional styles for green and red boxes + greenBox: { + backgroundColor: '#00FF00', // Green color + }, + redBox: { + backgroundColor: '#FF0000', // Red color + }, }); diff --git a/package-lock.json b/package-lock.json index 53768a3..ab7a101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@expo/vector-icons": "^14.0.2", "@react-navigation/bottom-tabs": "^6.5.20", "@react-navigation/native": "^6.1.17", + "axios": "^1.7.2", "expo": "~51.0.11", "expo-camera": "~15.0.10", "expo-status-bar": "~1.12.1", @@ -5997,6 +5998,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -7853,6 +7877,25 @@ "node": ">=0.4.0" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fontfaceobserver": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", @@ -11549,6 +11592,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", diff --git a/package.json b/package.json index fcb21ff..b5e67fa 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@expo/vector-icons": "^14.0.2", "@react-navigation/bottom-tabs": "^6.5.20", "@react-navigation/native": "^6.1.17", + "axios": "^1.7.2", "expo": "~51.0.11", "expo-camera": "~15.0.10", "expo-status-bar": "~1.12.1",