@downcity/agent 1.1.7 → 1.1.8

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 (274) hide show
  1. package/bin/agent/AgentContext.d.ts.map +1 -1
  2. package/bin/agent/AgentContext.js +1 -0
  3. package/bin/agent/AgentContext.js.map +1 -1
  4. package/bin/agent/AgentContextTypes.d.ts +5 -1
  5. package/bin/agent/AgentContextTypes.d.ts.map +1 -1
  6. package/bin/agent/AgentRuntime.d.ts +6 -1
  7. package/bin/agent/AgentRuntime.d.ts.map +1 -1
  8. package/bin/agent/AgentRuntime.js +22 -3
  9. package/bin/agent/AgentRuntime.js.map +1 -1
  10. package/bin/agent/AgentRuntimeState.d.ts.map +1 -1
  11. package/bin/agent/AgentRuntimeState.js +58 -2
  12. package/bin/agent/AgentRuntimeState.js.map +1 -1
  13. package/bin/agent/AgentRuntimeTypes.d.ts +5 -1
  14. package/bin/agent/AgentRuntimeTypes.d.ts.map +1 -1
  15. package/bin/agent/project/AgentInitializer.d.ts +3 -2
  16. package/bin/agent/project/AgentInitializer.d.ts.map +1 -1
  17. package/bin/agent/project/AgentInitializer.js +34 -44
  18. package/bin/agent/project/AgentInitializer.js.map +1 -1
  19. package/bin/config/Config.d.ts.map +1 -1
  20. package/bin/config/Config.js +2 -21
  21. package/bin/config/Config.js.map +1 -1
  22. package/bin/config/Paths.d.ts +1 -5
  23. package/bin/config/Paths.d.ts.map +1 -1
  24. package/bin/config/Paths.js +2 -8
  25. package/bin/config/Paths.js.map +1 -1
  26. package/bin/host/daemon/ProjectSetup.d.ts +2 -1
  27. package/bin/host/daemon/ProjectSetup.d.ts.map +1 -1
  28. package/bin/host/daemon/ProjectSetup.js +14 -21
  29. package/bin/host/daemon/ProjectSetup.js.map +1 -1
  30. package/bin/host/runtime/AgentHostRuntime.d.ts.map +1 -1
  31. package/bin/host/runtime/AgentHostRuntime.js +1 -2
  32. package/bin/host/runtime/AgentHostRuntime.js.map +1 -1
  33. package/bin/host/runtime/CityPaths.d.ts +0 -3
  34. package/bin/host/runtime/CityPaths.d.ts.map +1 -1
  35. package/bin/host/runtime/CityPaths.js +0 -3
  36. package/bin/host/runtime/CityPaths.js.map +1 -1
  37. package/bin/host/sdk/Agent.d.ts +1 -0
  38. package/bin/host/sdk/Agent.d.ts.map +1 -1
  39. package/bin/host/sdk/Agent.js +24 -2
  40. package/bin/host/sdk/Agent.js.map +1 -1
  41. package/bin/host/sdk/AgentSdkTypes.d.ts +9 -0
  42. package/bin/host/sdk/AgentSdkTypes.d.ts.map +1 -1
  43. package/bin/http/Server.d.ts.map +1 -1
  44. package/bin/http/Server.js +1 -11
  45. package/bin/http/Server.js.map +1 -1
  46. package/bin/http/auth/AuthEnv.d.ts +0 -9
  47. package/bin/http/auth/AuthEnv.d.ts.map +1 -1
  48. package/bin/http/auth/AuthEnv.js +0 -9
  49. package/bin/http/auth/AuthEnv.js.map +1 -1
  50. package/bin/http/auth/CliAuthStateStore.d.ts +0 -4
  51. package/bin/http/auth/CliAuthStateStore.d.ts.map +1 -1
  52. package/bin/http/auth/CliAuthStateStore.js +0 -4
  53. package/bin/http/auth/CliAuthStateStore.js.map +1 -1
  54. package/bin/http/control/ModelRoutes.d.ts.map +1 -1
  55. package/bin/http/control/ModelRoutes.js +3 -8
  56. package/bin/http/control/ModelRoutes.js.map +1 -1
  57. package/bin/index.d.ts +2 -6
  58. package/bin/index.d.ts.map +1 -1
  59. package/bin/index.js +2 -6
  60. package/bin/index.js.map +1 -1
  61. package/bin/model/CreateModel.d.ts +2 -2
  62. package/bin/model/CreateModel.d.ts.map +1 -1
  63. package/bin/model/CreateModel.js +13 -12
  64. package/bin/model/CreateModel.js.map +1 -1
  65. package/bin/plugin/Activation.d.ts +4 -0
  66. package/bin/plugin/Activation.d.ts.map +1 -1
  67. package/bin/plugin/Activation.js +2 -2
  68. package/bin/plugin/Activation.js.map +1 -1
  69. package/bin/plugin/LocalExecution.d.ts.map +1 -1
  70. package/bin/plugin/LocalExecution.js +23 -2
  71. package/bin/plugin/LocalExecution.js.map +1 -1
  72. package/bin/plugin/PluginRegistry.js +2 -2
  73. package/bin/plugin/PluginRegistry.js.map +1 -1
  74. package/bin/plugins/asr/Plugin.d.ts.map +1 -1
  75. package/bin/plugins/asr/Plugin.js +4 -5
  76. package/bin/plugins/asr/Plugin.js.map +1 -1
  77. package/bin/plugins/auth/Plugin.d.ts.map +1 -1
  78. package/bin/plugins/auth/Plugin.js +1 -0
  79. package/bin/plugins/auth/Plugin.js.map +1 -1
  80. package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts +4 -4
  81. package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts.map +1 -1
  82. package/bin/plugins/auth/runtime/AuthorizationConfig.js +28 -26
  83. package/bin/plugins/auth/runtime/AuthorizationConfig.js.map +1 -1
  84. package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts +2 -0
  85. package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts.map +1 -1
  86. package/bin/plugins/auth/runtime/AuthorizationPolicy.js +3 -2
  87. package/bin/plugins/auth/runtime/AuthorizationPolicy.js.map +1 -1
  88. package/bin/plugins/auth/runtime/AuthorizationStore.d.ts +1 -1
  89. package/bin/plugins/auth/runtime/AuthorizationStore.d.ts.map +1 -1
  90. package/bin/plugins/auth/runtime/AuthorizationStore.js +3 -4
  91. package/bin/plugins/auth/runtime/AuthorizationStore.js.map +1 -1
  92. package/bin/plugins/skill/Plugin.js +2 -2
  93. package/bin/plugins/skill/Plugin.js.map +1 -1
  94. package/bin/plugins/tts/Plugin.d.ts.map +1 -1
  95. package/bin/plugins/tts/Plugin.js +4 -5
  96. package/bin/plugins/tts/Plugin.js.map +1 -1
  97. package/bin/plugins/web/Plugin.d.ts.map +1 -1
  98. package/bin/plugins/web/Plugin.js +4 -5
  99. package/bin/plugins/web/Plugin.js.map +1 -1
  100. package/bin/plugins/workboard/Plugin.js +2 -2
  101. package/bin/plugins/workboard/Plugin.js.map +1 -1
  102. package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts +4 -1
  103. package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts.map +1 -1
  104. package/bin/service/builtins/chat/accounts/ChannelAccountService.js +64 -91
  105. package/bin/service/builtins/chat/accounts/ChannelAccountService.js.map +1 -1
  106. package/bin/service/builtins/chat/runtime/ChatChannelActions.d.ts.map +1 -1
  107. package/bin/service/builtins/chat/runtime/ChatChannelActions.js +11 -18
  108. package/bin/service/builtins/chat/runtime/ChatChannelActions.js.map +1 -1
  109. package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts +1 -1
  110. package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts.map +1 -1
  111. package/bin/service/builtins/chat/runtime/ChatChannelCore.js +9 -17
  112. package/bin/service/builtins/chat/runtime/ChatChannelCore.js.map +1 -1
  113. package/bin/service/builtins/memory/Action.d.ts +1 -5
  114. package/bin/service/builtins/memory/Action.d.ts.map +1 -1
  115. package/bin/service/builtins/memory/Action.js +4 -42
  116. package/bin/service/builtins/memory/Action.js.map +1 -1
  117. package/bin/service/builtins/memory/MemoryService.d.ts.map +1 -1
  118. package/bin/service/builtins/memory/MemoryService.js +2 -32
  119. package/bin/service/builtins/memory/MemoryService.js.map +1 -1
  120. package/bin/service/builtins/memory/runtime/Search.d.ts +7 -3
  121. package/bin/service/builtins/memory/runtime/Search.d.ts.map +1 -1
  122. package/bin/service/builtins/memory/runtime/Search.js +220 -16
  123. package/bin/service/builtins/memory/runtime/Search.js.map +1 -1
  124. package/bin/service/builtins/memory/runtime/Store.d.ts +9 -50
  125. package/bin/service/builtins/memory/runtime/Store.d.ts.map +1 -1
  126. package/bin/service/builtins/memory/runtime/Store.js +10 -130
  127. package/bin/service/builtins/memory/runtime/Store.js.map +1 -1
  128. package/bin/service/builtins/memory/runtime/Writer.d.ts.map +1 -1
  129. package/bin/service/builtins/memory/runtime/Writer.js +1 -2
  130. package/bin/service/builtins/memory/runtime/Writer.js.map +1 -1
  131. package/bin/service/builtins/memory/types/Memory.d.ts +3 -57
  132. package/bin/service/builtins/memory/types/Memory.d.ts.map +1 -1
  133. package/bin/service/schedule/Store.d.ts +22 -25
  134. package/bin/service/schedule/Store.d.ts.map +1 -1
  135. package/bin/service/schedule/Store.js +172 -154
  136. package/bin/service/schedule/Store.js.map +1 -1
  137. package/bin/session/composer/system/default/SystemDomain.d.ts.map +1 -1
  138. package/bin/session/composer/system/default/SystemDomain.js +1 -0
  139. package/bin/session/composer/system/default/SystemDomain.js.map +1 -1
  140. package/bin/shared/types/AgentHost.d.ts +120 -4
  141. package/bin/shared/types/AgentHost.d.ts.map +1 -1
  142. package/bin/shared/types/Plugin.d.ts +5 -1
  143. package/bin/shared/types/Plugin.d.ts.map +1 -1
  144. package/package.json +1 -4
  145. package/src/agent/AgentContext.ts +1 -0
  146. package/src/agent/AgentContextTypes.ts +5 -0
  147. package/src/agent/AgentRuntime.ts +32 -3
  148. package/src/agent/AgentRuntimeState.ts +66 -2
  149. package/src/agent/AgentRuntimeTypes.ts +5 -0
  150. package/src/agent/project/AgentInitializer.ts +40 -42
  151. package/src/config/Config.ts +2 -17
  152. package/src/config/Paths.ts +2 -9
  153. package/src/host/daemon/ProjectSetup.ts +19 -21
  154. package/src/host/runtime/AgentHostRuntime.ts +0 -2
  155. package/src/host/runtime/CityPaths.ts +0 -3
  156. package/src/host/sdk/Agent.ts +26 -2
  157. package/src/host/sdk/AgentSdkTypes.ts +10 -0
  158. package/src/http/Server.ts +0 -13
  159. package/src/http/auth/AuthEnv.ts +0 -9
  160. package/src/http/auth/CliAuthStateStore.ts +0 -4
  161. package/src/http/control/ModelRoutes.ts +3 -9
  162. package/src/index.ts +2 -12
  163. package/src/model/CreateModel.ts +15 -13
  164. package/src/plugin/Activation.ts +6 -2
  165. package/src/plugin/LocalExecution.ts +24 -2
  166. package/src/plugin/PluginRegistry.ts +2 -2
  167. package/src/plugins/asr/Plugin.ts +4 -5
  168. package/src/plugins/auth/Plugin.ts +1 -0
  169. package/src/plugins/auth/runtime/AuthorizationConfig.ts +47 -37
  170. package/src/plugins/auth/runtime/AuthorizationPolicy.ts +5 -2
  171. package/src/plugins/auth/runtime/AuthorizationStore.ts +6 -5
  172. package/src/plugins/skill/Plugin.ts +2 -2
  173. package/src/plugins/tts/Plugin.ts +4 -5
  174. package/src/plugins/web/Plugin.ts +4 -5
  175. package/src/plugins/workboard/Plugin.ts +2 -2
  176. package/src/service/builtins/chat/accounts/ChannelAccountService.ts +42 -62
  177. package/src/service/builtins/chat/runtime/ChatChannelActions.ts +12 -18
  178. package/src/service/builtins/chat/runtime/ChatChannelCore.ts +9 -14
  179. package/src/service/builtins/memory/Action.ts +6 -47
  180. package/src/service/builtins/memory/MemoryService.ts +1 -33
  181. package/src/service/builtins/memory/runtime/Search.ts +256 -16
  182. package/src/service/builtins/memory/runtime/Store.ts +13 -185
  183. package/src/service/builtins/memory/runtime/Writer.ts +1 -2
  184. package/src/service/builtins/memory/types/Memory.ts +2 -59
  185. package/src/service/schedule/Store.ts +215 -175
  186. package/src/session/composer/system/default/SystemDomain.ts +1 -0
  187. package/src/shared/types/AgentHost.ts +138 -4
  188. package/src/shared/types/Plugin.ts +5 -0
  189. package/tsconfig.tsbuildinfo +1 -1
  190. package/bin/http/auth/AuthMiddleware.d.ts +0 -36
  191. package/bin/http/auth/AuthMiddleware.d.ts.map +0 -1
  192. package/bin/http/auth/AuthMiddleware.js +0 -37
  193. package/bin/http/auth/AuthMiddleware.js.map +0 -1
  194. package/bin/http/auth/AuthRoutes.d.ts +0 -17
  195. package/bin/http/auth/AuthRoutes.d.ts.map +0 -1
  196. package/bin/http/auth/AuthRoutes.js +0 -78
  197. package/bin/http/auth/AuthRoutes.js.map +0 -1
  198. package/bin/http/auth/AuthService.d.ts +0 -119
  199. package/bin/http/auth/AuthService.d.ts.map +0 -1
  200. package/bin/http/auth/AuthService.js +0 -307
  201. package/bin/http/auth/AuthService.js.map +0 -1
  202. package/bin/http/auth/AuthStore.d.ts +0 -165
  203. package/bin/http/auth/AuthStore.d.ts.map +0 -1
  204. package/bin/http/auth/AuthStore.js +0 -442
  205. package/bin/http/auth/AuthStore.js.map +0 -1
  206. package/bin/http/auth/RoutePolicy.d.ts +0 -30
  207. package/bin/http/auth/RoutePolicy.d.ts.map +0 -1
  208. package/bin/http/auth/RoutePolicy.js +0 -229
  209. package/bin/http/auth/RoutePolicy.js.map +0 -1
  210. package/bin/plugin/Lifecycle.d.ts +0 -33
  211. package/bin/plugin/Lifecycle.d.ts.map +0 -1
  212. package/bin/plugin/Lifecycle.js +0 -102
  213. package/bin/plugin/Lifecycle.js.map +0 -1
  214. package/bin/service/builtins/memory/runtime/Indexer.d.ts +0 -71
  215. package/bin/service/builtins/memory/runtime/Indexer.d.ts.map +0 -1
  216. package/bin/service/builtins/memory/runtime/Indexer.js +0 -345
  217. package/bin/service/builtins/memory/runtime/Indexer.js.map +0 -1
  218. package/bin/service/schedule/Schema.d.ts +0 -171
  219. package/bin/service/schedule/Schema.d.ts.map +0 -1
  220. package/bin/service/schedule/Schema.js +0 -26
  221. package/bin/service/schedule/Schema.js.map +0 -1
  222. package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts +0 -34
  223. package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts.map +0 -1
  224. package/bin/shared/utils/store/StoreChannelAccountRepository.js +0 -198
  225. package/bin/shared/utils/store/StoreChannelAccountRepository.js.map +0 -1
  226. package/bin/shared/utils/store/StoreEnvRepository.d.ts +0 -98
  227. package/bin/shared/utils/store/StoreEnvRepository.d.ts.map +0 -1
  228. package/bin/shared/utils/store/StoreEnvRepository.js +0 -334
  229. package/bin/shared/utils/store/StoreEnvRepository.js.map +0 -1
  230. package/bin/shared/utils/store/StoreModelRepository.d.ts +0 -61
  231. package/bin/shared/utils/store/StoreModelRepository.d.ts.map +0 -1
  232. package/bin/shared/utils/store/StoreModelRepository.js +0 -278
  233. package/bin/shared/utils/store/StoreModelRepository.js.map +0 -1
  234. package/bin/shared/utils/store/StoreSchema.d.ts +0 -13
  235. package/bin/shared/utils/store/StoreSchema.d.ts.map +0 -1
  236. package/bin/shared/utils/store/StoreSchema.js +0 -319
  237. package/bin/shared/utils/store/StoreSchema.js.map +0 -1
  238. package/bin/shared/utils/store/StoreSecureSettings.d.ts +0 -33
  239. package/bin/shared/utils/store/StoreSecureSettings.d.ts.map +0 -1
  240. package/bin/shared/utils/store/StoreSecureSettings.js +0 -91
  241. package/bin/shared/utils/store/StoreSecureSettings.js.map +0 -1
  242. package/bin/shared/utils/store/StoreShared.d.ts +0 -44
  243. package/bin/shared/utils/store/StoreShared.d.ts.map +0 -1
  244. package/bin/shared/utils/store/StoreShared.js +0 -40
  245. package/bin/shared/utils/store/StoreShared.js.map +0 -1
  246. package/bin/shared/utils/store/crypto.d.ts +0 -24
  247. package/bin/shared/utils/store/crypto.d.ts.map +0 -1
  248. package/bin/shared/utils/store/crypto.js +0 -101
  249. package/bin/shared/utils/store/crypto.js.map +0 -1
  250. package/bin/shared/utils/store/index.d.ts +0 -230
  251. package/bin/shared/utils/store/index.d.ts.map +0 -1
  252. package/bin/shared/utils/store/index.js +0 -360
  253. package/bin/shared/utils/store/index.js.map +0 -1
  254. package/bin/shared/utils/store/schema.d.ts +0 -690
  255. package/bin/shared/utils/store/schema.d.ts.map +0 -1
  256. package/bin/shared/utils/store/schema.js +0 -81
  257. package/bin/shared/utils/store/schema.js.map +0 -1
  258. package/src/http/auth/AuthMiddleware.ts +0 -61
  259. package/src/http/auth/AuthRoutes.ts +0 -100
  260. package/src/http/auth/AuthService.ts +0 -367
  261. package/src/http/auth/AuthStore.ts +0 -572
  262. package/src/http/auth/RoutePolicy.ts +0 -255
  263. package/src/plugin/Lifecycle.ts +0 -116
  264. package/src/service/builtins/memory/runtime/Indexer.ts +0 -466
  265. package/src/service/schedule/Schema.ts +0 -34
  266. package/src/shared/utils/store/StoreChannelAccountRepository.ts +0 -269
  267. package/src/shared/utils/store/StoreEnvRepository.ts +0 -452
  268. package/src/shared/utils/store/StoreModelRepository.ts +0 -324
  269. package/src/shared/utils/store/StoreSchema.ts +0 -344
  270. package/src/shared/utils/store/StoreSecureSettings.ts +0 -126
  271. package/src/shared/utils/store/StoreShared.ts +0 -67
  272. package/src/shared/utils/store/crypto.ts +0 -112
  273. package/src/shared/utils/store/index.ts +0 -497
  274. package/src/shared/utils/store/schema.ts +0 -103
@@ -1,572 +0,0 @@
1
- /**
2
- * 统一账户存储层。
3
- *
4
- * 关键点(中文)
5
- * - 该模块只负责 `auth_*` 表的读写,不处理密码校验与 HTTP 语义。
6
- * - 数据仍落在控制面全局 SQLite 中,与现有平台配置共享底层存储。
7
- */
8
-
9
- import fs from "fs-extra";
10
- import path from "node:path";
11
- import Database from "better-sqlite3";
12
- import { drizzle } from "drizzle-orm/better-sqlite3";
13
- import { nanoid } from "nanoid";
14
- import { getPlatformStoreDbPath } from "@/host/runtime/CityPaths.js";
15
- import type { AuthIssuedToken, AuthTokenSummary } from "@/shared/types/auth/AuthToken.js";
16
- import {
17
- AUTH_DEFAULT_ROLES,
18
- AUTH_PERMISSION_DESCRIPTIONS,
19
- AUTH_PERMISSION_KEYS,
20
- type AuthDefaultRoleName,
21
- type AuthPermissionKey,
22
- } from "@/shared/types/auth/AuthPermission.js";
23
- import type {
24
- AuthAuditLog,
25
- AuthPermission,
26
- AuthRole,
27
- AuthTokenRecord,
28
- AuthUser,
29
- } from "@/shared/types/auth/AuthTypes.js";
30
- import { ensurePlatformStoreSchema } from "@/shared/utils/store/StoreSchema.js";
31
- import {
32
- nowIso,
33
- normalizeNonEmptyText,
34
- optionalTrimmedText,
35
- type PlatformStoreContext,
36
- } from "@/shared/utils/store/StoreShared.js";
37
-
38
- /**
39
- * AuthStore 构造参数。
40
- */
41
- export interface AuthStoreOptions {
42
- /**
43
- * SQLite 数据库路径。
44
- */
45
- dbPath?: string;
46
- }
47
-
48
- type SqliteRow = Record<string, unknown>;
49
-
50
- /**
51
- * AuthStore 门面。
52
- */
53
- export class AuthStore {
54
- private readonly sqlite: Database.Database;
55
- private readonly context: PlatformStoreContext;
56
-
57
- constructor(options: AuthStoreOptions = {}) {
58
- const dbPath = path.resolve(options.dbPath || getPlatformStoreDbPath());
59
- fs.ensureDirSync(path.dirname(dbPath));
60
- this.sqlite = new Database(dbPath);
61
- this.sqlite.pragma("journal_mode = WAL");
62
- this.context = {
63
- sqlite: this.sqlite,
64
- db: drizzle(this.sqlite),
65
- };
66
- ensurePlatformStoreSchema(this.context);
67
- }
68
-
69
- /**
70
- * 关闭数据库连接。
71
- */
72
- close(): void {
73
- this.sqlite.close();
74
- }
75
-
76
- /**
77
- * 返回当前用户数量。
78
- */
79
- countUsers(): number {
80
- const row = this.sqlite.prepare("SELECT COUNT(*) as count FROM auth_users").get() as
81
- | { count?: unknown }
82
- | undefined;
83
- return Number(row?.count || 0);
84
- }
85
-
86
- /**
87
- * 幂等写入默认角色与权限目录。
88
- */
89
- ensureDefaultCatalog(): void {
90
- const now = nowIso();
91
- const tx = this.sqlite.transaction(() => {
92
- const roleIds = new Map<AuthDefaultRoleName, string>();
93
- for (const role of AUTH_DEFAULT_ROLES) {
94
- const existing = this.sqlite
95
- .prepare("SELECT id FROM auth_roles WHERE name = ?")
96
- .get(role.name) as { id?: unknown } | undefined;
97
- if (existing?.id) {
98
- this.sqlite
99
- .prepare(
100
- "UPDATE auth_roles SET description = ?, updated_at = ? WHERE id = ?",
101
- )
102
- .run(role.description, now, String(existing.id));
103
- roleIds.set(role.name, String(existing.id));
104
- } else {
105
- const id = nanoid();
106
- this.sqlite
107
- .prepare(
108
- "INSERT INTO auth_roles (id, name, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?)",
109
- )
110
- .run(id, role.name, role.description, now, now);
111
- roleIds.set(role.name, id);
112
- }
113
- }
114
-
115
- const permissionIds = new Map<AuthPermissionKey, string>();
116
- for (const permission of AUTH_PERMISSION_KEYS) {
117
- const description = AUTH_PERMISSION_DESCRIPTIONS[permission];
118
- const existing = this.sqlite
119
- .prepare("SELECT id FROM auth_permissions WHERE key = ?")
120
- .get(permission) as { id?: unknown } | undefined;
121
- if (existing?.id) {
122
- this.sqlite
123
- .prepare(
124
- "UPDATE auth_permissions SET description = ?, updated_at = ? WHERE id = ?",
125
- )
126
- .run(description, now, String(existing.id));
127
- permissionIds.set(permission, String(existing.id));
128
- } else {
129
- const id = nanoid();
130
- this.sqlite
131
- .prepare(
132
- "INSERT INTO auth_permissions (id, key, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?)",
133
- )
134
- .run(id, permission, description, now, now);
135
- permissionIds.set(permission, id);
136
- }
137
- }
138
-
139
- for (const role of AUTH_DEFAULT_ROLES) {
140
- const roleId = roleIds.get(role.name);
141
- if (!roleId) continue;
142
- for (const permission of role.permissions) {
143
- const permissionId = permissionIds.get(permission);
144
- if (!permissionId) continue;
145
- this.sqlite
146
- .prepare(
147
- "INSERT OR IGNORE INTO auth_role_permissions (id, role_id, permission_id, created_at) VALUES (?, ?, ?, ?)",
148
- )
149
- .run(nanoid(), roleId, permissionId, now);
150
- }
151
- }
152
- });
153
- tx();
154
- }
155
-
156
- /**
157
- * 创建用户。
158
- */
159
- createUser(input: {
160
- username: string;
161
- passwordHash: string;
162
- displayName?: string;
163
- status?: "active" | "disabled";
164
- }): AuthUser {
165
- const id = nanoid();
166
- const now = nowIso();
167
- const username = normalizeNonEmptyText(input.username, "username");
168
- const passwordHash = normalizeNonEmptyText(input.passwordHash, "passwordHash");
169
- const displayName = optionalTrimmedText(input.displayName);
170
- const status = input.status === "disabled" ? "disabled" : "active";
171
- this.sqlite
172
- .prepare(
173
- "INSERT INTO auth_users (id, username, password_hash, display_name, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
174
- )
175
- .run(id, username, passwordHash, displayName || null, status, now, now);
176
- return {
177
- id,
178
- username,
179
- passwordHash,
180
- displayName,
181
- status,
182
- createdAt: now,
183
- updatedAt: now,
184
- };
185
- }
186
-
187
- /**
188
- * 根据用户名读取用户。
189
- */
190
- findUserByUsername(usernameInput: string): AuthUser | null {
191
- const username = normalizeNonEmptyText(usernameInput, "username");
192
- const row = this.sqlite
193
- .prepare("SELECT * FROM auth_users WHERE username = ?")
194
- .get(username) as SqliteRow | undefined;
195
- return row ? this.toAuthUser(row) : null;
196
- }
197
-
198
- /**
199
- * 根据用户 ID 读取用户。
200
- */
201
- getUserById(userIdInput: string): AuthUser | null {
202
- const userId = normalizeNonEmptyText(userIdInput, "userId");
203
- const row = this.sqlite
204
- .prepare("SELECT * FROM auth_users WHERE id = ?")
205
- .get(userId) as SqliteRow | undefined;
206
- return row ? this.toAuthUser(row) : null;
207
- }
208
-
209
- /**
210
- * 读取全部用户列表。
211
- */
212
- listUsers(): AuthUser[] {
213
- const rows = this.sqlite
214
- .prepare("SELECT * FROM auth_users ORDER BY username ASC")
215
- .all() as SqliteRow[];
216
- return rows.map((row) => this.toAuthUser(row));
217
- }
218
-
219
- /**
220
- * 更新用户基础资料。
221
- */
222
- updateUser(params: {
223
- userId: string;
224
- displayName?: string;
225
- status?: "active" | "disabled";
226
- }): AuthUser | null {
227
- const userId = normalizeNonEmptyText(params.userId, "userId");
228
- const current = this.getUserById(userId);
229
- if (!current) return null;
230
- const nextDisplayName = optionalTrimmedText(params.displayName);
231
- const nextStatus = params.status === "disabled" ? "disabled" : "active";
232
- const updatedAt = nowIso();
233
- this.sqlite
234
- .prepare(
235
- "UPDATE auth_users SET display_name = ?, status = ?, updated_at = ? WHERE id = ?",
236
- )
237
- .run(nextDisplayName || null, nextStatus, updatedAt, userId);
238
- return this.getUserById(userId);
239
- }
240
-
241
- /**
242
- * 更新用户密码哈希。
243
- */
244
- updateUserPasswordHash(params: {
245
- userId: string;
246
- passwordHash: string;
247
- }): AuthUser | null {
248
- const userId = normalizeNonEmptyText(params.userId, "userId");
249
- const passwordHash = normalizeNonEmptyText(params.passwordHash, "passwordHash");
250
- const current = this.getUserById(userId);
251
- if (!current) return null;
252
- const updatedAt = nowIso();
253
- this.sqlite
254
- .prepare(
255
- "UPDATE auth_users SET password_hash = ?, updated_at = ? WHERE id = ?",
256
- )
257
- .run(passwordHash, updatedAt, userId);
258
- return this.getUserById(userId);
259
- }
260
-
261
- /**
262
- * 给用户绑定角色。
263
- */
264
- assignRoleToUser(params: { userId: string; roleName: AuthDefaultRoleName | string }): void {
265
- const userId = normalizeNonEmptyText(params.userId, "userId");
266
- const role = this.sqlite
267
- .prepare("SELECT id FROM auth_roles WHERE name = ?")
268
- .get(normalizeNonEmptyText(params.roleName, "roleName")) as { id?: unknown } | undefined;
269
- if (!role?.id) throw new Error(`Unknown role: ${params.roleName}`);
270
- this.sqlite
271
- .prepare(
272
- "INSERT OR IGNORE INTO auth_user_roles (id, user_id, role_id, created_at) VALUES (?, ?, ?, ?)",
273
- )
274
- .run(nanoid(), userId, String(role.id), nowIso());
275
- }
276
-
277
- /**
278
- * 读取用户角色名列表。
279
- */
280
- listRoleNamesByUserId(userIdInput: string): string[] {
281
- const userId = normalizeNonEmptyText(userIdInput, "userId");
282
- const rows = this.sqlite
283
- .prepare(
284
- `
285
- SELECT DISTINCT roles.name as name
286
- FROM auth_roles roles
287
- INNER JOIN auth_user_roles links ON links.role_id = roles.id
288
- WHERE links.user_id = ?
289
- ORDER BY roles.name ASC
290
- `,
291
- )
292
- .all(userId) as Array<{ name?: unknown }>;
293
- return rows.map((row) => String(row.name || "").trim()).filter(Boolean);
294
- }
295
-
296
- /**
297
- * 清空用户当前绑定的全部角色。
298
- */
299
- clearRolesByUserId(userIdInput: string): void {
300
- const userId = normalizeNonEmptyText(userIdInput, "userId");
301
- this.sqlite
302
- .prepare("DELETE FROM auth_user_roles WHERE user_id = ?")
303
- .run(userId);
304
- }
305
-
306
- /**
307
- * 用新的角色集合覆盖用户角色绑定。
308
- */
309
- replaceRolesByUserId(params: {
310
- userId: string;
311
- roleNames: string[];
312
- }): string[] {
313
- const userId = normalizeNonEmptyText(params.userId, "userId");
314
- const roleNames = [...new Set(params.roleNames.map((item) => String(item || "").trim()).filter(Boolean))];
315
- const tx = this.sqlite.transaction(() => {
316
- this.clearRolesByUserId(userId);
317
- for (const roleName of roleNames) {
318
- this.assignRoleToUser({
319
- userId,
320
- roleName,
321
- });
322
- }
323
- });
324
- tx();
325
- return this.listRoleNamesByUserId(userId);
326
- }
327
-
328
- /**
329
- * 统计拥有指定角色且处于 active 状态的用户数量。
330
- */
331
- countActiveUsersByRole(roleNameInput: string): number {
332
- const roleName = normalizeNonEmptyText(roleNameInput, "roleName");
333
- const row = this.sqlite
334
- .prepare(
335
- `
336
- SELECT COUNT(DISTINCT users.id) as count
337
- FROM auth_users users
338
- INNER JOIN auth_user_roles user_roles ON user_roles.user_id = users.id
339
- INNER JOIN auth_roles roles ON roles.id = user_roles.role_id
340
- WHERE users.status = 'active' AND roles.name = ?
341
- `,
342
- )
343
- .get(roleName) as { count?: unknown } | undefined;
344
- return Number(row?.count || 0);
345
- }
346
-
347
- /**
348
- * 读取用户权限 key 列表。
349
- */
350
- listPermissionKeysByUserId(userIdInput: string): AuthPermissionKey[] {
351
- const userId = normalizeNonEmptyText(userIdInput, "userId");
352
- const rows = this.sqlite
353
- .prepare(
354
- `
355
- SELECT DISTINCT perms.key as key
356
- FROM auth_permissions perms
357
- INNER JOIN auth_role_permissions rp ON rp.permission_id = perms.id
358
- INNER JOIN auth_user_roles ur ON ur.role_id = rp.role_id
359
- WHERE ur.user_id = ?
360
- ORDER BY perms.key ASC
361
- `,
362
- )
363
- .all(userId) as Array<{ key?: unknown }>;
364
- return rows
365
- .map((row) => String(row.key || "").trim())
366
- .filter(Boolean) as AuthPermissionKey[];
367
- }
368
-
369
- /**
370
- * 创建 token 记录。
371
- */
372
- createToken(input: {
373
- userId: string;
374
- name: string;
375
- tokenHash: string;
376
- expiresAt?: string;
377
- }): AuthTokenRecord {
378
- const id = nanoid();
379
- const now = nowIso();
380
- const userId = normalizeNonEmptyText(input.userId, "userId");
381
- const name = normalizeNonEmptyText(input.name, "name");
382
- const tokenHash = normalizeNonEmptyText(input.tokenHash, "tokenHash");
383
- const expiresAt = optionalTrimmedText(input.expiresAt);
384
- this.sqlite
385
- .prepare(
386
- "INSERT INTO auth_tokens (id, user_id, name, token_hash, expires_at, revoked_at, last_used_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, NULL, NULL, ?, ?)",
387
- )
388
- .run(id, userId, name, tokenHash, expiresAt || null, now, now);
389
- return {
390
- id,
391
- userId,
392
- name,
393
- tokenHash,
394
- expiresAt,
395
- createdAt: now,
396
- updatedAt: now,
397
- };
398
- }
399
-
400
- /**
401
- * 根据 token 哈希读取记录。
402
- */
403
- findTokenByHash(tokenHashInput: string): AuthTokenRecord | null {
404
- const tokenHash = normalizeNonEmptyText(tokenHashInput, "tokenHash");
405
- const row = this.sqlite
406
- .prepare("SELECT * FROM auth_tokens WHERE token_hash = ?")
407
- .get(tokenHash) as SqliteRow | undefined;
408
- return row ? this.toAuthToken(row) : null;
409
- }
410
-
411
- /**
412
- * 根据 token ID 读取记录。
413
- */
414
- getTokenById(tokenIdInput: string): AuthTokenRecord | null {
415
- const tokenId = normalizeNonEmptyText(tokenIdInput, "tokenId");
416
- const row = this.sqlite
417
- .prepare("SELECT * FROM auth_tokens WHERE id = ?")
418
- .get(tokenId) as SqliteRow | undefined;
419
- return row ? this.toAuthToken(row) : null;
420
- }
421
-
422
- /**
423
- * 读取用户 token 列表。
424
- */
425
- listTokensByUserId(userIdInput: string): AuthTokenRecord[] {
426
- const userId = normalizeNonEmptyText(userIdInput, "userId");
427
- const rows = this.sqlite
428
- .prepare("SELECT * FROM auth_tokens WHERE user_id = ? ORDER BY created_at DESC")
429
- .all(userId) as SqliteRow[];
430
- return rows.map((row) => this.toAuthToken(row));
431
- }
432
-
433
- /**
434
- * 更新 token 最后使用时间。
435
- */
436
- touchToken(tokenIdInput: string): void {
437
- const tokenId = normalizeNonEmptyText(tokenIdInput, "tokenId");
438
- const now = nowIso();
439
- this.sqlite
440
- .prepare("UPDATE auth_tokens SET last_used_at = ?, updated_at = ? WHERE id = ?")
441
- .run(now, now, tokenId);
442
- }
443
-
444
- /**
445
- * 吊销 token。
446
- */
447
- revokeToken(tokenIdInput: string): AuthTokenRecord | null {
448
- const tokenId = normalizeNonEmptyText(tokenIdInput, "tokenId");
449
- const now = nowIso();
450
- this.sqlite
451
- .prepare("UPDATE auth_tokens SET revoked_at = ?, updated_at = ? WHERE id = ?")
452
- .run(now, now, tokenId);
453
- return this.getTokenById(tokenId);
454
- }
455
-
456
- /**
457
- * 删除 token。
458
- */
459
- deleteToken(tokenIdInput: string): boolean {
460
- const tokenId = normalizeNonEmptyText(tokenIdInput, "tokenId");
461
- const result = this.sqlite
462
- .prepare("DELETE FROM auth_tokens WHERE id = ?")
463
- .run(tokenId);
464
- return result.changes > 0;
465
- }
466
-
467
- /**
468
- * 写入审计日志。
469
- */
470
- insertAuditLog(input: {
471
- actorUserId?: string;
472
- actorTokenId?: string;
473
- resourceType: string;
474
- resourceId?: string;
475
- action: string;
476
- result: string;
477
- requestId?: string;
478
- ip?: string;
479
- userAgent?: string;
480
- metaJson?: string;
481
- }): AuthAuditLog {
482
- const id = nanoid();
483
- const createdAt = nowIso();
484
- const row: AuthAuditLog = {
485
- id,
486
- actorUserId: optionalTrimmedText(input.actorUserId),
487
- actorTokenId: optionalTrimmedText(input.actorTokenId),
488
- resourceType: normalizeNonEmptyText(input.resourceType, "resourceType"),
489
- resourceId: optionalTrimmedText(input.resourceId),
490
- action: normalizeNonEmptyText(input.action, "action"),
491
- result: normalizeNonEmptyText(input.result, "result"),
492
- requestId: optionalTrimmedText(input.requestId),
493
- ip: optionalTrimmedText(input.ip),
494
- userAgent: optionalTrimmedText(input.userAgent),
495
- metaJson: optionalTrimmedText(input.metaJson),
496
- createdAt,
497
- };
498
- this.sqlite
499
- .prepare(
500
- "INSERT INTO auth_audit_logs (id, actor_user_id, actor_token_id, resource_type, resource_id, action, result, request_id, ip, user_agent, meta_json, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
501
- )
502
- .run(
503
- row.id,
504
- row.actorUserId || null,
505
- row.actorTokenId || null,
506
- row.resourceType,
507
- row.resourceId || null,
508
- row.action,
509
- row.result,
510
- row.requestId || null,
511
- row.ip || null,
512
- row.userAgent || null,
513
- row.metaJson || null,
514
- row.createdAt,
515
- );
516
- return row;
517
- }
518
-
519
- /**
520
- * 将 token 记录转换为对外摘要。
521
- */
522
- toTokenSummary(record: AuthTokenRecord): AuthTokenSummary {
523
- return {
524
- id: record.id,
525
- name: record.name,
526
- expiresAt: record.expiresAt,
527
- lastUsedAt: record.lastUsedAt,
528
- createdAt: record.createdAt,
529
- updatedAt: record.updatedAt,
530
- };
531
- }
532
-
533
- /**
534
- * 将 token 记录与明文 token 合成为一次性返回体。
535
- */
536
- toIssuedToken(record: AuthTokenRecord, token: string): AuthIssuedToken {
537
- return {
538
- ...this.toTokenSummary(record),
539
- token,
540
- };
541
- }
542
-
543
- private toAuthUser(row: SqliteRow): AuthUser {
544
- return {
545
- id: String(row.id || ""),
546
- username: String(row.username || ""),
547
- passwordHash: String(row.password_hash || ""),
548
- displayName: optionalTrimmedText(String(row.display_name || "")),
549
- status: String(row.status || "active") === "disabled" ? "disabled" : "active",
550
- createdAt: String(row.created_at || ""),
551
- updatedAt: String(row.updated_at || ""),
552
- };
553
- }
554
-
555
- private toAuthToken(row: SqliteRow): AuthTokenRecord {
556
- return {
557
- id: String(row.id || ""),
558
- userId: String(row.user_id || ""),
559
- name: String(row.name || ""),
560
- tokenHash: String(row.token_hash || ""),
561
- expiresAt: optionalTrimmedText(String(row.expires_at || "")),
562
- revokedAt: optionalTrimmedText(String(row.revoked_at || "")),
563
- lastUsedAt: optionalTrimmedText(String(row.last_used_at || "")),
564
- createdAt: String(row.created_at || ""),
565
- updatedAt: String(row.updated_at || ""),
566
- };
567
- }
568
-
569
- private _unused(_row: SqliteRow): AuthRole | AuthPermission {
570
- throw new Error("unused");
571
- }
572
- }