-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
109 lines (85 loc) · 3.92 KB
/
server.js
File metadata and controls
109 lines (85 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Load environment variables from .env file
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
const pool = require('./db'); // Import the database connection pool
// --- Configuration from .env ---
const API_KEY = process.env.API_KEY;
const PORT = process.env.PORT || 3000; // Default to 3000 if not specified
// --- Middleware ---
app.use(cors()); // Enable CORS for all routes
app.use(express.json()); // For parsing application/json
app.use(express.urlencoded({ extended: true })); // For parsing application/x-www-form-urlencoded
// Static API-token authentication middleware
const authenticateApiKey = (req, res, next) => {
const apiKey = req.headers['x-api-key'];
if (!apiKey) {
return res.status(401).json({ message: 'Unauthorized: x-api-key header missing' });
}
if (apiKey !== API_KEY) {
return res.status(403).json({ message: 'Forbidden: Invalid API Key' });
}
next(); // API Key is valid, proceed to the next middleware/route handler
};
const loggingMiddleware = require('./loggingMiddleware');
// Apply authentication middleware to all routes that require it
app.use(authenticateApiKey);
// Apply logging middleware to all routes
app.use(loggingMiddleware);
// --- Endpoints ---
// GET /test: Returns a 200 OK status to verify the API is alive.
app.get('/test', (req, res) => {
res.status(200).send('API is alive and authenticated!');
});
// GET /sensor-values: Queries RELAY1, RELAY2, RELAY3, RELAY4 from sensor_readings where ID=1.
app.get('/sensor-values', async (req, res) => {
try {
const [rows] = await pool.execute(
'SELECT RELAY1, RELAY2, RELAY3, RELAY4 FROM sensor_readings WHERE ID = 1'
);
if (rows.length === 0) {
return res.status(404).json({ message: 'Sensor readings for ID 1 not found.' });
}
res.status(200).json(rows[0]);
} catch (error) {
console.error('Error fetching sensor values:', error);
res.status(500).json({ message: 'Internal server error', error: error.message });
}
});
// POST /update-relay: Accepts relayName and value to update specific relays back to 0.
app.post('/update-relay', async (req, res) => {
const { relayName, value } = req.body;
// Basic validation
if (!relayName || value === undefined) {
return res.status(400).json({ message: 'Missing relayName or value in request body.' });
}
// Validate relayName to prevent SQL injection and ensure it's a valid column
const validRelayNames = ['RELAY1', 'RELAY2', 'RELAY3', 'RELAY4'];
if (!validRelayNames.includes(relayName.toUpperCase())) {
return res.status(400).json({ message: `Invalid relayName: ${relayName}. Must be one of ${validRelayNames.join(', ')}.` });
}
// Validate the value. Allow 0 (reset), 1 (activate 3s), or 2 (activate 10s).
if (![0, 1, 2].includes(Number(value))) {
return res.status(400).json({ message: 'Invalid value. Must be 0, 1, or 2.' });
}
try {
// Use backticks for column name in SQL query to allow dynamic column names
const [result] = await pool.execute(
`UPDATE sensor_readings SET \`${relayName}\` = ? WHERE ID = 1`,
[value] // Pass the value to update
);
if (result.affectedRows === 0) {
return res.status(404).json({ message: 'Sensor reading for ID 1 not found or relay not updated.' });
}
res.status(200).json({ message: `${relayName} updated to ${value} successfully.` });
} catch (error) {
console.error('Error updating relay:', error);
res.status(500).json({ message: 'Internal server error', error: error.message });
}
});
// --- Start the Server ---
app.listen(PORT, '0.0.0.0', () => { // Explicitly listen on all interfaces for clarity, though it's default
console.log(`Server running on port ${PORT}`);
});
module.exports = app; // Export the app for testing