-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
138 lines (113 loc) Β· 3.61 KB
/
server.js
File metadata and controls
138 lines (113 loc) Β· 3.61 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const express = require("express");
const ZKLib = require("zklib-js");
const cors = require("cors");
const app = express();
// Parse command line arguments
const args = process.argv.slice(2);
let PORT = 3000;
let HOST = "0.0.0.0"; // Default to all interfaces
for (let i = 0; i < args.length; i++) {
if (args[i] === "--port" && args[i + 1]) {
PORT = parseInt(args[i + 1]);
} else if (args[i] === "--host" && args[i + 1]) {
HOST = args[i + 1];
} else if (args[i].startsWith("--port=")) {
PORT = parseInt(args[i].split("=")[1]);
} else if (args[i].startsWith("--host=")) {
HOST = args[i].split("=")[1];
}
}
// Device IP and port
const DEVICE_IP = "192.168.13.201";
const DEVICE_PORT = 4370;
app.use(cors());
// Initialize device connection object
const zk = new ZKLib(DEVICE_IP, DEVICE_PORT, 5000, 0);
// Helper function to connect with retry
async function connectToDevice() {
try {
console.log(`π Connecting to ZKTeco at ${DEVICE_IP}:${DEVICE_PORT}...`);
await zk.createSocket();
console.log("β
Connected to device.");
} catch (err) {
console.warn("β οΈ First connection attempt failed:", err.message);
console.log("π Retrying in 1 second...");
await new Promise((res) => setTimeout(res, 1000));
try {
await zk.createSocket();
console.log("β
Connected on second attempt.");
} catch (retryErr) {
throw new Error(
`Failed to connect to device after retry: ${retryErr.message}`
);
}
}
}
// β
GET /users
app.get("/users", async (req, res) => {
try {
await connectToDevice();
console.log("π₯ Fetching users...");
const users = await zk.getUsers();
await zk.disconnect();
console.log("π Disconnected from device.");
res.json({success: true, users});
} catch (err) {
console.error("β Error in /users:", err.message);
try {
await zk.disconnect(); // Ensure socket is closed on error
} catch {}
res.status(500).json({
success: false,
message: err.message || "Unknown error",
error: err,
});
}
});
// β
GET /logs
app.get("/logs", async (req, res) => {
const {from, to, userId} = req.query;
try {
const fromDate = from ? new Date(from) : null;
const toDate = to ? new Date(to) : null;
if ((from && isNaN(fromDate)) || (to && isNaN(toDate))) {
return res.status(400).json({
success: false,
message: "Invalid date format. Use MM/DD/YYYY",
});
}
await connectToDevice();
console.log("π₯ Fetching attendance logs...");
const rawLogs = await zk.getAttendances();
await zk.disconnect();
if (!rawLogs || !Array.isArray(rawLogs.data)) {
throw new Error("Device returned invalid or no log data.");
}
const logs = rawLogs.data;
// Filter logs
const filteredLogs = logs.filter((log) => {
const logDate = new Date(log.recordTime);
const isWithinDateRange =
(!fromDate || logDate >= fromDate) && (!toDate || logDate <= toDate);
const isMatchingUser =
!userId || String(log.deviceUserId) === String(userId);
return isWithinDateRange && isMatchingUser;
});
res.json({success: true, logs: filteredLogs});
} catch (err) {
console.error("β Error in /logs:", err.message);
try {
await zk.disconnect();
} catch {}
res.status(500).json({
success: false,
message: err.message || "Unknown error",
error: err,
});
}
});
// π’ Start the server
app.listen(PORT, HOST, () => {
console.log(`π API Server running at http://${HOST}:${PORT}`);
console.log(`π Server accessible on all network interfaces`);
});