From 9008a00579790074b7082f07f5c01fdf66943cd7 Mon Sep 17 00:00:00 2001 From: Ukaykhingmarma28 Date: Sat, 1 Feb 2025 23:18:53 +0600 Subject: first commit --- .gitignore | 47 ++++++++++++++++++++ index.js | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ inventory.sh | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 17 +++++++ 4 files changed, 323 insertions(+) create mode 100644 .gitignore create mode 100644 index.js create mode 100755 inventory.sh create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05df289 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Dependencies +node_modules/ +package-lock.json +yarn.lock + +# Environment variables +.env +.env.local +.env.*.local +key.json + +# Build output +dist/ +build/ +coverage/ + +# Logs +logs/ +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# IDE and editor files +.idea/ +.vscode/ +*.swp +*.swo +.DS_Store + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# TypeScript cache +*.tsbuildinfo \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..bd50051 --- /dev/null +++ b/index.js @@ -0,0 +1,143 @@ +import express from 'express'; +import { MongoClient } from 'mongodb'; +import { google } from 'googleapis'; +import crypto from 'crypto'; +import dotenv from 'dotenv'; // For loading environment variables +import fs from 'fs'; // For reading the Google credentials JSON file + +dotenv.config(); // Load .env variables + +const app = express(); +const port = 3000; + +app.use(express.json()); + +// Mongo URI from .env +const uri = process.env.MONGO_URI; +const client = new MongoClient(uri); +const dbName = 'inventory'; +const collectionName = 'items'; + +// Load Google credentials from the key.json file +const googleCredentialsPath = process.env.GOOGLE_CREDENTIALS_PATH; +const googleApisKey = JSON.parse(fs.readFileSync(googleCredentialsPath, 'utf8')); + +// Initialize Google Sheets API authentication +const auth = new google.auth.JWT( + googleApisKey.client_email, + null, + googleApisKey.private_key, + ['https://www.googleapis.com/auth/spreadsheets'] +); + +const spreadsheetId = process.env.SPREADSHEET_ID; +const sheets = google.sheets({ version: 'v4', auth }); +const range = 'Sheet1!A:H'; + +// Connect to MongoDB +async function connectDB() { + try { + await client.connect(); + console.log('Connected to MongoDB!'); + } catch (err) { + console.error('Error connecting to MongoDB:', err); + process.exit(1); + } +} + +connectDB(); + +// Generate Serial Number +function generateSerialNumber() { + return `Jadupc${crypto.randomInt(100000, 999999)}`; +} + +// Route to upload device details +app.post('/upload', async (req, res) => { + const { Verient, mac, os, status, customerAddress, customerNumber, customerName } = req.body; + + if (!Verient || !mac || !os) { + return res.status(400).send('Missing required fields: Verient, mac, os, or status'); + } + + // Check if device already exists in database + try { + const db = client.db(dbName); + const collection = db.collection(collectionName); + + const existingDevice = await collection.findOne({ mac }); + + if (existingDevice) { + return res.status(400).send('Device with the same MAC address is already registered'); + } + + // Generate serial number + const serialNumber = generateSerialNumber(); + + const newItem = { + serialNumber, + Verient, + mac, + os, + status: status || 'registered', + customerAddress, + customerNumber, + customerName, + }; + + await collection.insertOne(newItem); + console.log('Item successfully added to MongoDB'); + + try { + // Append data to Google Sheets + const response = await sheets.spreadsheets.values.append({ + spreadsheetId, + range, + valueInputOption: 'USER_ENTERED', + requestBody: { + values: [[serialNumber, Verient, mac, os, status, customerAddress, customerNumber, customerName]], + }, + }); + console.log('Data successfully appended to Google Sheets'); + res.status(200).send('Device uploaded and added to MongoDB and Google Sheets. Serial Number: ' + serialNumber); + } catch (err) { + console.error('Error appending to Google Sheets:', err); + res.status(500).send('Error uploading to Google Sheets'); + } + } catch (err) { + console.error('Error inserting item into MongoDB:', err); + res.status(500).send('Error uploading item to MongoDB'); + } +}); + +// Route to check device status +app.get('/check-status', async (req, res) => { + const { mac, serialNumber } = req.query; + + if (!mac && !serialNumber) { + return res.status(400).send('MAC or Serial Number required'); + } + + try { + const db = client.db(dbName); + const collection = db.collection(collectionName); + const device = await collection.findOne(mac ? { mac } : { serialNumber }); + + if (!device) { + return res.status(200).json({ + serialNumber: null, + status: 'new' // Default status if not found + }); + } + + res.status(200).json({ + serialNumber: device.serialNumber, + status: device.status // Default status if missing + }); + } catch (err) { + res.status(500).send('Error checking device status'); + } +}); + +// Start the server +app.listen(port, () => console.log(`Server running on http://localhost:${port}`)); diff --git a/inventory.sh b/inventory.sh new file mode 100755 index 0000000..ed7a037 --- /dev/null +++ b/inventory.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +# Function to get MAC address of the default network interface +get_mac_address() { + INTERFACE=$(ip route | awk '/default/ {print $5; exit}') + + if [[ -n "$INTERFACE" ]]; then + MAC=$(cat /sys/class/net/$INTERFACE/address) + echo "Detected MAC Address: $MAC" + check_device_status "$MAC" + else + echo "No active network interface found!" + exit 1 + fi +} + +# Function for manual input +manual_input() { + read -p "Enter MAC Address (manually or via barcode scan): " MAC + if [[ -n "$MAC" ]]; then + check_device_status "$MAC" + else + echo "Invalid input! MAC Address cannot be empty." + exit 1 + fi +} + +# Function to check device status using the API +check_device_status() { + local MAC_ADDRESS="$1" + API_URL="http://localhost:3000/check-status?mac=$MAC_ADDRESS" + + RESPONSE=$(curl -s "$API_URL") + + if [[ -z "$RESPONSE" ]]; then + echo "No response from server. Check if the API is running." + exit 1 + fi + + # Check if the device is registered or new + STATUS=$(echo "$RESPONSE" | jq -r '.status') + + if [[ "$STATUS" == "registered" ]]; then + SERIAL_NUMBER=$(echo "$RESPONSE" | jq -r '.serialNumber') + echo "Device is already registered. Serial number is $SERIAL_NUMBER." + elif [[ "$STATUS" == "new" ]]; then + echo "Device is new. Proceeding to registration." + register_device "$MAC_ADDRESS" + else + echo "Unknown status: $STATUS" + fi +} + +# Function to register the device +register_device() { + local MAC_ADDRESS="$1" + + # Ask user for variant choice (pro or starter) + echo "Select variant (pro or starter):" + read -p "Enter your choice: " VARIANT + + if [[ "$VARIANT" != "pro" && "$VARIANT" != "starter" ]]; then + echo "Invalid variant choice. Exiting." + exit 1 + fi + + # Get OS name from /etc/os-release + OS_NAME=$(grep "^NAME=" /etc/os-release | cut -d= -f2 | tr -d '"') + + # Optional customer information + read -p "Enter customer name (or press Enter to skip): " CUSTOMER_NAME + read -p "Enter customer address (or press Enter to skip): " CUSTOMER_ADDRESS + read -p "Enter customer phone number (or press Enter to skip): " CUSTOMER_NUMBER + + # Prepare JSON body for the POST request + JSON_BODY=$(jq -n \ + --arg verient "$VARIANT" \ + --arg mac "$MAC_ADDRESS" \ + --arg os "$OS_NAME" \ + --arg status "registered" \ + --arg customerName "$CUSTOMER_NAME" \ + --arg customerAddress "$CUSTOMER_ADDRESS" \ + --arg customerNumber "$CUSTOMER_NUMBER" \ + '{ + Verient: $verient, + mac: $mac, + os: $os, + status: $status, + customerName: $customerName, + customerAddress: $customerAddress, + customerNumber: $customerNumber + }') + + # Send the registration request + REGISTER_URL="http://localhost:3000/upload" + REGISTER_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d "$JSON_BODY" "$REGISTER_URL") + + if [[ -n "$REGISTER_RESPONSE" ]]; then + echo "Device successfully registered. Response: $REGISTER_RESPONSE" + else + echo "No response from the registration API. Check if the API is running." + fi +} + +# Menu for user selection +echo "Select an option:" +echo "1. Input MAC manually (type manually or barcode scan)" +echo "2. Auto-detect device MAC" + +read -p "Enter your choice (1 or 2): " CHOICE + +case $CHOICE in + 1) manual_input ;; + 2) get_mac_address ;; + *) echo "Invalid option. Please select 1 or 2." ;; +esac diff --git a/package.json b/package.json new file mode 100644 index 0000000..5779172 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "inventory", + "version": "1.0.0", + "type": "module", + "main": "index.js", + "scripts": { + "start": "nodemon index.js" + }, + "dependencies": { + "crypto": "^1.0.1", + "dotenv": "^16.4.7", + "express": "^4.17.1", + "fs": "^0.0.1-security", + "googleapis": "^39.2.0", + "mongodb": "^4.17.2" + } +} -- cgit v1.2.3