@syshcndr/attendance 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/attendance.js +151 -0
  2. package/package.json +24 -0
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawnSync } = require("node:child_process");
4
+
5
+ function printHelp() {
6
+ console.log(`attendance - WLAN SSID attendance checker\n
7
+ Usage:
8
+ attendance [--ssid <SSID_NAME>] [--start YYYY-MM-DD]
9
+
10
+ Options:
11
+ --ssid SSID name to match in WLAN AutoConfig logs. Default: Sapiens-Corporate
12
+ --start Start date in YYYY-MM-DD format. Default: 2026-01-01
13
+ --help Show this help.
14
+
15
+ Example:
16
+ attendance --ssid "Sapiens-Corporate" --start 2026-01-01`);
17
+ }
18
+
19
+ function parseArgs(argv) {
20
+ const args = {
21
+ ssid: "Sapiens-Corporate",
22
+ start: "2026-01-01",
23
+ help: false,
24
+ };
25
+
26
+ for (let i = 0; i < argv.length; i += 1) {
27
+ const token = argv[i];
28
+
29
+ if (token === "--help" || token === "-h") {
30
+ args.help = true;
31
+ continue;
32
+ }
33
+
34
+ if (token === "--ssid") {
35
+ args.ssid = argv[i + 1];
36
+ i += 1;
37
+ continue;
38
+ }
39
+
40
+ if (token === "--start") {
41
+ args.start = argv[i + 1];
42
+ i += 1;
43
+ continue;
44
+ }
45
+ }
46
+
47
+ return args;
48
+ }
49
+
50
+ function validateDate(dateText) {
51
+ return /^\d{4}-\d{2}-\d{2}$/.test(dateText);
52
+ }
53
+
54
+ function escapeForSingleQuotedPsString(value) {
55
+ return String(value).replace(/'/g, "''");
56
+ }
57
+
58
+ function getAttendanceDates({ ssid, start }) {
59
+ const safeSsid = escapeForSingleQuotedPsString(ssid);
60
+ const safeStart = escapeForSingleQuotedPsString(start);
61
+
62
+ const psScript = `
63
+ $ErrorActionPreference = 'Stop'
64
+ $ssid='${safeSsid}'
65
+ $start=[datetime]'${safeStart}'
66
+
67
+ $rows = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-WLAN-AutoConfig/Operational'; StartTime=$start; Id=8001} |
68
+ Where-Object { $_.Message -like ('*' + $ssid + '*') } |
69
+ Sort-Object TimeCreated |
70
+ Select-Object @{n='Date';e={$_.TimeCreated.ToString('yyyy-MM-dd')}} -Unique
71
+
72
+ $rows | ConvertTo-Json -Compress
73
+ `;
74
+
75
+ const result = spawnSync(
76
+ "powershell",
77
+ ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psScript],
78
+ {
79
+ encoding: "utf8",
80
+ maxBuffer: 10 * 1024 * 1024,
81
+ },
82
+ );
83
+
84
+ if (result.error) {
85
+ throw result.error;
86
+ }
87
+
88
+ if (result.status !== 0) {
89
+ const stderr = (result.stderr || "").trim();
90
+ throw new Error(stderr || "PowerShell command failed.");
91
+ }
92
+
93
+ const stdout = (result.stdout || "").trim();
94
+ if (!stdout) {
95
+ return [];
96
+ }
97
+
98
+ let parsed;
99
+ try {
100
+ parsed = JSON.parse(stdout);
101
+ } catch {
102
+ return [];
103
+ }
104
+
105
+ const rows = Array.isArray(parsed) ? parsed : [parsed];
106
+ return rows.map((r) => r.Date).filter(Boolean);
107
+ }
108
+
109
+ function printResult(ssid, start, dates) {
110
+ console.log(`SSID : ${ssid}`);
111
+ console.log(`Start Date : ${start}`);
112
+ console.log("");
113
+
114
+ if (dates.length === 0) {
115
+ console.log("No attendance days found.");
116
+ console.log("Total Days: 0");
117
+ return;
118
+ }
119
+
120
+ for (const date of dates) {
121
+ console.log(date);
122
+ }
123
+
124
+ console.log("");
125
+ console.log(`Total Days: ${dates.length}`);
126
+ }
127
+
128
+ function main() {
129
+ const args = parseArgs(process.argv.slice(2));
130
+
131
+ if (args.help) {
132
+ printHelp();
133
+ process.exit(0);
134
+ }
135
+
136
+ if (!validateDate(args.start)) {
137
+ console.error("Error: --start must be in YYYY-MM-DD format.");
138
+ process.exit(1);
139
+ }
140
+
141
+ try {
142
+ const dates = getAttendanceDates({ ssid: args.ssid, start: args.start });
143
+ printResult(args.ssid, args.start, dates);
144
+ } catch (error) {
145
+ console.error("Failed to fetch attendance from Windows event logs.");
146
+ console.error(error.message || String(error));
147
+ process.exit(1);
148
+ }
149
+ }
150
+
151
+ main();
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@syshcndr/attendance",
3
+ "version": "1.0.0",
4
+ "description": "CLI to list attendance days from Windows WLAN AutoConfig logs for a specific SSID",
5
+ "private": false,
6
+ "type": "commonjs",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "bin": {
11
+ "attendance": "./bin/attendance.js"
12
+ },
13
+ "scripts": {
14
+ "start": "node ./bin/attendance.js"
15
+ },
16
+ "keywords": [
17
+ "attendance",
18
+ "wlan",
19
+ "windows",
20
+ "cli"
21
+ ],
22
+ "author": "",
23
+ "license": "MIT"
24
+ }