@heyhru/app-dms-server 0.1.9 → 0.2.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.
- package/dist/index.js +33 -137
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -83,119 +83,14 @@ async function authHook(req, reply) {
|
|
|
83
83
|
|
|
84
84
|
// src/auth/auth.service.ts
|
|
85
85
|
import { signToken } from "@heyhru/server-plugin-jwt";
|
|
86
|
-
import { hashPassword
|
|
87
|
-
|
|
88
|
-
// src/users/users.service.ts
|
|
89
|
-
import { hashPassword } from "@heyhru/server-util-crypto";
|
|
90
|
-
|
|
91
|
-
// src/users/users.model.ts
|
|
92
|
-
import { getPgDb } from "@heyhru/server-plugin-pg";
|
|
93
|
-
|
|
94
|
-
// src/users/users.sql.ts
|
|
95
|
-
var LIST = `
|
|
96
|
-
SELECT id, username, email, role, created_at
|
|
97
|
-
FROM users
|
|
98
|
-
ORDER BY created_at DESC`;
|
|
99
|
-
var FIND_BY_ID = `
|
|
100
|
-
SELECT id, username, email, role, created_at
|
|
101
|
-
FROM users
|
|
102
|
-
WHERE id = ?`;
|
|
103
|
-
var FIND_BY_USERNAME = `
|
|
104
|
-
SELECT *
|
|
105
|
-
FROM users
|
|
106
|
-
WHERE username = ?`;
|
|
107
|
-
var CREATE = `
|
|
108
|
-
INSERT INTO users (username, email, password_hash, role)
|
|
109
|
-
VALUES (?, ?, ?, ?)
|
|
110
|
-
RETURNING id, username, email, role, created_at`;
|
|
111
|
-
var UPDATE_PASSWORD = () => `
|
|
112
|
-
UPDATE users
|
|
113
|
-
SET password_hash = ?, updated_at = NOW()
|
|
114
|
-
WHERE id = ?`;
|
|
115
|
-
var DELETE = `
|
|
116
|
-
DELETE FROM users
|
|
117
|
-
WHERE id = ?`;
|
|
118
|
-
|
|
119
|
-
// src/users/users.model.ts
|
|
120
|
-
function listUsers() {
|
|
121
|
-
return getPgDb().query(LIST);
|
|
122
|
-
}
|
|
123
|
-
function getUserById(id) {
|
|
124
|
-
return getPgDb().queryOne(FIND_BY_ID, [id]);
|
|
125
|
-
}
|
|
126
|
-
function getUserByUsername(username) {
|
|
127
|
-
return getPgDb().queryOne(FIND_BY_USERNAME, [username]);
|
|
128
|
-
}
|
|
129
|
-
function createUserRow(username, email, hash, role) {
|
|
130
|
-
return getPgDb().queryOne(CREATE, [username, email, hash, role]);
|
|
131
|
-
}
|
|
132
|
-
async function updateUserRow(id, data) {
|
|
133
|
-
const fields = [];
|
|
134
|
-
const values = [];
|
|
135
|
-
if (data.email) {
|
|
136
|
-
fields.push("email = ?");
|
|
137
|
-
values.push(data.email);
|
|
138
|
-
}
|
|
139
|
-
if (data.role) {
|
|
140
|
-
fields.push("role = ?");
|
|
141
|
-
values.push(data.role);
|
|
142
|
-
}
|
|
143
|
-
if (!fields.length) return getUserById(id);
|
|
144
|
-
fields.push("updated_at = NOW()");
|
|
145
|
-
values.push(id);
|
|
146
|
-
return getPgDb().queryOne(
|
|
147
|
-
`UPDATE users SET ${fields.join(", ")} WHERE id = ? RETURNING id, username, email, role, created_at`,
|
|
148
|
-
values
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
function deleteUser(id) {
|
|
152
|
-
return getPgDb().run(DELETE, [id]);
|
|
153
|
-
}
|
|
154
|
-
function updatePasswordHash(id, hash) {
|
|
155
|
-
return getPgDb().run(UPDATE_PASSWORD(), [hash, id]);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// src/users/users.service.ts
|
|
159
|
-
function getUserByUsername2(username) {
|
|
160
|
-
return getUserByUsername(username);
|
|
161
|
-
}
|
|
162
|
-
function updateUserPassword(id, hash) {
|
|
163
|
-
return updatePasswordHash(id, hash);
|
|
164
|
-
}
|
|
165
|
-
async function userList(_req, reply) {
|
|
166
|
-
return reply.send(await listUsers());
|
|
167
|
-
}
|
|
168
|
-
async function userGet(req, reply) {
|
|
169
|
-
const { id } = req.body ?? {};
|
|
170
|
-
const user = await getUserById(id);
|
|
171
|
-
if (!user) return reply.code(404).send({ error: "\u672A\u627E\u5230" });
|
|
172
|
-
return reply.send(user);
|
|
173
|
-
}
|
|
174
|
-
async function userCreate(req, reply) {
|
|
175
|
-
const body = req.body ?? {};
|
|
176
|
-
const hash = await hashPassword(body.password);
|
|
177
|
-
const user = await createUserRow(body.username, body.email, hash, body.role);
|
|
178
|
-
return reply.code(201).send(user);
|
|
179
|
-
}
|
|
180
|
-
async function userUpdate(req, reply) {
|
|
181
|
-
const { id, ...rest } = req.body ?? {};
|
|
182
|
-
const user = await updateUserRow(id, rest);
|
|
183
|
-
if (!user) return reply.code(404).send({ error: "\u672A\u627E\u5230" });
|
|
184
|
-
return reply.send(user);
|
|
185
|
-
}
|
|
186
|
-
async function userDelete(req, reply) {
|
|
187
|
-
const { id } = req.body ?? {};
|
|
188
|
-
await deleteUser(id);
|
|
189
|
-
return reply.code(204).send();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/auth/auth.service.ts
|
|
86
|
+
import { hashPassword, verifyPassword } from "@heyhru/server-util-crypto";
|
|
87
|
+
import { getUserByUsername, updateUserPassword } from "@heyhru/business-dms-user";
|
|
193
88
|
async function authLogin(req, reply) {
|
|
194
89
|
const { username, password } = req.body ?? {};
|
|
195
90
|
if (!username || !password) {
|
|
196
91
|
return reply.code(400).send({ error: "\u7528\u6237\u540D\u548C\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A" });
|
|
197
92
|
}
|
|
198
|
-
const user = await
|
|
93
|
+
const user = await getUserByUsername(username);
|
|
199
94
|
if (!user || !await verifyPassword(password, user.password_hash)) {
|
|
200
95
|
req.log.warn("Login failed for user: %s", username);
|
|
201
96
|
return reply.code(401).send({ error: "\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF" });
|
|
@@ -217,11 +112,11 @@ async function authChangePassword(req, reply) {
|
|
|
217
112
|
if (!currentPassword || !newPassword) {
|
|
218
113
|
return reply.code(400).send({ error: "\u5F53\u524D\u5BC6\u7801\u548C\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A" });
|
|
219
114
|
}
|
|
220
|
-
const user = await
|
|
115
|
+
const user = await getUserByUsername(req.user.username);
|
|
221
116
|
if (!user || !await verifyPassword(currentPassword, user.password_hash)) {
|
|
222
117
|
return reply.code(400).send({ error: "\u5F53\u524D\u5BC6\u7801\u4E0D\u6B63\u786E" });
|
|
223
118
|
}
|
|
224
|
-
const hash = await
|
|
119
|
+
const hash = await hashPassword(newPassword);
|
|
225
120
|
await updateUserPassword(user.id, hash);
|
|
226
121
|
req.log.info("Password changed for user: %s", req.user.username);
|
|
227
122
|
return reply.send({ ok: true });
|
|
@@ -236,6 +131,7 @@ function authController(app) {
|
|
|
236
131
|
}
|
|
237
132
|
|
|
238
133
|
// src/users/users.controller.ts
|
|
134
|
+
import { userList, userGet, userCreate, userUpdate, userDelete } from "@heyhru/business-dms-user";
|
|
239
135
|
function userController(app) {
|
|
240
136
|
app.post("/users/list", userList);
|
|
241
137
|
app.post("/users/get", userGet);
|
|
@@ -250,14 +146,14 @@ import { createPool as createMysqlPool } from "@heyhru/server-plugin-mysql";
|
|
|
250
146
|
import { createPool as createPgPool } from "@heyhru/server-plugin-pg";
|
|
251
147
|
|
|
252
148
|
// src/datasources/datasources.model.ts
|
|
253
|
-
import { getPgDb
|
|
149
|
+
import { getPgDb } from "@heyhru/server-plugin-pg";
|
|
254
150
|
|
|
255
151
|
// src/datasources/datasources.sql.ts
|
|
256
|
-
var
|
|
152
|
+
var LIST = `
|
|
257
153
|
SELECT id, name, type, host, port, database, username, ssl, pool_min, pool_max, created_by, created_at
|
|
258
154
|
FROM data_sources
|
|
259
155
|
ORDER BY created_at DESC`;
|
|
260
|
-
var
|
|
156
|
+
var FIND_BY_ID = `
|
|
261
157
|
SELECT id, name, type, host, port, database, username, ssl, pool_min, pool_max, created_by, created_at
|
|
262
158
|
FROM data_sources
|
|
263
159
|
WHERE id = ?`;
|
|
@@ -265,27 +161,27 @@ var FIND_WITH_PASSWORD = `
|
|
|
265
161
|
SELECT *
|
|
266
162
|
FROM data_sources
|
|
267
163
|
WHERE id = ?`;
|
|
268
|
-
var
|
|
164
|
+
var CREATE = `
|
|
269
165
|
INSERT INTO data_sources (name, type, host, port, database, username, password_encrypted, ssl, pool_min, pool_max, created_by)
|
|
270
166
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
271
167
|
RETURNING id, name, type, host, port, database, username, ssl, pool_min, pool_max, created_by, created_at`;
|
|
272
168
|
var UPDATE_FIELDS = ["name", "type", "host", "port", "database", "username", "ssl", "pool_min", "pool_max"];
|
|
273
|
-
var
|
|
169
|
+
var DELETE = `
|
|
274
170
|
DELETE FROM data_sources
|
|
275
171
|
WHERE id = ?`;
|
|
276
172
|
|
|
277
173
|
// src/datasources/datasources.model.ts
|
|
278
174
|
function listDataSources() {
|
|
279
|
-
return
|
|
175
|
+
return getPgDb().query(LIST);
|
|
280
176
|
}
|
|
281
177
|
function getDataSourceById(id) {
|
|
282
|
-
return
|
|
178
|
+
return getPgDb().queryOne(FIND_BY_ID, [id]);
|
|
283
179
|
}
|
|
284
180
|
function getDataSourceRow(id) {
|
|
285
|
-
return
|
|
181
|
+
return getPgDb().queryOne(FIND_WITH_PASSWORD, [id]);
|
|
286
182
|
}
|
|
287
183
|
function insertDataSource(data, encryptedPassword, createdBy) {
|
|
288
|
-
return
|
|
184
|
+
return getPgDb().queryOne(CREATE, [
|
|
289
185
|
data.name,
|
|
290
186
|
data.type,
|
|
291
187
|
data.host,
|
|
@@ -314,13 +210,13 @@ async function updateDataSource(id, data, encryptedPassword) {
|
|
|
314
210
|
}
|
|
315
211
|
if (!fields.length) return getDataSourceById(id);
|
|
316
212
|
values.push(id);
|
|
317
|
-
return
|
|
213
|
+
return getPgDb().queryOne(
|
|
318
214
|
`UPDATE data_sources SET ${fields.join(", ")} WHERE id = ? RETURNING id, name, type, host, port, database, username, ssl, pool_min, pool_max, created_by, created_at`,
|
|
319
215
|
values
|
|
320
216
|
);
|
|
321
217
|
}
|
|
322
218
|
function removeDataSource(id) {
|
|
323
|
-
return
|
|
219
|
+
return getPgDb().run(DELETE, [id]);
|
|
324
220
|
}
|
|
325
221
|
|
|
326
222
|
// src/datasources/datasources.service.ts
|
|
@@ -430,13 +326,13 @@ function datasourceController(app) {
|
|
|
430
326
|
import NodeSqlParser from "node-sql-parser";
|
|
431
327
|
|
|
432
328
|
// src/audit/audit.model.ts
|
|
433
|
-
import { getPgDb as
|
|
329
|
+
import { getPgDb as getPgDb2 } from "@heyhru/server-plugin-pg";
|
|
434
330
|
|
|
435
331
|
// src/audit/audit.sql.ts
|
|
436
332
|
var INSERT = `
|
|
437
333
|
INSERT INTO audit_logs (user_id, data_source_id, action, sql_text, result_summary, ip_address)
|
|
438
334
|
VALUES (?, ?, ?, ?, ?, ?)`;
|
|
439
|
-
var
|
|
335
|
+
var LIST2 = `
|
|
440
336
|
SELECT al.*, u.username
|
|
441
337
|
FROM audit_logs al
|
|
442
338
|
LEFT JOIN users u ON al.user_id = u.id
|
|
@@ -444,7 +340,7 @@ WHERE 1=1`;
|
|
|
444
340
|
|
|
445
341
|
// src/audit/audit.model.ts
|
|
446
342
|
function insertAuditLog(entry) {
|
|
447
|
-
return
|
|
343
|
+
return getPgDb2().run(INSERT, [
|
|
448
344
|
entry.userId,
|
|
449
345
|
entry.dataSourceId ?? null,
|
|
450
346
|
entry.action,
|
|
@@ -454,7 +350,7 @@ function insertAuditLog(entry) {
|
|
|
454
350
|
]);
|
|
455
351
|
}
|
|
456
352
|
async function queryAuditLogs(filters) {
|
|
457
|
-
let query =
|
|
353
|
+
let query = LIST2;
|
|
458
354
|
const params = [];
|
|
459
355
|
if (filters?.userId) {
|
|
460
356
|
query += " AND al.user_id = ?";
|
|
@@ -466,7 +362,7 @@ async function queryAuditLogs(filters) {
|
|
|
466
362
|
}
|
|
467
363
|
query += " ORDER BY al.created_at DESC LIMIT ? OFFSET ?";
|
|
468
364
|
params.push(filters?.limit ?? 50, filters?.offset ?? 0);
|
|
469
|
-
return
|
|
365
|
+
return getPgDb2().query(query, params);
|
|
470
366
|
}
|
|
471
367
|
|
|
472
368
|
// src/audit/audit.service.ts
|
|
@@ -590,14 +486,14 @@ function sqlController(app) {
|
|
|
590
486
|
}
|
|
591
487
|
|
|
592
488
|
// src/approvals/approvals.model.ts
|
|
593
|
-
import { getPgDb as
|
|
489
|
+
import { getPgDb as getPgDb3 } from "@heyhru/server-plugin-pg";
|
|
594
490
|
|
|
595
491
|
// src/approvals/approvals.sql.ts
|
|
596
|
-
var
|
|
492
|
+
var FIND_BY_ID2 = `
|
|
597
493
|
SELECT *
|
|
598
494
|
FROM approvals
|
|
599
495
|
WHERE id = ?`;
|
|
600
|
-
var
|
|
496
|
+
var CREATE2 = `
|
|
601
497
|
INSERT INTO approvals (data_source_id, sql_text, submitted_by)
|
|
602
498
|
VALUES (?, ?, ?)
|
|
603
499
|
RETURNING *`;
|
|
@@ -628,22 +524,22 @@ async function listApprovals(filters) {
|
|
|
628
524
|
params.push(filters.submittedBy);
|
|
629
525
|
}
|
|
630
526
|
query += " ORDER BY created_at DESC";
|
|
631
|
-
return
|
|
527
|
+
return getPgDb3().query(query, params);
|
|
632
528
|
}
|
|
633
529
|
function getApprovalById(id) {
|
|
634
|
-
return
|
|
530
|
+
return getPgDb3().queryOne(FIND_BY_ID2, [id]);
|
|
635
531
|
}
|
|
636
532
|
function insertApproval(dataSourceId, sqlText, submittedBy) {
|
|
637
|
-
return
|
|
533
|
+
return getPgDb3().queryOne(CREATE2, [dataSourceId, sqlText, submittedBy]);
|
|
638
534
|
}
|
|
639
535
|
function updateReview(id, status, reviewedBy, rejectReason) {
|
|
640
|
-
return
|
|
536
|
+
return getPgDb3().queryOne(UPDATE_REVIEW(), [status, reviewedBy, rejectReason, id]);
|
|
641
537
|
}
|
|
642
538
|
function setExecuting(id) {
|
|
643
|
-
return
|
|
539
|
+
return getPgDb3().run(UPDATE_EXECUTING(), [id]);
|
|
644
540
|
}
|
|
645
541
|
function setExecuteResult(id, status, result) {
|
|
646
|
-
return
|
|
542
|
+
return getPgDb3().run(UPDATE_RESULT(), [status, result, id]);
|
|
647
543
|
}
|
|
648
544
|
|
|
649
545
|
// src/approvals/approvals.service.ts
|
|
@@ -781,7 +677,7 @@ async function buildApp() {
|
|
|
781
677
|
}
|
|
782
678
|
|
|
783
679
|
// src/migrate/runner.ts
|
|
784
|
-
import { getPgDb as
|
|
680
|
+
import { getPgDb as getPgDb4 } from "@heyhru/server-plugin-pg";
|
|
785
681
|
|
|
786
682
|
// src/migrate/migrations.ts
|
|
787
683
|
var migrations = [
|
|
@@ -873,7 +769,7 @@ CREATE INDEX IF NOT EXISTS idx_approvals_submitted_by ON approvals(submitted_by)
|
|
|
873
769
|
|
|
874
770
|
// src/migrate/runner.ts
|
|
875
771
|
async function runMigrations() {
|
|
876
|
-
const db =
|
|
772
|
+
const db = getPgDb4();
|
|
877
773
|
await db.exec(`CREATE TABLE IF NOT EXISTS _migrations (
|
|
878
774
|
name TEXT PRIMARY KEY,
|
|
879
775
|
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.2.0",
|
|
7
7
|
"description": "DMS backend API server built on Fastify",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./dist/index.mjs",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"dev": "tsx watch src/index.ts",
|
|
14
|
+
"dev": "tsx watch --env-file=.env src/index.ts",
|
|
15
15
|
"build": "tsup",
|
|
16
16
|
"lint": "eslint src",
|
|
17
17
|
"test": "vitest run --passWithNoTests",
|
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@fastify/cookie": "^11.0.2",
|
|
22
22
|
"@fastify/cors": "^11.0.0",
|
|
23
|
-
"@heyhru/
|
|
24
|
-
"@heyhru/
|
|
25
|
-
"@heyhru/server-plugin-
|
|
26
|
-
"@heyhru/server-plugin-
|
|
27
|
-
"@heyhru/server-
|
|
23
|
+
"@heyhru/business-dms-user": "0.2.0",
|
|
24
|
+
"@heyhru/common-util-logger": "0.2.0",
|
|
25
|
+
"@heyhru/server-plugin-jwt": "0.2.0",
|
|
26
|
+
"@heyhru/server-plugin-mysql": "0.2.0",
|
|
27
|
+
"@heyhru/server-plugin-pg": "0.2.0",
|
|
28
|
+
"@heyhru/server-util-crypto": "0.2.0",
|
|
28
29
|
"fastify": "^5.8.4",
|
|
29
30
|
"node-sql-parser": "^5.4.0"
|
|
30
31
|
},
|
|
@@ -36,5 +37,5 @@
|
|
|
36
37
|
"typescript": "^6.0.2",
|
|
37
38
|
"vitest": "^4.1.2"
|
|
38
39
|
},
|
|
39
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "52867b97f908359000f3b690daf2229921dcfd9a"
|
|
40
41
|
}
|