-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
146 lines (121 loc) · 4.15 KB
/
index.js
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
139
140
141
142
143
144
145
146
// @ts-check
import bot from 'node-autoit-koffi';
import { createServer } from 'node:http';
import qs from 'node:querystring';
import pkg from './package.json' assert { type: 'json' };
const host = `127.0.0.1`; // bind the server to the loopback interface so we don't expose it
const port = Number(process.env.SERVER_PORT) || 3000;
const fp_win_title = process.env.FP_WIN_TITLE || 'Aplikasi Registrasi Sidik Jari';
const fp_ins_path = process.env.FP_INS_PATH || 'C:\\Program Files (x86)\\BPJS Kesehatan\\Aplikasi Sidik Jari BPJS Kesehatan\\After.exe';
const server = createServer((req, res) => {
// allow cors
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
/** @param {Error} error */
function handle_error(error) {
console.error(error);
json(500, { message: error?.message || `Internal server error` });
}
/**
* @param {number} status
* @param {any =} data
*/
function json(status, data) {
res.writeHead(status, { 'Content-Type': 'application/json' });
if (!data) return res.end();
res.end(JSON.stringify(data));
}
try {
const url = new URL(req.url || '/', `http://${host}`);
if (url.pathname === '/' && req.method === 'GET') {
// service info
json(200, { message: pkg.description });
} else if (url.pathname === '/' && req.method === 'POST') {
// apm bot service
let body = '';
req.on('data', (chunk) => (body += chunk.toString()));
req.on('end', () => {
const form_data = qs.parse(body);
const username = form_data['username'];
const password = form_data['password'];
const card_number = form_data['card_number'];
const exit = form_data['exit'] === 'true';
const wait = form_data['wait'];
if (!username || !password || !card_number) {
return json(400, {
message: `username, password, and card_number are required fields`
});
}
run_bot({ username, password, card_number, exit, wait })
.then(() => json(201))
.catch((e) => handle_error(e));
});
} else {
json(404, { message: `Not found` });
}
} catch (error) {
handle_error(error);
}
});
server.on('error', (err) => {
// might to try restarting the server or take other actions
console.error('Server error:', err);
});
server.listen(port, host, () => {
console.log(`Server running at http://${host}:${port}`);
});
/** @param {number} ms */
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function run_bot({ username, password, card_number, exit, wait }) {
// open or activate the application window
const already_open = await bot.winExists(fp_win_title);
if (!already_open) {
await bot.run(fp_ins_path);
await bot.winWait(fp_win_title); // wait for the application window to appear
}
await bot.winActivate(fp_win_title); // activate the application window
await bot.winWaitActive(fp_win_title); // wait for the application to be in focus
if (exit) {
await bot.winSetOnTop(fp_win_title, '', 1); // set window on top
}
// get the position and size of the window
const win_pos = await bot.winGetPos(fp_win_title);
if (!win_pos) throw new Error('Failed to get window position');
// use top and left positions to calculate absolute points
const { top, left } = win_pos;
// login if window just open up
if (already_open) {
// focus number input
await bot.mouseMove(left + 223, top + 121, 0);
await bot.mouseClick('left');
// clear number input
await bot.send('^a');
await bot.send('{BACKSPACE}');
} else {
// focus to the first input
await bot.mouseMove(left + 223, top + 179, 0);
await bot.mouseClick('left');
await delay(1000);
// clear and enter the username
await bot.send('^a');
await bot.send('{BACKSPACE}');
await bot.send(username);
await bot.send('{TAB}');
// clear and enter the password
await bot.send('^a');
await bot.send('{BACKSPACE}');
await bot.send(password);
// hit enter key for login
await bot.send('{ENTER}');
await delay(+wait || 3_593);
}
// send card number
await bot.send(card_number);
if (exit) {
// wait for window to close
await bot.winWaitClose(fp_win_title);
}
}