@pengzi/kms 1.1.0 → 1.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.
Files changed (73) hide show
  1. package/README.md +64 -5
  2. package/dist/cli/cli/kms.js +1050 -0
  3. package/dist/cli/kms.js +1050 -0
  4. package/dist/cli/src/client.js +254 -0
  5. package/dist/cli/src/core/asymmetric-crypto.js +170 -0
  6. package/dist/cli/src/core/crypto.js +99 -0
  7. package/dist/cli/src/core/crypto.service.js +66 -0
  8. package/dist/cli/src/core/key-derivation.js +95 -0
  9. package/dist/cli/src/index.js +50 -0
  10. package/dist/cli/src/models/audit.model.js +82 -0
  11. package/dist/cli/src/models/key.model.js +119 -0
  12. package/dist/cli/src/models/project.model.js +53 -0
  13. package/dist/cli/src/models/user.model.js +140 -0
  14. package/dist/cli/src/repositories/audit.repository.js +115 -0
  15. package/dist/cli/src/repositories/base.repository.js +94 -0
  16. package/dist/cli/src/repositories/key.repository.js +125 -0
  17. package/dist/cli/src/repositories/project.repository.js +81 -0
  18. package/dist/cli/src/repositories/user.repository.js +101 -0
  19. package/dist/cli/src/services/audit.service.js +111 -0
  20. package/dist/cli/src/services/auth.service.js +176 -0
  21. package/dist/cli/src/services/key.service.js +137 -0
  22. package/dist/cli/src/services/permission.service.js +142 -0
  23. package/dist/cli/src/services/project.service.js +102 -0
  24. package/dist/cli/src/types/audit.types.js +54 -0
  25. package/dist/cli/src/types/crypto.types.js +5 -0
  26. package/dist/cli/src/types/index.js +90 -0
  27. package/dist/cli/src/types/key.types.js +27 -0
  28. package/dist/cli/src/types/project.types.js +15 -0
  29. package/dist/cli/src/types/user.types.js +48 -0
  30. package/dist/cli/src/utils/config-loader.js +125 -0
  31. package/dist/cli/src/utils/constants.js +118 -0
  32. package/dist/cli/src/utils/error-handler.js +108 -0
  33. package/dist/client.d.ts.map +1 -1
  34. package/dist/client.js +19 -2
  35. package/dist/client.js.map +1 -1
  36. package/dist/models/key.model.js +1 -1
  37. package/dist/models/key.model.js.map +1 -1
  38. package/dist/services/key.service.d.ts +5 -0
  39. package/dist/services/key.service.d.ts.map +1 -1
  40. package/dist/services/key.service.js +12 -4
  41. package/dist/services/key.service.js.map +1 -1
  42. package/dist/src/client.js +269 -0
  43. package/dist/src/core/asymmetric-crypto.js +170 -0
  44. package/dist/src/core/crypto.js +99 -0
  45. package/dist/src/core/crypto.service.js +66 -0
  46. package/dist/src/core/key-derivation.js +95 -0
  47. package/dist/src/index.js +50 -0
  48. package/dist/src/models/audit.model.js +82 -0
  49. package/dist/src/models/key.model.js +119 -0
  50. package/dist/src/models/project.model.js +53 -0
  51. package/dist/src/models/user.model.js +140 -0
  52. package/dist/src/repositories/audit.repository.js +115 -0
  53. package/dist/src/repositories/base.repository.js +94 -0
  54. package/dist/src/repositories/key.repository.js +125 -0
  55. package/dist/src/repositories/project.repository.js +81 -0
  56. package/dist/src/repositories/user.repository.js +101 -0
  57. package/dist/src/services/audit.service.js +111 -0
  58. package/dist/src/services/auth.service.js +176 -0
  59. package/dist/src/services/key.service.js +137 -0
  60. package/dist/src/services/permission.service.js +142 -0
  61. package/dist/src/services/project.service.js +102 -0
  62. package/dist/src/types/audit.types.js +54 -0
  63. package/dist/src/types/crypto.types.js +5 -0
  64. package/dist/src/types/index.js +90 -0
  65. package/dist/src/types/key.types.js +27 -0
  66. package/dist/src/types/project.types.js +15 -0
  67. package/dist/src/types/user.types.js +48 -0
  68. package/dist/src/utils/config-loader.js +125 -0
  69. package/dist/src/utils/constants.js +118 -0
  70. package/dist/src/utils/error-handler.js +108 -0
  71. package/dist/types/client.types.d.ts +20 -0
  72. package/dist/types/client.types.d.ts.map +1 -1
  73. package/package.json +7 -2
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * KMS - 密钥管理系统
4
+ * 主入口文件
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.readPrivateKeyFile = exports.createClientFromEncryptedConfig = exports.loadConfigFromEnvironment = exports.loadEncryptedConfig = exports.getPrivateKeyPassphrase = exports.isValidPEMKey = exports.generateKeyId = exports.decryptConnectionString = exports.encryptConnectionString = exports.generateRSAKeyPair = exports.CryptoError = exports.ValidationError = exports.ForbiddenError = exports.AuthenticationError = exports.UserNotFoundError = exports.KeyNotFoundError = exports.ProjectNotFoundError = exports.KMSError = exports.KMSClient = void 0;
22
+ // 导出主类
23
+ var client_1 = require("./client");
24
+ Object.defineProperty(exports, "KMSClient", { enumerable: true, get: function () { return client_1.KMSClient; } });
25
+ // 导出所有类型
26
+ __exportStar(require("./types"), exports);
27
+ // 导出错误类
28
+ var types_1 = require("./types");
29
+ Object.defineProperty(exports, "KMSError", { enumerable: true, get: function () { return types_1.KMSError; } });
30
+ Object.defineProperty(exports, "ProjectNotFoundError", { enumerable: true, get: function () { return types_1.ProjectNotFoundError; } });
31
+ Object.defineProperty(exports, "KeyNotFoundError", { enumerable: true, get: function () { return types_1.KeyNotFoundError; } });
32
+ Object.defineProperty(exports, "UserNotFoundError", { enumerable: true, get: function () { return types_1.UserNotFoundError; } });
33
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return types_1.AuthenticationError; } });
34
+ Object.defineProperty(exports, "ForbiddenError", { enumerable: true, get: function () { return types_1.ForbiddenError; } });
35
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return types_1.ValidationError; } });
36
+ Object.defineProperty(exports, "CryptoError", { enumerable: true, get: function () { return types_1.CryptoError; } });
37
+ // 导出加密工具(用于连接字符串加密)
38
+ var asymmetric_crypto_1 = require("./core/asymmetric-crypto");
39
+ Object.defineProperty(exports, "generateRSAKeyPair", { enumerable: true, get: function () { return asymmetric_crypto_1.generateRSAKeyPair; } });
40
+ Object.defineProperty(exports, "encryptConnectionString", { enumerable: true, get: function () { return asymmetric_crypto_1.encryptConnectionString; } });
41
+ Object.defineProperty(exports, "decryptConnectionString", { enumerable: true, get: function () { return asymmetric_crypto_1.decryptConnectionString; } });
42
+ Object.defineProperty(exports, "generateKeyId", { enumerable: true, get: function () { return asymmetric_crypto_1.generateKeyId; } });
43
+ Object.defineProperty(exports, "isValidPEMKey", { enumerable: true, get: function () { return asymmetric_crypto_1.isValidPEMKey; } });
44
+ Object.defineProperty(exports, "getPrivateKeyPassphrase", { enumerable: true, get: function () { return asymmetric_crypto_1.getPrivateKeyPassphrase; } });
45
+ // 导出配置加载工具
46
+ var config_loader_1 = require("./utils/config-loader");
47
+ Object.defineProperty(exports, "loadEncryptedConfig", { enumerable: true, get: function () { return config_loader_1.loadEncryptedConfig; } });
48
+ Object.defineProperty(exports, "loadConfigFromEnvironment", { enumerable: true, get: function () { return config_loader_1.loadConfigFromEnvironment; } });
49
+ Object.defineProperty(exports, "createClientFromEncryptedConfig", { enumerable: true, get: function () { return config_loader_1.createClientFromEncryptedConfig; } });
50
+ Object.defineProperty(exports, "readPrivateKeyFile", { enumerable: true, get: function () { return config_loader_1.readPrivateKeyFile; } });
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * 审计日志数据模型
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAuditLog = createAuditLog;
7
+ exports.calculateSeverity = calculateSeverity;
8
+ exports.formatAuditDetails = formatAuditDetails;
9
+ const types_1 = require("../types");
10
+ const constants_1 = require("../utils/constants");
11
+ /**
12
+ * 创建审计日志
13
+ */
14
+ function createAuditLog(data) {
15
+ const timestamp = new Date();
16
+ return {
17
+ _id: (0, constants_1.generateId)('audit'),
18
+ projectId: data.projectId,
19
+ userId: data.userId,
20
+ action: data.action,
21
+ resourceType: data.resourceType,
22
+ resourceId: data.resourceId,
23
+ details: {
24
+ ...data.details,
25
+ },
26
+ timestamp,
27
+ severity: calculateSeverity(data.action, data.details.success),
28
+ };
29
+ }
30
+ /**
31
+ * 计算日志严重级别
32
+ */
33
+ function calculateSeverity(action, success) {
34
+ if (!success) {
35
+ const criticalActions = [
36
+ types_1.AuditAction.DELETE_PROJECT,
37
+ types_1.AuditAction.DELETE_KEY,
38
+ types_1.AuditAction.LOGIN_FAILED,
39
+ ];
40
+ const warningActions = [
41
+ types_1.AuditAction.UPDATE_KEY,
42
+ types_1.AuditAction.UPDATE_PROJECT,
43
+ types_1.AuditAction.PERMISSION_DENIED,
44
+ ];
45
+ if (criticalActions.includes(action)) {
46
+ return types_1.AuditSeverity.CRITICAL;
47
+ }
48
+ if (warningActions.includes(action)) {
49
+ return types_1.AuditSeverity.WARNING;
50
+ }
51
+ return types_1.AuditSeverity.ERROR;
52
+ }
53
+ // 成功的操作
54
+ const criticalActions = [
55
+ types_1.AuditAction.DELETE_PROJECT,
56
+ types_1.AuditAction.DELETE_KEY,
57
+ types_1.AuditAction.DELETE_USER,
58
+ ];
59
+ if (criticalActions.includes(action)) {
60
+ return types_1.AuditSeverity.CRITICAL;
61
+ }
62
+ return types_1.AuditSeverity.INFO;
63
+ }
64
+ /**
65
+ * 格式化审计日志详情
66
+ */
67
+ function formatAuditDetails(details) {
68
+ const parts = [];
69
+ if (details.keyName) {
70
+ parts.push(`Key: ${details.keyName}`);
71
+ }
72
+ if (details.keyType) {
73
+ parts.push(`Type: ${details.keyType}`);
74
+ }
75
+ if (details.ipAddress) {
76
+ parts.push(`IP: ${details.ipAddress}`);
77
+ }
78
+ if (!details.success && details.errorMessage) {
79
+ parts.push(`Error: ${details.errorMessage}`);
80
+ }
81
+ return parts.join(' | ');
82
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /**
3
+ * 密钥数据模型
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createKey = createKey;
7
+ exports.validateKey = validateKey;
8
+ exports.updateKey = updateKey;
9
+ exports.toKeyValue = toKeyValue;
10
+ exports.isKeyExpired = isKeyExpired;
11
+ exports.isKeyAccessible = isKeyAccessible;
12
+ const types_1 = require("../types");
13
+ const constants_1 = require("../utils/constants");
14
+ /**
15
+ * 创建新密钥
16
+ */
17
+ function createKey(projectId, keyData, encryptedData, createdBy) {
18
+ const now = new Date();
19
+ return {
20
+ keyId: (0, constants_1.generateId)('key'),
21
+ projectId,
22
+ keyName: keyData.keyName,
23
+ keyType: keyData.keyType,
24
+ encryptedValue: encryptedData.encrypted,
25
+ iv: encryptedData.iv,
26
+ authTag: encryptedData.authTag,
27
+ version: 1,
28
+ tags: keyData.tags || [],
29
+ description: keyData.description,
30
+ createdBy,
31
+ createdAt: now,
32
+ updatedAt: now,
33
+ expiresAt: keyData.expiresAt,
34
+ status: types_1.KeyStatus.ACTIVE,
35
+ };
36
+ }
37
+ /**
38
+ * 验证密钥数据
39
+ */
40
+ function validateKey(keyData) {
41
+ const errors = [];
42
+ if (!keyData.keyName || keyData.keyName.trim().length === 0) {
43
+ errors.push('Key name is required');
44
+ }
45
+ if (keyData.keyName && keyData.keyName.length > 100) {
46
+ errors.push('Key name must be less than 100 characters');
47
+ }
48
+ if (!keyData.keyType) {
49
+ errors.push('Key type is required');
50
+ }
51
+ if (!keyData.value || keyData.value.trim().length === 0) {
52
+ errors.push('Key value is required');
53
+ }
54
+ if (keyData.value && keyData.value.length > 2000) {
55
+ errors.push('Key value must be less than 2000 characters');
56
+ }
57
+ if (keyData.expiresAt && keyData.expiresAt < new Date()) {
58
+ errors.push('Expiration date must be in the future');
59
+ }
60
+ return {
61
+ valid: errors.length === 0,
62
+ errors,
63
+ };
64
+ }
65
+ /**
66
+ * 更新密钥
67
+ */
68
+ function updateKey(key, updates, newEncryptedData) {
69
+ const updatedKey = { ...key };
70
+ if (newEncryptedData) {
71
+ updatedKey.encryptedValue = newEncryptedData.encrypted;
72
+ updatedKey.iv = newEncryptedData.iv;
73
+ updatedKey.authTag = newEncryptedData.authTag;
74
+ updatedKey.version += 1;
75
+ updatedKey.lastRotatedAt = new Date();
76
+ }
77
+ if (updates.tags !== undefined) {
78
+ updatedKey.tags = updates.tags;
79
+ }
80
+ if (updates.description !== undefined) {
81
+ updatedKey.description = updates.description;
82
+ }
83
+ if (updates.expiresAt !== undefined) {
84
+ updatedKey.expiresAt = updates.expiresAt;
85
+ }
86
+ if (updates.status !== undefined) {
87
+ updatedKey.status = updates.status;
88
+ }
89
+ updatedKey.updatedAt = new Date();
90
+ return updatedKey;
91
+ }
92
+ /**
93
+ * 转换密钥为KeyValue(包含解密值)
94
+ */
95
+ function toKeyValue(key, decryptedValue) {
96
+ const { encryptedValue, iv, authTag, ...keyValue } = key;
97
+ return {
98
+ ...keyValue,
99
+ value: decryptedValue,
100
+ };
101
+ }
102
+ /**
103
+ * 检查密钥是否已过期
104
+ */
105
+ function isKeyExpired(key) {
106
+ return key.expiresAt !== undefined && key.expiresAt < new Date();
107
+ }
108
+ /**
109
+ * 检查密钥是否可用
110
+ */
111
+ function isKeyAccessible(key) {
112
+ if (key.status !== types_1.KeyStatus.ACTIVE) {
113
+ return false;
114
+ }
115
+ if (isKeyExpired(key)) {
116
+ return false;
117
+ }
118
+ return true;
119
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * 项目数据模型
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createProject = createProject;
7
+ exports.validateProject = validateProject;
8
+ exports.toSafeProject = toSafeProject;
9
+ const types_1 = require("../types");
10
+ const constants_1 = require("../utils/constants");
11
+ /**
12
+ * 创建新项目
13
+ */
14
+ function createProject(options, masterKeyEncrypted, masterKeyHash, salt) {
15
+ const now = new Date();
16
+ return {
17
+ projectId: (0, constants_1.generateId)('proj'),
18
+ projectName: options.projectName,
19
+ masterKeyHash,
20
+ masterKeyEncrypted,
21
+ salt,
22
+ createdAt: now,
23
+ updatedAt: now,
24
+ status: types_1.ProjectStatus.ACTIVE,
25
+ metadata: options.metadata,
26
+ };
27
+ }
28
+ /**
29
+ * 验证项目数据
30
+ */
31
+ function validateProject(project) {
32
+ const errors = [];
33
+ if (!project.projectName || project.projectName.trim().length === 0) {
34
+ errors.push('Project name is required');
35
+ }
36
+ if (project.projectName && project.projectName.length > 100) {
37
+ errors.push('Project name must be less than 100 characters');
38
+ }
39
+ if (!project.projectId || project.projectId.trim().length === 0) {
40
+ errors.push('Project ID is required');
41
+ }
42
+ return {
43
+ valid: errors.length === 0,
44
+ errors,
45
+ };
46
+ }
47
+ /**
48
+ * 转换项目为安全格式(不包含敏感信息)
49
+ */
50
+ function toSafeProject(project) {
51
+ const { masterKeyHash, masterKeyEncrypted, salt, ...safeProject } = project;
52
+ return safeProject;
53
+ }
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * 用户数据模型
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createUser = createUser;
7
+ exports.validateUser = validateUser;
8
+ exports.updateLastLogin = updateLastLogin;
9
+ exports.lockUser = lockUser;
10
+ exports.activateUser = activateUser;
11
+ exports.addRole = addRole;
12
+ exports.removeRole = removeRole;
13
+ exports.addPermission = addPermission;
14
+ exports.removePermission = removePermission;
15
+ exports.toSafeUser = toSafeUser;
16
+ const types_1 = require("../types");
17
+ const constants_1 = require("../utils/constants");
18
+ /**
19
+ * 创建新用户
20
+ */
21
+ function createUser(projectId, userData, passwordHash, apiKeyHash) {
22
+ const now = new Date();
23
+ return {
24
+ userId: (0, constants_1.generateId)('user'),
25
+ projectId,
26
+ username: userData.username,
27
+ passwordHash,
28
+ roles: userData.roles || [],
29
+ permissions: userData.permissions || [],
30
+ apiKeyHash,
31
+ createdAt: now,
32
+ updatedAt: now,
33
+ status: types_1.UserStatus.ACTIVE,
34
+ };
35
+ }
36
+ /**
37
+ * 验证用户数据
38
+ */
39
+ function validateUser(userData) {
40
+ const errors = [];
41
+ if (!userData.username || userData.username.trim().length === 0) {
42
+ errors.push('Username is required');
43
+ }
44
+ if (userData.username && (userData.username.length < 3 || userData.username.length > 50)) {
45
+ errors.push('Username must be between 3 and 50 characters');
46
+ }
47
+ if (!userData.password || userData.password.length === 0) {
48
+ errors.push('Password is required');
49
+ }
50
+ if (userData.roles && userData.roles.length === 0) {
51
+ errors.push('At least one role is required');
52
+ }
53
+ return {
54
+ valid: errors.length === 0,
55
+ errors,
56
+ };
57
+ }
58
+ /**
59
+ * 更新用户最后登录时间
60
+ */
61
+ function updateLastLogin(user) {
62
+ return {
63
+ ...user,
64
+ lastLoginAt: new Date(),
65
+ updatedAt: new Date(),
66
+ };
67
+ }
68
+ /**
69
+ * 锁定用户
70
+ */
71
+ function lockUser(user) {
72
+ return {
73
+ ...user,
74
+ status: types_1.UserStatus.LOCKED,
75
+ updatedAt: new Date(),
76
+ };
77
+ }
78
+ /**
79
+ * 激活用户
80
+ */
81
+ function activateUser(user) {
82
+ return {
83
+ ...user,
84
+ status: types_1.UserStatus.ACTIVE,
85
+ updatedAt: new Date(),
86
+ };
87
+ }
88
+ /**
89
+ * 添加角色
90
+ */
91
+ function addRole(user, role) {
92
+ if (user.roles.includes(role)) {
93
+ return user;
94
+ }
95
+ return {
96
+ ...user,
97
+ roles: [...user.roles, role],
98
+ updatedAt: new Date(),
99
+ };
100
+ }
101
+ /**
102
+ * 移除角色
103
+ */
104
+ function removeRole(user, role) {
105
+ return {
106
+ ...user,
107
+ roles: user.roles.filter((r) => r !== role),
108
+ updatedAt: new Date(),
109
+ };
110
+ }
111
+ /**
112
+ * 添加权限
113
+ */
114
+ function addPermission(user, permission) {
115
+ if (user.permissions.includes(permission)) {
116
+ return user;
117
+ }
118
+ return {
119
+ ...user,
120
+ permissions: [...user.permissions, permission],
121
+ updatedAt: new Date(),
122
+ };
123
+ }
124
+ /**
125
+ * 移除权限
126
+ */
127
+ function removePermission(user, permission) {
128
+ return {
129
+ ...user,
130
+ permissions: user.permissions.filter((p) => p !== permission),
131
+ updatedAt: new Date(),
132
+ };
133
+ }
134
+ /**
135
+ * 转换用户为安全格式(不包含敏感信息)
136
+ */
137
+ function toSafeUser(user) {
138
+ const { passwordHash, apiKeyHash, ...safeUser } = user;
139
+ return safeUser;
140
+ }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * 审计日志仓储
4
+ * 负责审计日志的数据访问
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.AuditRepository = void 0;
8
+ const base_repository_1 = require("./base.repository");
9
+ const types_1 = require("../types");
10
+ class AuditRepository extends base_repository_1.BaseRepository {
11
+ constructor(db) {
12
+ super(db, 'audit_logs');
13
+ this.initializeIndexes();
14
+ }
15
+ /**
16
+ * 初始化索引
17
+ */
18
+ async initializeIndexes() {
19
+ await this.createIndexes([
20
+ { projectId: 1 },
21
+ { userId: 1 },
22
+ { action: 1 },
23
+ { resourceType: 1 },
24
+ { resourceId: 1 },
25
+ { timestamp: -1 },
26
+ { severity: 1 },
27
+ { projectId: 1, timestamp: -1 },
28
+ { userId: 1, timestamp: -1 },
29
+ ]);
30
+ }
31
+ /**
32
+ * 查询审计日志
33
+ */
34
+ async findAuditLogs(projectId, query) {
35
+ const filter = { projectId };
36
+ if (query.startDate) {
37
+ filter.timestamp = { ...filter.timestamp, $gte: query.startDate };
38
+ }
39
+ if (query.endDate) {
40
+ filter.timestamp = { ...filter.timestamp, $lte: query.endDate };
41
+ }
42
+ if (query.action) {
43
+ filter.action = query.action;
44
+ }
45
+ if (query.resourceType) {
46
+ filter.resourceType = query.resourceType;
47
+ }
48
+ if (query.userId) {
49
+ filter.userId = query.userId;
50
+ }
51
+ if (query.severity) {
52
+ filter.severity = query.severity;
53
+ }
54
+ if (query.success !== undefined) {
55
+ filter['details.success'] = query.success;
56
+ }
57
+ const total = await this.count(filter);
58
+ const page = query.page || 1;
59
+ const limit = query.limit || 50;
60
+ const skip = (page - 1) * limit;
61
+ const logs = await this.findMany(filter, {
62
+ sort: { timestamp: -1 },
63
+ skip,
64
+ limit,
65
+ });
66
+ return { logs, total };
67
+ }
68
+ /**
69
+ * 查询最近的审计日志
70
+ */
71
+ async findRecentLogs(projectId, limit = 100) {
72
+ return await this.findMany({ projectId }, { sort: { timestamp: -1 }, limit });
73
+ }
74
+ /**
75
+ * 统计特定操作的次数
76
+ */
77
+ async countByAction(projectId, action, startDate, endDate) {
78
+ const filter = { projectId, action };
79
+ if (startDate || endDate) {
80
+ filter.timestamp = {};
81
+ if (startDate)
82
+ filter.timestamp.$gte = startDate;
83
+ if (endDate)
84
+ filter.timestamp.$lte = endDate;
85
+ }
86
+ return await this.count(filter);
87
+ }
88
+ /**
89
+ * 统计失败的登录尝试
90
+ */
91
+ async countFailedLogins(projectId, userId, since) {
92
+ const filter = {
93
+ projectId,
94
+ action: types_1.AuditAction.LOGIN_FAILED,
95
+ };
96
+ if (userId) {
97
+ filter.userId = userId;
98
+ }
99
+ if (since) {
100
+ filter.timestamp = { $gte: since };
101
+ }
102
+ return await this.count(filter);
103
+ }
104
+ /**
105
+ * 删除旧日志(用于归档)
106
+ */
107
+ async deleteOldLogs(beforeDate) {
108
+ const collection = this.getCollection();
109
+ const result = await collection.deleteMany({
110
+ timestamp: { $lt: beforeDate },
111
+ });
112
+ return result.deletedCount;
113
+ }
114
+ }
115
+ exports.AuditRepository = AuditRepository;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * 基础仓储类
4
+ * 提供通用的数据库操作
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BaseRepository = void 0;
8
+ /**
9
+ * 基础仓储类
10
+ */
11
+ class BaseRepository {
12
+ constructor(db, collectionName) {
13
+ this.db = db;
14
+ this.collectionName = collectionName;
15
+ }
16
+ /**
17
+ * 获取集合
18
+ */
19
+ getCollection() {
20
+ return this.db.collection(this.collectionName);
21
+ }
22
+ /**
23
+ * 创建索引
24
+ */
25
+ async createIndexes(indexes) {
26
+ const collection = this.getCollection();
27
+ for (const index of indexes) {
28
+ await collection.createIndex(index);
29
+ }
30
+ }
31
+ /**
32
+ * 插入单个文档
33
+ */
34
+ async insertOne(document) {
35
+ const collection = this.getCollection();
36
+ const result = await collection.insertOne(document);
37
+ return { ...document, _id: result.insertedId.toString() };
38
+ }
39
+ /**
40
+ * 查询单个文档
41
+ */
42
+ async findOne(filter) {
43
+ const collection = this.getCollection();
44
+ return await collection.findOne(filter);
45
+ }
46
+ /**
47
+ * 查询多个文档
48
+ */
49
+ async findMany(filter = {}, options) {
50
+ const collection = this.getCollection();
51
+ let query = collection.find(filter);
52
+ if (options?.sort) {
53
+ query = query.sort(options.sort);
54
+ }
55
+ if (options?.skip) {
56
+ query = query.skip(options.skip);
57
+ }
58
+ if (options?.limit) {
59
+ query = query.limit(options.limit);
60
+ }
61
+ return await query.toArray();
62
+ }
63
+ /**
64
+ * 更新单个文档
65
+ */
66
+ async updateOne(filter, update) {
67
+ const collection = this.getCollection();
68
+ const result = await collection.updateOne(filter, update);
69
+ return result.modifiedCount > 0;
70
+ }
71
+ /**
72
+ * 删除单个文档
73
+ */
74
+ async deleteOne(filter) {
75
+ const collection = this.getCollection();
76
+ const result = await collection.deleteOne(filter);
77
+ return result.deletedCount > 0;
78
+ }
79
+ /**
80
+ * 统计文档数量
81
+ */
82
+ async count(filter = {}) {
83
+ const collection = this.getCollection();
84
+ return await collection.countDocuments(filter);
85
+ }
86
+ /**
87
+ * 检查文档是否存在
88
+ */
89
+ async exists(filter) {
90
+ const count = await this.count(filter);
91
+ return count > 0;
92
+ }
93
+ }
94
+ exports.BaseRepository = BaseRepository;