sdlc-agent-4-enterprise-server 1.42.3 → 1.43.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 (218) hide show
  1. package/.env.example +23 -0
  2. package/README.md +3 -2
  3. package/dist/admin/db/config.js +14 -3
  4. package/dist/admin/db/config.js.map +1 -1
  5. package/dist/admin/db/core.d.ts +6 -0
  6. package/dist/admin/db/core.js +14 -6
  7. package/dist/admin/db/core.js.map +1 -1
  8. package/dist/admin/db/schema.d.ts +0 -1
  9. package/dist/admin/db/schema.js +217 -4
  10. package/dist/admin/db/schema.js.map +1 -1
  11. package/dist/admin/db/sessions.d.ts +3 -3
  12. package/dist/admin/db/sessions.js +12 -7
  13. package/dist/admin/db/sessions.js.map +1 -1
  14. package/dist/admin/db/users.js +2 -2
  15. package/dist/admin/db/users.js.map +1 -1
  16. package/dist/config/EntraConfig.d.ts +77 -0
  17. package/dist/config/EntraConfig.js +190 -0
  18. package/dist/config/EntraConfig.js.map +1 -0
  19. package/dist/config/index.d.ts +6 -2
  20. package/dist/config/index.js +25 -0
  21. package/dist/config/index.js.map +1 -1
  22. package/dist/database/adapters/SqliteAdapter.js +19 -1
  23. package/dist/database/adapters/SqliteAdapter.js.map +1 -1
  24. package/dist/database/repositories/UserRepository.d.ts +13 -2
  25. package/dist/database/repositories/UserRepository.js +62 -0
  26. package/dist/database/repositories/UserRepository.js.map +1 -1
  27. package/dist/database/repositories/interfaces.d.ts +17 -0
  28. package/dist/database/schema-registry/ensure-sa4e-276.d.ts +4 -0
  29. package/dist/database/schema-registry/ensure-sa4e-276.js +40 -0
  30. package/dist/database/schema-registry/ensure-sa4e-276.js.map +1 -0
  31. package/dist/models/pega-schema.models.d.ts +42 -42
  32. package/dist/server/HttpServer.js +11 -0
  33. package/dist/server/HttpServer.js.map +1 -1
  34. package/dist/server/auth/index.d.ts +3 -0
  35. package/dist/server/auth/index.js +4 -0
  36. package/dist/server/auth/index.js.map +1 -0
  37. package/dist/server/auth/models/GitHubProfile.d.ts +75 -0
  38. package/dist/server/auth/models/GitHubProfile.js +34 -0
  39. package/dist/server/auth/models/GitHubProfile.js.map +1 -0
  40. package/dist/server/auth/models/GoogleClaims.d.ts +75 -0
  41. package/dist/server/auth/models/GoogleClaims.js +44 -0
  42. package/dist/server/auth/models/GoogleClaims.js.map +1 -0
  43. package/dist/server/auth/models/NormalizedProfile.d.ts +8 -0
  44. package/dist/server/auth/models/NormalizedProfile.js +2 -0
  45. package/dist/server/auth/models/NormalizedProfile.js.map +1 -0
  46. package/dist/server/auth/models/SsoProviderConfig.d.ts +14 -0
  47. package/dist/server/auth/models/SsoProviderConfig.js +2 -0
  48. package/dist/server/auth/models/SsoProviderConfig.js.map +1 -0
  49. package/dist/server/auth/strategies/EntraProviderStrategy.d.ts +7 -0
  50. package/dist/server/auth/strategies/EntraProviderStrategy.js +112 -0
  51. package/dist/server/auth/strategies/EntraProviderStrategy.js.map +1 -0
  52. package/dist/server/auth/strategies/GitHubProviderStrategy.d.ts +24 -0
  53. package/dist/server/auth/strategies/GitHubProviderStrategy.js +133 -0
  54. package/dist/server/auth/strategies/GitHubProviderStrategy.js.map +1 -0
  55. package/dist/server/auth/strategies/GoogleProviderConfig.d.ts +23 -0
  56. package/dist/server/auth/strategies/GoogleProviderConfig.js +50 -0
  57. package/dist/server/auth/strategies/GoogleProviderConfig.js.map +1 -0
  58. package/dist/server/auth/strategies/GoogleProviderStrategy.d.ts +35 -0
  59. package/dist/server/auth/strategies/GoogleProviderStrategy.js +104 -0
  60. package/dist/server/auth/strategies/GoogleProviderStrategy.js.map +1 -0
  61. package/dist/server/auth/strategies/SsoProviderStrategy.d.ts +33 -0
  62. package/dist/server/auth/strategies/SsoProviderStrategy.js +2 -0
  63. package/dist/server/auth/strategies/SsoProviderStrategy.js.map +1 -0
  64. package/dist/server/auth/strategies/SsoStrategyRegistry.d.ts +13 -0
  65. package/dist/server/auth/strategies/SsoStrategyRegistry.js +30 -0
  66. package/dist/server/auth/strategies/SsoStrategyRegistry.js.map +1 -0
  67. package/dist/server/auth/strategies/index.d.ts +5 -0
  68. package/dist/server/auth/strategies/index.js +14 -0
  69. package/dist/server/auth/strategies/index.js.map +1 -0
  70. package/dist/server/auth/utils/callback-url.d.ts +22 -0
  71. package/dist/server/auth/utils/callback-url.js +34 -0
  72. package/dist/server/auth/utils/callback-url.js.map +1 -0
  73. package/dist/server/auth/utils/pkce-helper.d.ts +6 -0
  74. package/dist/server/auth/utils/pkce-helper.js +29 -0
  75. package/dist/server/auth/utils/pkce-helper.js.map +1 -0
  76. package/dist/server/auth/utils/sso-config-loader.d.ts +15 -0
  77. package/dist/server/auth/utils/sso-config-loader.js +35 -0
  78. package/dist/server/auth/utils/sso-config-loader.js.map +1 -0
  79. package/dist/server/middleware/jwt-auth.js +19 -12
  80. package/dist/server/middleware/jwt-auth.js.map +1 -1
  81. package/dist/server/middleware/verifiers/EntraRS256Verifier.d.ts +46 -0
  82. package/dist/server/middleware/verifiers/EntraRS256Verifier.js +124 -0
  83. package/dist/server/middleware/verifiers/EntraRS256Verifier.js.map +1 -0
  84. package/dist/server/middleware/verifiers/GoogleIdTokenVerifier.d.ts +34 -0
  85. package/dist/server/middleware/verifiers/GoogleIdTokenVerifier.js +82 -0
  86. package/dist/server/middleware/verifiers/GoogleIdTokenVerifier.js.map +1 -0
  87. package/dist/server/middleware/verifiers/JwksCache.d.ts +34 -0
  88. package/dist/server/middleware/verifiers/JwksCache.js +82 -0
  89. package/dist/server/middleware/verifiers/JwksCache.js.map +1 -0
  90. package/dist/server/middleware/verifiers/LocalHS256Verifier.d.ts +11 -0
  91. package/dist/server/middleware/verifiers/LocalHS256Verifier.js +55 -0
  92. package/dist/server/middleware/verifiers/LocalHS256Verifier.js.map +1 -0
  93. package/dist/server/middleware/verifiers/TokenVerifier.d.ts +38 -0
  94. package/dist/server/middleware/verifiers/TokenVerifier.js +35 -0
  95. package/dist/server/middleware/verifiers/TokenVerifier.js.map +1 -0
  96. package/dist/server/middleware/verifiers/entra-auth.d.ts +32 -0
  97. package/dist/server/middleware/verifiers/entra-auth.js +104 -0
  98. package/dist/server/middleware/verifiers/entra-auth.js.map +1 -0
  99. package/dist/server/middleware/verifiers/verifier.test.d.ts +5 -0
  100. package/dist/server/middleware/verifiers/verifier.test.js +338 -0
  101. package/dist/server/middleware/verifiers/verifier.test.js.map +1 -0
  102. package/dist/server/routes/admin/auth.js +6 -109
  103. package/dist/server/routes/admin/auth.js.map +1 -1
  104. package/dist/server/routes/admin/config.js +87 -0
  105. package/dist/server/routes/admin/config.js.map +1 -1
  106. package/dist/server/routes/admin/context.js +4 -1
  107. package/dist/server/routes/admin/context.js.map +1 -1
  108. package/dist/server/routes/admin/database.js +11 -1
  109. package/dist/server/routes/admin/database.js.map +1 -1
  110. package/dist/server/routes/admin/index.js +2 -0
  111. package/dist/server/routes/admin/index.js.map +1 -1
  112. package/dist/server/routes/admin/sso-providers.d.ts +3 -0
  113. package/dist/server/routes/admin/sso-providers.js +112 -0
  114. package/dist/server/routes/admin/sso-providers.js.map +1 -0
  115. package/dist/server/routes/auth/entra.d.ts +11 -0
  116. package/dist/server/routes/auth/entra.js +121 -0
  117. package/dist/server/routes/auth/entra.js.map +1 -0
  118. package/dist/server/routes/auth/sso-dynamic.d.ts +2 -0
  119. package/dist/server/routes/auth/sso-dynamic.js +40 -0
  120. package/dist/server/routes/auth/sso-dynamic.js.map +1 -0
  121. package/dist/server/routes/auth/sso-http-helpers.d.ts +61 -0
  122. package/dist/server/routes/auth/sso-http-helpers.js +162 -0
  123. package/dist/server/routes/auth/sso-http-helpers.js.map +1 -0
  124. package/dist/server/routes/auth/sso-provider.d.ts +12 -0
  125. package/dist/server/routes/auth/sso-provider.js +137 -0
  126. package/dist/server/routes/auth/sso-provider.js.map +1 -0
  127. package/dist/server/routes/auth/unified.d.ts +2 -0
  128. package/dist/server/routes/auth/unified.js +196 -0
  129. package/dist/server/routes/auth/unified.js.map +1 -0
  130. package/dist/server/routes/sa4e-215/auth.d.ts +1 -0
  131. package/dist/server/routes/sa4e-215/auth.js +2 -102
  132. package/dist/server/routes/sa4e-215/auth.js.map +1 -1
  133. package/dist/server/services/JitProvisioningService.d.ts +33 -0
  134. package/dist/server/services/JitProvisioningService.js +145 -0
  135. package/dist/server/services/JitProvisioningService.js.map +1 -0
  136. package/dist/server/services/SessionService.d.ts +15 -0
  137. package/dist/server/services/SessionService.js +20 -0
  138. package/dist/server/services/SessionService.js.map +1 -0
  139. package/dist/server/utils/ua.d.ts +2 -0
  140. package/dist/server/utils/ua.js +11 -0
  141. package/dist/server/utils/ua.js.map +1 -0
  142. package/dist/servers/atlassian/credentials/credential-schemas.d.ts +4 -4
  143. package/dist/shared/EventBus.d.ts +2 -0
  144. package/dist/shared/EventBus.js +2 -0
  145. package/dist/shared/EventBus.js.map +1 -1
  146. package/dist/viewer/admin/entra-sso.html +27 -0
  147. package/dist/viewer/admin/index.html +44 -5
  148. package/package.json +2 -1
  149. package/src/admin/db/config.ts +15 -5
  150. package/src/admin/db/core.ts +14 -6
  151. package/src/admin/db/schema.ts +208 -4
  152. package/src/admin/db/sessions.ts +14 -6
  153. package/src/admin/db/users.ts +2 -2
  154. package/src/config/EntraConfig.ts +231 -0
  155. package/src/config/index.ts +26 -0
  156. package/src/database/adapters/SqliteAdapter.ts +19 -1
  157. package/src/database/repositories/UserRepository.ts +70 -2
  158. package/src/database/repositories/__tests__/UserRepository.test.ts +99 -1
  159. package/src/database/repositories/interfaces.ts +13 -0
  160. package/src/database/schema-registry/ensure-sa4e-276.ts +41 -0
  161. package/src/server/HttpServer.ts +11 -0
  162. package/src/server/auth/index.ts +3 -0
  163. package/src/server/auth/models/GitHubProfile.ts +41 -0
  164. package/src/server/auth/models/GoogleClaims.ts +52 -0
  165. package/src/server/auth/models/NormalizedProfile.ts +8 -0
  166. package/src/server/auth/models/SsoProviderConfig.ts +14 -0
  167. package/src/server/auth/strategies/EntraProviderStrategy.ts +140 -0
  168. package/src/server/auth/strategies/GitHubProviderStrategy.ts +151 -0
  169. package/src/server/auth/strategies/GoogleProviderConfig.ts +78 -0
  170. package/src/server/auth/strategies/GoogleProviderStrategy.ts +148 -0
  171. package/src/server/auth/strategies/SsoProviderStrategy.ts +41 -0
  172. package/src/server/auth/strategies/SsoStrategyRegistry.ts +39 -0
  173. package/src/server/auth/strategies/__tests__/EntraProviderStrategy.state.test.ts +81 -0
  174. package/src/server/auth/strategies/__tests__/EntraProviderStrategy.test.ts +265 -0
  175. package/src/server/auth/strategies/__tests__/GitHubProviderStrategy.test.ts +129 -0
  176. package/src/server/auth/strategies/__tests__/GoogleProviderConfig.test.ts +69 -0
  177. package/src/server/auth/strategies/__tests__/GoogleProviderStrategy.test.ts +172 -0
  178. package/src/server/auth/strategies/__tests__/SsoStrategyRegistry.test.ts +75 -0
  179. package/src/server/auth/strategies/index.ts +15 -0
  180. package/src/server/auth/utils/callback-url.ts +35 -0
  181. package/src/server/auth/utils/pkce-helper.ts +32 -0
  182. package/src/server/auth/utils/sso-config-loader.ts +55 -0
  183. package/src/server/middleware/__tests__/jwt-auth.test.ts +1 -1
  184. package/src/server/middleware/jwt-auth.ts +19 -14
  185. package/src/server/middleware/verifiers/EntraRS256Verifier.ts +184 -0
  186. package/src/server/middleware/verifiers/GoogleIdTokenVerifier.ts +98 -0
  187. package/src/server/middleware/verifiers/JwksCache.ts +103 -0
  188. package/src/server/middleware/verifiers/LocalHS256Verifier.ts +66 -0
  189. package/src/server/middleware/verifiers/TokenVerifier.ts +65 -0
  190. package/src/server/middleware/verifiers/__tests__/GoogleIdTokenVerifier.test.ts +106 -0
  191. package/src/server/middleware/verifiers/entra-auth.ts +117 -0
  192. package/src/server/middleware/verifiers/verifier.test.ts +429 -0
  193. package/src/server/routes/admin/auth.ts +6 -112
  194. package/src/server/routes/admin/config.ts +69 -0
  195. package/src/server/routes/admin/context.ts +4 -1
  196. package/src/server/routes/admin/database.ts +11 -1
  197. package/src/server/routes/admin/index.ts +2 -0
  198. package/src/server/routes/admin/sso-providers.ts +102 -0
  199. package/src/server/routes/auth/__tests__/sso-dynamic.test.ts +108 -0
  200. package/src/server/routes/auth/entra.ts +143 -0
  201. package/src/server/routes/auth/sso-dynamic.ts +50 -0
  202. package/src/server/routes/auth/sso-http-helpers.ts +176 -0
  203. package/src/server/routes/auth/sso-provider.ts +160 -0
  204. package/src/server/routes/auth/unified.ts +188 -0
  205. package/src/server/routes/sa4e-215/__tests__/sa4e-215.routes.test.ts +2 -2
  206. package/src/server/routes/sa4e-215/auth.ts +3 -123
  207. package/src/server/services/JitProvisioningService.ts +194 -0
  208. package/src/server/services/SessionService.ts +20 -0
  209. package/src/server/services/__tests__/JitProvisioningService.test.ts +187 -0
  210. package/src/server/utils/ua.ts +11 -0
  211. package/src/shared/EventBus.ts +2 -0
  212. package/src/viewer/admin/entra-sso.html +27 -0
  213. package/src/viewer/admin/index.html +44 -5
  214. package/tests/integration/auth.test.ts +1 -1
  215. package/tests/integration/entra-oauth.it.test.ts +169 -0
  216. package/tests/integration/google-oauth.it.test.ts +173 -0
  217. package/tests/unit/EntraConfig.test.ts +169 -0
  218. package/tests/unit/entra-loopback-redirect.test.ts +49 -0
package/.env.example CHANGED
@@ -72,3 +72,26 @@ CHECKSUM_MAX_ZIP_ENTRIES=50000 # trần số entry trong ZIP
72
72
  # --- Bulk-check limits (SEC-04) ---
73
73
  # Server-side cap on checksums per bulk-check request (client batches <= 1000).
74
74
  BULK_CHECK_MAX_CHECKSUMS=5000
75
+
76
+ # =============================================================================
77
+ # SA4E-264 — Entra ID SSO config (env template — placeholders only)
78
+ # NEVER commit real values. Use local .env (untracked) or a secret manager.
79
+ # See FSD SA4E-264 §4.1 for validation rules.
80
+ # =============================================================================
81
+
82
+ # Gate flag: true/1 = enable SSO (Entra vars become REQUIRED at startup, fail-fast)
83
+ SSO_ENABLED=false
84
+
85
+ # --- Required when SSO_ENABLED=true (4 values from App Registration runbook SA4E-271) ---
86
+ ENTRA_TENANT_ID=<azure-ad-tenant-guid-or-common>
87
+ ENTRA_CLIENT_ID=<app-registration-client-guid>
88
+ ENTRA_CLIENT_SECRET=<set-via-secret-manager> # min 8 chars; NEVER a real secret in repo
89
+ ENTRA_REDIRECT_URI=http://localhost:48721/auth/entra/callback
90
+
91
+ # --- Optional (derived defaults when absent — see FSD §7.2) ---
92
+ # ENTRA_AUTHORITY=https://login.microsoftonline.com/<tenant-guid>
93
+ # ENTRA_ISSUER=https://login.microsoftonline.com/<tenant-guid>/v2.0
94
+ # ENTRA_JWKS_URI=https://login.microsoftonline.com/<tenant-guid>/discovery/v2.0/keys
95
+ # ENTRA_SCOPES=openid profile email offline_access
96
+ # SSO_ALLOWED_REDIRECTS=/admin?page=dashboard,/app/dashboard
97
+ # SSO_LEGACY_REDIRECT_WITH_TOKEN=false
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <img src="https://img.shields.io/badge/version-1.42.2-blue?style=for-the-badge" alt="Version">
9
+ <img src="https://img.shields.io/badge/version-1.43.0-blue?style=for-the-badge" alt="Version">
10
10
  <img src="https://img.shields.io/badge/tools-66+-teal?style=for-the-badge" alt="Tools">
11
11
  <img src="https://img.shields.io/badge/node-%3E%3D18-green?style=for-the-badge" alt="Node">
12
12
  </p>
@@ -38,7 +38,7 @@ Server starts at **http://localhost:48721**. Verify it's running:
38
38
 
39
39
  ```bash
40
40
  curl http://localhost:48721/health
41
- # → {"status":"healthy","version":"1.42.2","uptime":5,"tools_loaded":52}
41
+ # → {"status":"healthy","version":"1.43.0","uptime":5,"tools_loaded":52}
42
42
  ```
43
43
 
44
44
  ### Development Mode (auto-reload)
@@ -233,6 +233,7 @@ The embedding model is expected at `.code-intel/models/model.onnx`. Download it:
233
233
 
234
234
  | Version | Date | Ticket | Changes |
235
235
  |---------|------|--------|---------|
236
+ | 1.43.0 | 2026-09-22 | SA4E-262 | Multi-provider SSO unified on `sso_providers` (Entra/Google/GitHub, Strategy pattern). Entra email verification via Microsoft `xms_edov` claim (Entra omits standard `email_verified`); loopback SSO sessions no longer User-Agent-bound so extension `/api/admin/auth/me` works; JIT provisioning rejections return `403 provisioning_rejected` with a clear reason. |
236
237
  | 1.42.2 | 2026-09-11 | SA4E-257 | Wire DB-backed MCP server config to McpClientManager: McpServerConfigRepository loads `mcp_servers` table, initializeAll reads enabled servers from DB, real-time hooks auto connect/reconnect/disconnect on CRUD, transport normalization `streamable-http → httpStream`, mock logs removed. Regression tests pass. |
237
238
  | 1.42.1 | 2026-09-10 | SA4E-258 | Tenant scope stamping for tool execution: `/api/tools/execute` + `/api/code/search` stamp trusted scope onto tool args via canonical `__projectId`/`__userId` (not only `_projectContext`), fixing code-intel tools (fail-closed on missing `__projectId`) that returned "No results found". Covers MCP call path (mcpServer) + KB API route. Graph migrator idempotency, query-layer scope resolution, indexing-engine fixes. KB Graph: FileContainsSymbolStrategy dir-based match for LWC/Aura components (LWC_COMPONENT no longer isolated). Regression tests added (tools-execute-scope, orchestration dynamic IT, mcpServer calltool IT). |
238
239
  | 1.42.0 | 2026-09-08 | SA4E-301 | Multi-language tree-sitter parsers (C/C++/C#/PHP/Ruby/Scala/Swift/Kotlin) via shared GenericTreeSitterParser + regex fallback; symbol-kind fixes (struct/enum naming, method promotion, variable/property/constant separation, dedupe). Salesforce indexing (Apex/LWC/Aura/Visualforce/meta) with grammars copied to dist. KB Graph edges rebuilt from `relationships` (MembershipEdgeStrategy CONTAINS + FileContainsSymbolStrategy + inherits/implements resolve-by-name); auto-heal backfill (ensure-sa4e-301), unused edge tables dropped (303), unique index (302). Enrichment dedup (single CodeEnrichmentTaskCreator + PENDING guard, orphan task cleanup 300). Continuous budget-driven KB Graph LOD renderer. Node.js 22 LTS. |
@@ -33,9 +33,20 @@ export async function recordConfigChange(section, key, oldValue, newValue, chang
33
33
  * @param limit - Max entries (default 10)
34
34
  */
35
35
  export async function getConfigChanges(limit = 10) {
36
- const adapter = getDbAdapter();
37
- const rows = await adapter.allAsync('SELECT * FROM config_changes ORDER BY changed_at DESC LIMIT ?', [limit]);
38
- return rows.map(rowToConfigChange);
36
+ // Fail-safe: if the config_changes table is not ready yet (e.g. right after
37
+ // switching to a freshly-provisioned Postgres engine before migrations run),
38
+ // return an empty history instead of throwing. Throwing here would bubble up
39
+ // through GET /api/admin/config and blank out the ENTIRE config page
40
+ // (LLM / taskWorker / auth sections all disappear, leaving only Database).
41
+ // Mirrors the resilient pattern used by getLatestConfigValue/loadPersistedLLMConfig.
42
+ try {
43
+ const adapter = getDbAdapter();
44
+ const rows = await adapter.allAsync('SELECT * FROM config_changes ORDER BY changed_at DESC LIMIT ?', [limit]);
45
+ return rows.map(rowToConfigChange);
46
+ }
47
+ catch {
48
+ return [];
49
+ }
39
50
  }
40
51
  /**
41
52
  * Load the latest persisted value for a specific section.key from config_changes.
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/admin/db/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/admin/db/config.ts"],"names":[],"mappings":"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"}
@@ -33,5 +33,11 @@ export declare function resetAdminDb(): void;
33
33
  /**
34
34
  * Get the raw DB instance.
35
35
  * @deprecated Use getDbAdapter() for new code. Kept for backward compat with tests.
36
+ * SA4E-262 fix: delegates to getDbAdapter() to honor the unified-DB contract.
37
+ * The previous implementation force-initialized the SQLite adapter even when the
38
+ * active engine was PostgreSQL — splitting admin-UI writes (SQLite) from
39
+ * auth/login-page reads (PostgreSQL) and crashing the server on first
40
+ * sso-providers/config request (lazy SqliteAdapter.connect threw CANTOPEN and
41
+ * the rejection was unhandled).
36
42
  */
37
43
  export declare function getAdminDb(): any;
@@ -81,10 +81,14 @@ let sqliteReady = null;
81
81
  function getUnifiedSqliteAdapter() {
82
82
  if (!sqliteAdapter) {
83
83
  sqliteAdapter = new SqliteAdapter(DB_PATH);
84
- // SqliteAdapter.connect() is sync internally — safe to call eagerly
85
- void sqliteAdapter.connect();
84
+ // SA4E-262 fix: connect() MUST be chained into sqliteReady — the previous
85
+ // `void connect()` orphaned the rejection, so a CANTOPEN during lazy init
86
+ // crashed the whole server (unhandled rejection) instead of failing the
87
+ // caller's request with a 500.
86
88
  const adapter = sqliteAdapter;
87
- sqliteReady = initSchema(adapter).then(() => seedDefaults(adapter))
89
+ sqliteReady = adapter.connect()
90
+ .then(() => initSchema(adapter))
91
+ .then(() => seedDefaults(adapter))
88
92
  .catch((err) => logger.error({ err }, '[admin] SQLite schema init failed'));
89
93
  }
90
94
  return sqliteAdapter;
@@ -162,10 +166,14 @@ export function resetAdminDb() {
162
166
  /**
163
167
  * Get the raw DB instance.
164
168
  * @deprecated Use getDbAdapter() for new code. Kept for backward compat with tests.
169
+ * SA4E-262 fix: delegates to getDbAdapter() to honor the unified-DB contract.
170
+ * The previous implementation force-initialized the SQLite adapter even when the
171
+ * active engine was PostgreSQL — splitting admin-UI writes (SQLite) from
172
+ * auth/login-page reads (PostgreSQL) and crashing the server on first
173
+ * sso-providers/config request (lazy SqliteAdapter.connect threw CANTOPEN and
174
+ * the rejection was unhandled).
165
175
  */
166
176
  export function getAdminDb() {
167
- const adapter = getUnifiedSqliteAdapter();
168
- // getRawDb removed; return adapter directly for compat
169
- return adapter;
177
+ return getDbAdapter();
170
178
  }
171
179
  //# sourceMappingURL=core.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/admin/db/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/admin/db/core.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,6 @@
5
5
  * SQLite and PostgreSQL (PostgresAdapter throws on the sync exec/get/run methods).
6
6
  */
7
7
  import type { DatabaseAdapter } from '../../database/adapters/DatabaseAdapter.js';
8
- /** Initialize admin schema tables (idempotent CREATE IF NOT EXISTS). */
9
8
  export declare function initSchema(db: DatabaseAdapter): Promise<void>;
10
9
  /** Seed default access groups and admin user. */
11
10
  export declare function seedDefaults(db: DatabaseAdapter): Promise<void>;
@@ -20,9 +20,182 @@ function insertIgnore(engine, sql) {
20
20
  return sql;
21
21
  }
22
22
  /** Initialize admin schema tables (idempotent CREATE IF NOT EXISTS). */
23
+ async function migrateUsersSso(db, engine) {
24
+ try {
25
+ if (engine === 'postgresql') {
26
+ await db.execAsync(`ALTER TABLE users ADD COLUMN IF NOT EXISTS account_type TEXT NOT NULL DEFAULT 'LOCAL'`);
27
+ await db.execAsync(`ALTER TABLE users ADD COLUMN IF NOT EXISTS external_provider TEXT`);
28
+ await db.execAsync(`ALTER TABLE users ADD COLUMN IF NOT EXISTS external_subject_id TEXT`);
29
+ await db.execAsync(`ALTER TABLE users ALTER COLUMN password_hash DROP NOT NULL`);
30
+ await db.execAsync(`CREATE UNIQUE INDEX IF NOT EXISTS uq_users_external_identity ON users (external_provider, external_subject_id)`);
31
+ }
32
+ else {
33
+ try {
34
+ await db.execAsync(`ALTER TABLE users ADD COLUMN account_type TEXT NOT NULL DEFAULT 'LOCAL'`);
35
+ }
36
+ catch { }
37
+ try {
38
+ await db.execAsync(`ALTER TABLE users ADD COLUMN external_provider TEXT`);
39
+ }
40
+ catch { }
41
+ try {
42
+ await db.execAsync(`ALTER TABLE users ADD COLUMN external_subject_id TEXT`);
43
+ }
44
+ catch { }
45
+ // SQLite cannot ALTER COLUMN nullability; recreate table if password_hash is NOT NULL
46
+ try {
47
+ const info = await db.allAsync(`PRAGMA table_info(users)`);
48
+ const col = info.find(c => c.name === 'password_hash');
49
+ if (col && col.notnull === 1) {
50
+ await db.execAsync(`ALTER TABLE users RENAME TO users_old`);
51
+ await db.execAsync(`CREATE TABLE users (
52
+ user_id TEXT PRIMARY KEY,
53
+ username TEXT,
54
+ email TEXT UNIQUE,
55
+ password_hash TEXT,
56
+ status TEXT,
57
+ access_group_id TEXT,
58
+ force_password_change INTEGER,
59
+ created_at TEXT,
60
+ last_login TEXT,
61
+ account_type TEXT NOT NULL DEFAULT 'LOCAL',
62
+ external_provider TEXT,
63
+ external_subject_id TEXT
64
+ )`);
65
+ await db.execAsync(`INSERT INTO users SELECT user_id, username, email, password_hash, status, access_group_id, force_password_change, created_at, last_login, COALESCE(account_type,'LOCAL'), external_provider, external_subject_id FROM users_old`);
66
+ await db.execAsync(`DROP TABLE users_old`);
67
+ }
68
+ }
69
+ catch { }
70
+ await db.execAsync(`CREATE UNIQUE INDEX IF NOT EXISTS uq_users_external_identity ON users (external_provider, external_subject_id)`);
71
+ }
72
+ }
73
+ catch (err) {
74
+ console.debug('[schema] users_sso migration:', err.message);
75
+ }
76
+ }
77
+ async function seedDefaultSsoProviders(db) {
78
+ try {
79
+ const templates = [
80
+ {
81
+ // Hướng A (SA4E-262): Entra is configured via sso_providers like every
82
+ // other provider (single source of truth), so it must have a seed row too.
83
+ provider_type: 'entra',
84
+ name: 'Microsoft Entra ID',
85
+ enabled: 0,
86
+ login_ui_html: `<span class="sso-btn sso-entra"><svg width="18" height="18" viewBox="0 0 23 23"><path fill="#f35325" d="M1 1h10v10H1z"/><path fill="#81bc06" d="M12 1h10v10H12z"/><path fill="#05a6f0" d="M1 12h10v10H1z"/><path fill="#ffba08" d="M12 12h10v10H12z"/></svg> Sign in with Microsoft</span>`,
87
+ },
88
+ {
89
+ provider_type: 'google',
90
+ name: 'Google',
91
+ enabled: 0,
92
+ // login_ui_html holds only the visual (icon + label) — NO navigation URL.
93
+ // The login page wraps it in an anchor built from basePath so it works
94
+ // under sub-path deploys (ui-relative-paths: never embed absolute hrefs).
95
+ login_ui_html: `<span class="sso-btn sso-google"><svg width="18" height="18" viewBox="0 0 24 24"><path fill="#EA4335" d="M12 10.2v3.6h5.1c-.2 1.2-1.5 3.6-5.1 3.6-3.1 0-5.6-2.5-5.6-5.6s2.5-5.6 5.6-5.6c1.8 0 3 .8 3.7 1.4l2.5-2.4C17 2.9 14.7 1.8 12 1.8 6.8 1.8 2.5 6.1 2.5 11.3S6.8 20.8 12 20.8c5.6 0 9.3-4 9.3-9.3 0-.6 0-1.2-.1-1.8H12z"/></svg> Sign in with Google</span>`,
96
+ },
97
+ {
98
+ provider_type: 'github',
99
+ name: 'GitHub',
100
+ enabled: 0,
101
+ login_ui_html: `<span class="sso-btn sso-github"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .5a12 12 0 0 0-3.79 23.4c.6.11.82-.26.82-.58v-2.02c-3.34.73-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.1-.75.08-.73.08-.73 1.22.09 1.86 1.26 1.86 1.26 1.08 1.86 2.83 1.32 3.52 1.01.11-.79.42-1.32.76-1.62-2.67-.3-5.47-1.34-5.47-5.95 0-1.31.47-2.38 1.24-3.22-.12-.3-.54-1.52.12-3.18 0 0 1.01-.32 3.3 1.23a11.4 11.4 0 0 1 6 0c2.29-1.55 3.3-1.23 3.3-1.23.66 1.66.24 2.88.12 3.18.77.84 1.24 1.91 1.24 3.22 0 4.61-2.8 5.65-5.48 5.95.43.37.81 1.1.81 2.22v3.29c0 .32.22.69.82.58A12 12 0 0 0 12 .5Z"/></svg> Sign in with GitHub</span>`,
102
+ },
103
+ {
104
+ provider_type: 'x',
105
+ name: 'X',
106
+ enabled: 0,
107
+ login_ui_html: `<span class="sso-btn sso-x">Sign in with X</span>`,
108
+ },
109
+ {
110
+ provider_type: 'facebook',
111
+ name: 'Facebook',
112
+ enabled: 0,
113
+ login_ui_html: `<span class="sso-btn sso-facebook"><svg width="18" height="18" viewBox="0 0 24 24"><path fill="#1877F2" d="M24 12.07C24 5.41 18.63 0 12 0S0 5.41 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.05V9.41c0-3.02 1.8-4.7 4.55-4.7 1.31 0 2.68.24 2.68.24v2.95h-1.51c-1.48 0-1.94.92-1.94 1.86v2.24h3.3l-.53 3.49h-2.77V24C19.61 23.1 24 18.1 24 12.07z"/></svg> Sign in with Facebook</span>`,
114
+ },
115
+ ];
116
+ const now = new Date().toISOString();
117
+ for (const t of templates) {
118
+ const exists = await db.getAsync('SELECT 1 FROM sso_providers WHERE provider_type = ?', [t.provider_type]);
119
+ if (!exists) {
120
+ const provider_id = `${t.provider_type}-${Date.now()}`;
121
+ // 13 columns → 13 placeholders (fix SA4E-262: was 12 placeholders for 13 values)
122
+ await db.runAsync(`INSERT INTO sso_providers (provider_id, provider_type, name, enabled, client_id, client_secret, tenant_id, redirect_uri, allowed_redirects, scopes, login_ui_html, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)`, [provider_id, t.provider_type, t.name, t.enabled, '', '', '', '', '', '', t.login_ui_html, now, now]);
123
+ }
124
+ }
125
+ }
126
+ catch (err) {
127
+ // Non-fatal: seed of default provider templates is optional, but surface the
128
+ // error (console.error, not debug) so a broken INSERT is not swallowed silently.
129
+ console.error('[schema] seedDefaultSsoProviders failed:', err.message);
130
+ }
131
+ }
132
+ /**
133
+ * Rewrite legacy login_ui_html that embedded an absolute login URL
134
+ * (`<a href="/auth/{provider}/login">…</a>`) into a URL-less `<span>` so the
135
+ * login page can wrap it in a basePath-aware anchor. Runs outside any
136
+ * transaction (autocommit) — safe to re-run (idempotent on already-migrated rows).
137
+ */
138
+ async function migrateLoginUiHtmlToUrlless(db) {
139
+ try {
140
+ const rows = await db.allAsync("SELECT provider_id, login_ui_html FROM sso_providers WHERE login_ui_html LIKE '%href=%/auth/%/login%'");
141
+ for (const row of rows || []) {
142
+ // Drop the opening <a ...> (keeping inner content) and turn </a> into </span>.
143
+ const migrated = row.login_ui_html
144
+ .replace(/<a\b[^>]*\bhref=["'][^"']*\/auth\/[^"']*\/login["'][^>]*>/i, '<span class="sso-btn">')
145
+ .replace(/<\/a>/i, '</span>');
146
+ await db.runAsync('UPDATE sso_providers SET login_ui_html = ? WHERE provider_id = ?', [migrated, row.provider_id]);
147
+ }
148
+ if (rows && rows.length > 0) {
149
+ console.debug(`[schema] migrated ${rows.length} login_ui_html row(s) to URL-less form`);
150
+ }
151
+ }
152
+ catch (err) {
153
+ // Non-fatal: surface the error but do not block schema init.
154
+ console.error('[schema] migrateLoginUiHtmlToUrlless failed:', err.message);
155
+ }
156
+ }
157
+ async function seedSsoProvidersFromEnv(db) {
158
+ try {
159
+ const cnt = await db.getAsync('SELECT COUNT(*) as count FROM sso_providers');
160
+ if (cnt && cnt.count > 0)
161
+ return;
162
+ const env = process.env;
163
+ if (!env.SSO_ENABLED || env.SSO_ENABLED !== 'true')
164
+ return;
165
+ const tenant = env.ENTRA_TENANT_ID || '';
166
+ const clientId = env.ENTRA_CLIENT_ID || '';
167
+ const clientSecret = env.ENTRA_CLIENT_SECRET || '';
168
+ if (!tenant || !clientId)
169
+ return;
170
+ const now = new Date().toISOString();
171
+ const provider_id = `entra-${Date.now()}`;
172
+ const name = 'Entra ID';
173
+ const enabled = 1;
174
+ const redirect_uri = env.ENTRA_REDIRECT_URI || '';
175
+ const allowed_redirects = env.SSO_ALLOWED_REDIRECTS || '';
176
+ const scopes = env.ENTRA_SCOPES || 'openid profile email offline_access';
177
+ const login_ui_html = `<button class="sso-btn sso-entra">Sign in with Entra ID</button>`;
178
+ // 13 columns → 13 placeholders (fix SA4E-262: was 12 placeholders for 13 values)
179
+ await db.runAsync(`INSERT INTO sso_providers (provider_id, provider_type, name, enabled, client_id, client_secret, tenant_id, redirect_uri, allowed_redirects, scopes, login_ui_html, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)`, [provider_id, 'entra', name, enabled, clientId, clientSecret, tenant, redirect_uri, allowed_redirects, scopes, login_ui_html, now, now]);
180
+ console.debug('[schema] sso_providers seeded from env');
181
+ }
182
+ catch (err) {
183
+ // Non-fatal, but surface the error so a broken INSERT is not swallowed silently.
184
+ console.error('[schema] seedSsoProvidersFromEnv failed:', err.message);
185
+ }
186
+ }
23
187
  export async function initSchema(db) {
24
188
  const engine = db.getEngine();
25
189
  await db.execAsync(schemaSql(engine));
190
+ // SA4E-265 migration: users_sso
191
+ await migrateUsersSso(db, engine);
192
+ // SA4E-262 migration: add user_agent_hash to sessions for session fixation hardening
193
+ try {
194
+ await db.execAsync(`ALTER TABLE sessions ADD COLUMN user_agent_hash TEXT DEFAULT ''`);
195
+ }
196
+ catch (err) {
197
+ console.debug('[schema] sessions.user_agent_hash already exists :', err.message);
198
+ }
26
199
  // Idempotent migration: add project_id to graph_nodes for existing DBs
27
200
  try {
28
201
  await db.execAsync(`ALTER TABLE graph_nodes ADD COLUMN project_id TEXT NOT NULL DEFAULT ''`);
@@ -59,6 +232,22 @@ export async function initSchema(db) {
59
232
  catch (err) {
60
233
  console.debug('[schema] group_permissions unique index :', err.message);
61
234
  }
235
+ // Migration: add login_ui_html column if missing
236
+ try {
237
+ await db.execAsync(`ALTER TABLE sso_providers ADD COLUMN login_ui_html TEXT NOT NULL DEFAULT ''`);
238
+ }
239
+ catch (err) {
240
+ console.debug('[schema] login_ui_html already exists:', err.message);
241
+ }
242
+ // Migration (SA4E-310): strip absolute-path anchors from stored login_ui_html.
243
+ // Old seeds embedded <a href="/auth/{p}/login">…</a> which breaks sub-path
244
+ // deploys. The login page now builds the URL from basePath, so stored HTML
245
+ // must carry only the visual content — rewrite legacy <a href=...> to <span>.
246
+ await migrateLoginUiHtmlToUrlless(db);
247
+ // Migration: seed sso_providers from env if table empty
248
+ await seedSsoProvidersFromEnv(db);
249
+ // Seed default provider templates for Google/GitHub/X/Facebook
250
+ await seedDefaultSsoProviders(db);
62
251
  }
63
252
  /** Seed default access groups and admin user. */
64
253
  export async function seedDefaults(db) {
@@ -103,8 +292,8 @@ async function seedAdminUser(db) {
103
292
  ? envPassword
104
293
  : crypto.randomBytes(18).toString('base64url');
105
294
  const hash = hashPassword(initialPassword);
106
- await db.runAsync(`INSERT INTO users (user_id, username, email, password_hash, status, access_group_id, force_password_change, created_at)
107
- VALUES (?, ?, ?, ?, 'ACTIVE', 'grp-admin', 1, ?)`, ['user-admin-001', 'admin', 'admin@localhost', hash, now]);
295
+ await db.runAsync(`INSERT INTO users (user_id, username, email, password_hash, status, access_group_id, force_password_change, created_at, account_type)
296
+ VALUES (?, ?, ?, ?, 'ACTIVE', 'grp-admin', 1, ?, 'LOCAL')`, ['user-admin-001', 'admin', 'admin@localhost', hash, now]);
108
297
  if (!envPassword) {
109
298
  process.stdout.write('\n============================================================\n' +
110
299
  ' ADMIN ACCOUNT CREATED — generated one-time password:\n' +
@@ -137,12 +326,15 @@ function schemaSql(engine) {
137
326
  user_id TEXT PRIMARY KEY,
138
327
  username TEXT UNIQUE NOT NULL,
139
328
  email TEXT NOT NULL DEFAULT '',
140
- password_hash TEXT NOT NULL,
329
+ password_hash TEXT,
141
330
  status TEXT NOT NULL DEFAULT 'ACTIVE',
142
331
  access_group_id TEXT NOT NULL,
143
332
  force_password_change INTEGER NOT NULL DEFAULT 0,
144
333
  created_at TEXT NOT NULL,
145
- last_login TEXT
334
+ last_login TEXT,
335
+ account_type TEXT NOT NULL DEFAULT 'LOCAL' CHECK (account_type IN ('LOCAL','SSO')),
336
+ external_provider TEXT,
337
+ external_subject_id TEXT
146
338
  );
147
339
 
148
340
  CREATE TABLE IF NOT EXISTS access_groups (
@@ -168,6 +360,7 @@ function schemaSql(engine) {
168
360
  token TEXT UNIQUE NOT NULL,
169
361
  device TEXT DEFAULT '',
170
362
  ip_address TEXT DEFAULT '',
363
+ user_agent_hash TEXT DEFAULT '',
171
364
  login_at TEXT NOT NULL,
172
365
  expires_at TEXT NOT NULL,
173
366
  is_active INTEGER NOT NULL DEFAULT 1,
@@ -203,6 +396,26 @@ function schemaSql(engine) {
203
396
  CREATE INDEX IF NOT EXISTS idx_audit_user ON audit_log(user_id);
204
397
  CREATE INDEX IF NOT EXISTS idx_config_changes_time ON config_changes(changed_at);
205
398
 
399
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_users_external_identity ON users (external_provider, external_subject_id);
400
+
401
+ CREATE TABLE IF NOT EXISTS sso_providers (
402
+ provider_id TEXT PRIMARY KEY,
403
+ provider_type TEXT NOT NULL CHECK (provider_type IN ('entra','google','github','x','facebook','azuread')),
404
+ name TEXT NOT NULL,
405
+ enabled INTEGER NOT NULL DEFAULT 0,
406
+ client_id TEXT NOT NULL DEFAULT '',
407
+ client_secret TEXT NOT NULL DEFAULT '',
408
+ tenant_id TEXT NOT NULL DEFAULT '',
409
+ redirect_uri TEXT NOT NULL DEFAULT '',
410
+ allowed_redirects TEXT NOT NULL DEFAULT '',
411
+ scopes TEXT NOT NULL DEFAULT '',
412
+ login_ui_html TEXT NOT NULL DEFAULT '',
413
+ created_at TEXT NOT NULL DEFAULT ${now},
414
+ updated_at TEXT NOT NULL DEFAULT ${now}
415
+ );
416
+
417
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_sso_providers_type ON sso_providers(provider_type);
418
+
206
419
  CREATE TABLE IF NOT EXISTS graph_nodes (
207
420
  entry_id TEXT PRIMARY KEY,
208
421
  label TEXT NOT NULL DEFAULT '',
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/admin/db/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/admin/db/schema.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import type { Session } from '../types/rbac.types.js';
7
7
  * Create a new session for a user.
8
8
  * @returns Session with plain-text token
9
9
  */
10
- export declare function createSession(userId: string, device?: string, ip?: string): Promise<Session & {
10
+ export declare function createSession(userId: string, device?: string, ip?: string, userAgentHash?: string): Promise<Session & {
11
11
  token: string;
12
12
  }>;
13
13
  /**
@@ -15,7 +15,7 @@ export declare function createSession(userId: string, device?: string, ip?: stri
15
15
  * Checks is_active, expiry, and user status.
16
16
  * @returns Session identity or null if invalid/expired
17
17
  */
18
- export declare function validateSession(token: string): Promise<{
18
+ export declare function validateSession(token: string, currentUserAgentHash?: string): Promise<{
19
19
  userId: string;
20
20
  username: string;
21
21
  accessGroupId: string;
@@ -31,7 +31,7 @@ export declare function invalidateUserSessions(userId: string): Promise<number>;
31
31
  * Rotate a session token (sliding expiry).
32
32
  * @returns New token + expiry or null if session is invalid
33
33
  */
34
- export declare function refreshSession(token: string): Promise<{
34
+ export declare function refreshSession(token: string, currentUserAgentHash?: string): Promise<{
35
35
  token: string;
36
36
  expiresAt: string;
37
37
  } | null>;
@@ -9,14 +9,14 @@ import { generateToken } from './password.js';
9
9
  * Create a new session for a user.
10
10
  * @returns Session with plain-text token
11
11
  */
12
- export async function createSession(userId, device, ip) {
12
+ export async function createSession(userId, device, ip, userAgentHash) {
13
13
  const adapter = getDbAdapter();
14
14
  const sessionId = 'sess-' + crypto.randomUUID().slice(0, 8);
15
15
  const token = generateToken();
16
16
  const now = new Date();
17
17
  const expires = new Date(now.getTime() + 24 * 60 * 60 * 1000);
18
- await adapter.runAsync(`INSERT INTO sessions (session_id, user_id, token, device, ip_address, login_at, expires_at, is_active)
19
- VALUES (?, ?, ?, ?, ?, ?, ?, 1)`, [sessionId, userId, token, device || '', ip || '', now.toISOString(), expires.toISOString()]);
18
+ await adapter.runAsync(`INSERT INTO sessions (session_id, user_id, token, device, ip_address, user_agent_hash, login_at, expires_at, is_active)
19
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)`, [sessionId, userId, token, device || '', ip || '', userAgentHash || '', now.toISOString(), expires.toISOString()]);
20
20
  return {
21
21
  sessionId, userId, token,
22
22
  device, ipAddress: ip,
@@ -30,11 +30,14 @@ export async function createSession(userId, device, ip) {
30
30
  * Checks is_active, expiry, and user status.
31
31
  * @returns Session identity or null if invalid/expired
32
32
  */
33
- export async function validateSession(token) {
33
+ export async function validateSession(token, currentUserAgentHash) {
34
34
  const adapter = getDbAdapter();
35
- const row = await adapter.getAsync(`SELECT s.user_id, s.expires_at, s.is_active, u.username, u.access_group_id, u.status
35
+ const row = await adapter.getAsync(`SELECT s.user_id, s.expires_at, s.is_active, s.user_agent_hash, u.username, u.access_group_id, u.status
36
36
  FROM sessions s JOIN users u ON s.user_id = u.user_id
37
37
  WHERE s.token = ?`, [token]);
38
+ if (currentUserAgentHash && row?.user_agent_hash && row.user_agent_hash !== currentUserAgentHash) {
39
+ return null;
40
+ }
38
41
  if (!row)
39
42
  return null;
40
43
  if (!row.is_active)
@@ -67,13 +70,15 @@ export async function invalidateUserSessions(userId) {
67
70
  * Rotate a session token (sliding expiry).
68
71
  * @returns New token + expiry or null if session is invalid
69
72
  */
70
- export async function refreshSession(token) {
73
+ export async function refreshSession(token, currentUserAgentHash) {
71
74
  const adapter = getDbAdapter();
72
- const row = await adapter.getAsync(`SELECT s.user_id, s.expires_at, s.is_active, u.status
75
+ const row = await adapter.getAsync(`SELECT s.user_id, s.expires_at, s.is_active, s.user_agent_hash, u.status
73
76
  FROM sessions s JOIN users u ON s.user_id = u.user_id
74
77
  WHERE s.token = ?`, [token]);
75
78
  if (!row || !row.is_active || row.status !== 'ACTIVE')
76
79
  return null;
80
+ if (currentUserAgentHash && row.user_agent_hash && row.user_agent_hash !== currentUserAgentHash)
81
+ return null;
77
82
  if (new Date(row.expires_at) < new Date()) {
78
83
  await adapter.runAsync('UPDATE sessions SET is_active = 0 WHERE token = ?', [token]);
79
84
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/admin/db/sessions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/admin/db/sessions.ts"],"names":[],"mappings":"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"}
@@ -84,8 +84,8 @@ export async function createUser(username, email, password, accessGroupId) {
84
84
  const userId = 'user-' + crypto.randomUUID().slice(0, 8);
85
85
  const now = new Date().toISOString();
86
86
  const hash = hashPassword(password);
87
- await adapter.runAsync(`INSERT INTO users (user_id, username, email, password_hash, status, access_group_id, force_password_change, created_at)
88
- VALUES (?, ?, ?, ?, 'ACTIVE', ?, 1, ?)`, [userId, username, email, hash, accessGroupId, now]);
87
+ await adapter.runAsync(`INSERT INTO users (user_id, username, email, password_hash, status, access_group_id, force_password_change, created_at, account_type)
88
+ VALUES (?, ?, ?, ?, 'ACTIVE', ?, 1, ?, 'LOCAL')`, [userId, username, email, hash, accessGroupId, now]);
89
89
  return { userId, username, email, status: 'ACTIVE', accessGroupId, forcePasswordChange: true, createdAt: now };
90
90
  }
91
91
  /**