asaihost-nodejs 0.0.8 → 0.0.10

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 (44) hide show
  1. package/dist/InterventionLog-WNVDQFAH.cjs.map +1 -1
  2. package/dist/LogStore-AP4T2CFD.cjs.map +1 -1
  3. package/dist/asaihost-nodejs.cjs +778 -507
  4. package/dist/asaihost-nodejs.cjs.map +1 -1
  5. package/dist/asaihost-nodejs.es.js +391 -120
  6. package/dist/asaihost-nodejs.es.js.map +1 -1
  7. package/dist/chunk-2BCIIKRG.cjs.map +1 -1
  8. package/dist/{chunk-OTL2B4WS.es.js → chunk-3E4Y5ATG.es.js} +2 -2
  9. package/dist/{chunk-ZK4O4Z2O.cjs → chunk-5EWEKXQI.cjs} +20 -20
  10. package/dist/chunk-5EWEKXQI.cjs.map +1 -0
  11. package/dist/chunk-ARHPHWT5.cjs.map +1 -1
  12. package/dist/{chunk-GXOFLFFW.cjs → chunk-FRPN33BY.cjs} +3 -2
  13. package/dist/chunk-FRPN33BY.cjs.map +1 -0
  14. package/dist/{chunk-WXW5DYNU.cjs → chunk-H2QP5J7X.cjs} +9 -9
  15. package/dist/chunk-H2QP5J7X.cjs.map +1 -0
  16. package/dist/chunk-HR5JKN7Y.cjs.map +1 -1
  17. package/dist/{chunk-BOIRAQXE.es.js → chunk-M3NURHGU.es.js} +2 -1
  18. package/dist/chunk-O6LVLSNB.cjs.map +1 -1
  19. package/dist/chunk-OCEBEEP5.cjs.map +1 -1
  20. package/dist/chunk-SMVZ3ZDJ.cjs.map +1 -1
  21. package/dist/chunk-U2YJH2RW.cjs.map +1 -1
  22. package/dist/{chunk-5WJQD4RZ.es.js → chunk-UKZ3DP37.es.js} +3 -3
  23. package/dist/intervention-hooks-4NAAAZK3.cjs.map +1 -1
  24. package/dist/log-alert-LAJ6VSAG.cjs.map +1 -1
  25. package/dist/log-formats-TUXGMCCU.cjs.map +1 -1
  26. package/dist/{password-4P7IZUDQ.es.js → password-2ZBHQQBF.es.js} +3 -3
  27. package/dist/password-T762KJOI.cjs +20 -0
  28. package/dist/password-T762KJOI.cjs.map +1 -0
  29. package/dist/user-store-6QNAL4CK.cjs +12 -0
  30. package/dist/user-store-6QNAL4CK.cjs.map +1 -0
  31. package/dist/{user-store-FXD2N55G.es.js → user-store-ZI67TXSI.es.js} +3 -3
  32. package/package.json +1 -1
  33. package/dist/chunk-GXOFLFFW.cjs.map +0 -1
  34. package/dist/chunk-WXW5DYNU.cjs.map +0 -1
  35. package/dist/chunk-ZK4O4Z2O.cjs.map +0 -1
  36. package/dist/password-MDYRL6ZD.cjs +0 -20
  37. package/dist/password-MDYRL6ZD.cjs.map +0 -1
  38. package/dist/user-store-55HOLHEM.cjs +0 -12
  39. package/dist/user-store-55HOLHEM.cjs.map +0 -1
  40. /package/dist/{chunk-OTL2B4WS.es.js.map → chunk-3E4Y5ATG.es.js.map} +0 -0
  41. /package/dist/{chunk-BOIRAQXE.es.js.map → chunk-M3NURHGU.es.js.map} +0 -0
  42. /package/dist/{chunk-5WJQD4RZ.es.js.map → chunk-UKZ3DP37.es.js.map} +0 -0
  43. /package/dist/{password-4P7IZUDQ.es.js.map → password-2ZBHQQBF.es.js.map} +0 -0
  44. /package/dist/{user-store-FXD2N55G.es.js.map → user-store-ZI67TXSI.es.js.map} +0 -0
@@ -50,7 +50,7 @@ var _chunkO6LVLSNBcjs = require('./chunk-O6LVLSNB.cjs');
50
50
 
51
51
 
52
52
 
53
- var _chunkWXW5DYNUcjs = require('./chunk-WXW5DYNU.cjs');
53
+ var _chunkH2QP5J7Xcjs = require('./chunk-H2QP5J7X.cjs');
54
54
 
55
55
 
56
56
 
@@ -62,7 +62,7 @@ var _chunkWXW5DYNUcjs = require('./chunk-WXW5DYNU.cjs');
62
62
 
63
63
 
64
64
 
65
- var _chunkZK4O4Z2Ocjs = require('./chunk-ZK4O4Z2O.cjs');
65
+ var _chunk5EWEKXQIcjs = require('./chunk-5EWEKXQI.cjs');
66
66
 
67
67
 
68
68
 
@@ -75,7 +75,8 @@ var _chunkZK4O4Z2Ocjs = require('./chunk-ZK4O4Z2O.cjs');
75
75
 
76
76
 
77
77
 
78
- var _chunkGXOFLFFWcjs = require('./chunk-GXOFLFFW.cjs');
78
+
79
+ var _chunkFRPN33BYcjs = require('./chunk-FRPN33BY.cjs');
79
80
 
80
81
 
81
82
  var _chunk2BCIIKRGcjs = require('./chunk-2BCIIKRG.cjs');
@@ -814,8 +815,8 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, checkNtpOffset, "checkNtpOffset");
814
815
 
815
816
  // src/infra/config-integrity.ts
816
817
  var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
817
- var _fs = require('fs'); var fs3 = _interopRequireWildcard(_fs); var fs6 = _interopRequireWildcard(_fs); var fs4 = _interopRequireWildcard(_fs); var fs5 = _interopRequireWildcard(_fs); var fs8 = _interopRequireWildcard(_fs); var fs10 = _interopRequireWildcard(_fs);
818
- var _path = require('path'); var nodePath2 = _interopRequireWildcard(_path); var path2 = _interopRequireWildcard(_path); var nodePath = _interopRequireWildcard(_path); var nodePath3 = _interopRequireWildcard(_path); var path4 = _interopRequireWildcard(_path); var path6 = _interopRequireWildcard(_path); var path7 = _interopRequireWildcard(_path);
818
+ var _fs = require('fs'); var fs3 = _interopRequireWildcard(_fs); var fs6 = _interopRequireWildcard(_fs); var fs4 = _interopRequireWildcard(_fs); var fs5 = _interopRequireWildcard(_fs); var fs8 = _interopRequireWildcard(_fs); var fs11 = _interopRequireWildcard(_fs);
819
+ var _path = require('path'); var nodePath2 = _interopRequireWildcard(_path); var path2 = _interopRequireWildcard(_path); var nodePath = _interopRequireWildcard(_path); var nodePath3 = _interopRequireWildcard(_path); var path5 = _interopRequireWildcard(_path); var path7 = _interopRequireWildcard(_path); var path8 = _interopRequireWildcard(_path);
819
820
  function computeConfigHash(configPath) {
820
821
  try {
821
822
  const raw = fs3.default.readFileSync(configPath);
@@ -869,7 +870,7 @@ function initAsaiHostNodejs($asai, _opt) {
869
870
  resAES
870
871
  };
871
872
  }
872
- if (_chunkZK4O4Z2Ocjs.isDevDefaultPassword.call(void 0, _optionalChain([$asai, 'access', _102 => _102.hostconfig, 'optionalAccess', _103 => _103.password]) || "")) {
873
+ if (_chunk5EWEKXQIcjs.isDevDefaultPassword.call(void 0, _optionalChain([$asai, 'access', _102 => _102.hostconfig, 'optionalAccess', _103 => _103.password]) || "")) {
873
874
  logSecurityEvent($asai, {
874
875
  type: "CONFIG_WARN",
875
876
  detail: "Using dev-only password; set ASAI_HOST_PASSWORD for production (IEC 62443-4-2 CR 1.7)"
@@ -940,145 +941,296 @@ function deUserInfoWithAsai(userinfo, $asai) {
940
941
  }
941
942
  _chunkSMVZ3ZDJcjs.__name.call(void 0, deUserInfoWithAsai, "deUserInfoWithAsai");
942
943
 
944
+ // src/ws/ws-probe.ts
945
+
946
+ function isWsStillActive(ws2) {
947
+ if (!ws2) return false;
948
+ const state = ws2.readyState;
949
+ return state === _ws.WebSocket.CONNECTING || state === _ws.WebSocket.OPEN;
950
+ }
951
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, isWsStillActive, "isWsStillActive");
952
+ function getWsProbeTimeoutMs($asai) {
953
+ return _optionalChain([$asai, 'optionalAccess', _109 => _109.hostconfig, 'optionalAccess', _110 => _110.tm, 'optionalAccess', _111 => _111.d]) || 3e3;
954
+ }
955
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, getWsProbeTimeoutMs, "getWsProbeTimeoutMs");
956
+ function probeWsAlive($asai, wsclient, timeoutMs) {
957
+ const waitMs = _nullishCoalesce(timeoutMs, () => ( getWsProbeTimeoutMs($asai)));
958
+ return new Promise((resolve6) => {
959
+ if (!wsclient || !isWsStillActive(wsclient)) {
960
+ resolve6(false);
961
+ return;
962
+ }
963
+ let settled = false;
964
+ const finish = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (alive) => {
965
+ if (settled) return;
966
+ settled = true;
967
+ clearTimeout(timer);
968
+ try {
969
+ _optionalChain([wsclient, 'access', _112 => _112.off, 'optionalCall', _113 => _113("message", onMessage)]);
970
+ } catch (e16) {
971
+ }
972
+ resolve6(alive);
973
+ }, "finish");
974
+ const onMessage = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, () => finish(true), "onMessage");
975
+ const timer = setTimeout(() => finish(false), waitMs);
976
+ try {
977
+ _optionalChain([wsclient, 'access', _114 => _114.once, 'optionalCall', _115 => _115("message", onMessage)]);
978
+ wsclient.send(JSON.stringify({ ty: "publish/web", db: "pong" }));
979
+ } catch (e17) {
980
+ finish(false);
981
+ }
982
+ });
983
+ }
984
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, probeWsAlive, "probeWsAlive");
985
+ function terminateWs(wsclient) {
986
+ if (!wsclient) return;
987
+ try {
988
+ _optionalChain([wsclient, 'access', _116 => _116.terminate, 'optionalCall', _117 => _117()]);
989
+ } catch (e18) {
990
+ }
991
+ try {
992
+ _optionalChain([wsclient, 'access', _118 => _118.close, 'optionalCall', _119 => _119()]);
993
+ } catch (e19) {
994
+ }
995
+ }
996
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, terminateWs, "terminateWs");
997
+ async function clearStaleWsIfDead($asai, hostdir, us, existingWs) {
998
+ if (!us || us === "asai") return true;
999
+ const map = _optionalChain([$asai, 'access', _120 => _120.connectionsws, 'optionalAccess', _121 => _121[hostdir]]);
1000
+ if (!existingWs) {
1001
+ if (_optionalChain([map, 'optionalAccess', _122 => _122[us]])) delete map[us];
1002
+ return true;
1003
+ }
1004
+ if (existingWs._asaiKicked) {
1005
+ terminateWs(existingWs);
1006
+ if (_optionalChain([map, 'optionalAccess', _123 => _123[us]]) === existingWs) delete map[us];
1007
+ return true;
1008
+ }
1009
+ if (!isWsStillActive(existingWs)) {
1010
+ terminateWs(existingWs);
1011
+ if (_optionalChain([map, 'optionalAccess', _124 => _124[us]]) === existingWs) delete map[us];
1012
+ return true;
1013
+ }
1014
+ const alive = await probeWsAlive($asai, existingWs);
1015
+ if (alive) return false;
1016
+ terminateWs(existingWs);
1017
+ if (_optionalChain([map, 'optionalAccess', _125 => _125[us]]) === existingWs) delete map[us];
1018
+ return true;
1019
+ }
1020
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, clearStaleWsIfDead, "clearStaleWsIfDead");
1021
+
943
1022
  // src/ws/auth.ts
944
1023
  function getWsUserinfo(req, $asai) {
945
1024
  try {
946
- const raw = _optionalChain([req, 'access', _109 => _109.headers, 'optionalAccess', _110 => _110["sec-websocket-protocol"]]);
1025
+ const raw = _optionalChain([req, 'access', _126 => _126.headers, 'optionalAccess', _127 => _127["sec-websocket-protocol"]]);
947
1026
  if (!raw) return null;
948
1027
  return deUserInfoWithAsai(raw.split("##"), $asai);
949
- } catch (e16) {
1028
+ } catch (e20) {
950
1029
  return null;
951
1030
  }
952
1031
  }
953
1032
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getWsUserinfo, "getWsUserinfo");
954
1033
  function listOnlineWsUsers($asai, hostdir) {
1034
+ return listOnlineWsEntries($asai, hostdir).map((e) => e.us);
1035
+ }
1036
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, listOnlineWsUsers, "listOnlineWsUsers");
1037
+ function listOnlineWsEntries($asai, hostdir) {
955
1038
  const users = [];
1039
+ const seen = /* @__PURE__ */ new Set();
956
1040
  const map = $asai.connectionsws || {};
957
1041
  const dirs = hostdir ? [hostdir] : Object.keys(map);
958
1042
  for (const dir of dirs) {
959
1043
  for (const [us, ws2] of Object.entries(map[dir] || {})) {
960
1044
  if (!us || us === "asai") continue;
961
1045
  if (isWsStillActive(ws2)) {
962
- users.push(us);
963
- } else if (_optionalChain([map, 'access', _111 => _111[dir], 'optionalAccess', _112 => _112[us]]) === ws2) {
1046
+ if (seen.has(us)) continue;
1047
+ seen.add(us);
1048
+ const rawLv = _optionalChain([ws2, 'optionalAccess', _128 => _128.Userinfo, 'optionalAccess', _129 => _129[1]]);
1049
+ if (rawLv === "" || rawLv == null) {
1050
+ users.push({ us, lv: null });
1051
+ } else {
1052
+ const lvNum = Number(rawLv);
1053
+ users.push({
1054
+ us,
1055
+ lv: Number.isFinite(lvNum) ? lvNum : null
1056
+ });
1057
+ }
1058
+ } else if (_optionalChain([map, 'access', _130 => _130[dir], 'optionalAccess', _131 => _131[us]]) === ws2) {
964
1059
  delete map[dir][us];
965
1060
  }
966
1061
  }
967
1062
  }
968
- return [...new Set(users)];
1063
+ return users;
969
1064
  }
970
- _chunkSMVZ3ZDJcjs.__name.call(void 0, listOnlineWsUsers, "listOnlineWsUsers");
1065
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, listOnlineWsEntries, "listOnlineWsEntries");
971
1066
  function isUserOnlineOnWs($asai, us, hostdir) {
972
1067
  if (!us || us === "asai") return false;
973
1068
  const map = $asai.connectionsws || {};
974
1069
  const dirs = hostdir ? [hostdir] : Object.keys(map);
975
1070
  for (const dir of dirs) {
976
- const ws2 = _optionalChain([map, 'access', _113 => _113[dir], 'optionalAccess', _114 => _114[us]]);
1071
+ const ws2 = _optionalChain([map, 'access', _132 => _132[dir], 'optionalAccess', _133 => _133[us]]);
977
1072
  if (!ws2) continue;
978
1073
  if (isWsStillActive(ws2)) return true;
979
- if (_optionalChain([map, 'access', _115 => _115[dir], 'optionalAccess', _116 => _116[us]]) === ws2) delete map[dir][us];
1074
+ if (_optionalChain([map, 'access', _134 => _134[dir], 'optionalAccess', _135 => _135[us]]) === ws2) delete map[dir][us];
980
1075
  }
981
1076
  return false;
982
1077
  }
983
1078
  _chunkSMVZ3ZDJcjs.__name.call(void 0, isUserOnlineOnWs, "isUserOnlineOnWs");
984
- function kickUserWs($asai, us, hostdir) {
1079
+ async function kickUserWs($asai, us, hostdir) {
985
1080
  if (!us || us === "asai") return;
986
1081
  const map = $asai.connectionsws || {};
987
1082
  const dirs = hostdir ? [hostdir] : Object.keys(map);
1083
+ const waits = [];
988
1084
  for (const dir of dirs) {
989
- const ws2 = _optionalChain([map, 'access', _117 => _117[dir], 'optionalAccess', _118 => _118[us]]);
1085
+ const ws2 = _optionalChain([map, 'access', _136 => _136[dir], 'optionalAccess', _137 => _137[us]]);
990
1086
  if (!ws2) continue;
1087
+ if (_optionalChain([map, 'access', _138 => _138[dir], 'optionalAccess', _139 => _139[us]]) === ws2) delete map[dir][us];
991
1088
  try {
992
- ws2.close();
993
- } catch (e17) {
1089
+ ws2._asaiKicked = Date.now();
1090
+ } catch (e21) {
994
1091
  }
995
- if (_optionalChain([map, 'access', _119 => _119[dir], 'optionalAccess', _120 => _120[us]]) === ws2) delete map[dir][us];
1092
+ waits.push(
1093
+ new Promise((resolve6) => {
1094
+ let done = false;
1095
+ const finish = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, () => {
1096
+ if (done) return;
1097
+ done = true;
1098
+ try {
1099
+ _optionalChain([ws2, 'access', _140 => _140.off, 'optionalCall', _141 => _141("close", finish)]);
1100
+ } catch (e22) {
1101
+ }
1102
+ resolve6();
1103
+ }, "finish");
1104
+ try {
1105
+ _optionalChain([ws2, 'access', _142 => _142.once, 'optionalCall', _143 => _143("close", finish)]);
1106
+ } catch (e23) {
1107
+ }
1108
+ const payload = JSON.stringify({
1109
+ ty: "publish/web",
1110
+ db: {
1111
+ exit: 1,
1112
+ type: "err",
1113
+ lang: "forcedout",
1114
+ langpm: `${us}`,
1115
+ con: `${us} forced out by another login`
1116
+ }
1117
+ });
1118
+ const hardClose = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, () => {
1119
+ try {
1120
+ if (typeof ws2.terminate === "function") ws2.terminate();
1121
+ else ws2.close();
1122
+ } catch (e24) {
1123
+ try {
1124
+ ws2.close();
1125
+ } catch (e25) {
1126
+ }
1127
+ }
1128
+ }, "hardClose");
1129
+ try {
1130
+ ws2.send(payload, () => {
1131
+ hardClose();
1132
+ finish();
1133
+ });
1134
+ } catch (e26) {
1135
+ hardClose();
1136
+ finish();
1137
+ }
1138
+ setTimeout(() => {
1139
+ hardClose();
1140
+ finish();
1141
+ }, 150);
1142
+ })
1143
+ );
996
1144
  }
1145
+ if (waits.length) await Promise.all(waits);
997
1146
  }
998
1147
  _chunkSMVZ3ZDJcjs.__name.call(void 0, kickUserWs, "kickUserWs");
999
1148
  async function removeSessionOnWsClose($asai, us, token) {
1000
1149
  try {
1001
- const store = _chunkZK4O4Z2Ocjs.createUserStore.call(void 0, $asai);
1150
+ const store = _chunk5EWEKXQIcjs.createUserStore.call(void 0, $asai);
1002
1151
  const sessions = await store.getSessions();
1003
1152
  const match = sessions.find((s) => s.us === us && s.pub === token);
1004
1153
  if (match) await store.removeSession(match.id);
1005
- } catch (e18) {
1154
+ } catch (e27) {
1006
1155
  }
1007
1156
  }
1008
1157
  _chunkSMVZ3ZDJcjs.__name.call(void 0, removeSessionOnWsClose, "removeSessionOnWsClose");
1009
- function isWsStillActive(ws2) {
1010
- if (!ws2) return false;
1011
- const state = ws2.readyState;
1012
- return state === _ws.WebSocket.CONNECTING || state === _ws.WebSocket.OPEN;
1013
- }
1014
- _chunkSMVZ3ZDJcjs.__name.call(void 0, isWsStillActive, "isWsStillActive");
1015
1158
  function rejectIncomingWs(ws2, db) {
1016
1159
  const payload = JSON.stringify({ ty: "publish/web", db: { exit: 1, type: "err", ...db } });
1017
1160
  try {
1018
1161
  ws2.send(payload, () => {
1019
1162
  try {
1020
1163
  ws2.close();
1021
- } catch (e19) {
1164
+ } catch (e28) {
1022
1165
  }
1023
1166
  });
1024
- } catch (e20) {
1167
+ } catch (e29) {
1025
1168
  try {
1026
1169
  ws2.close();
1027
- } catch (e21) {
1170
+ } catch (e30) {
1028
1171
  }
1029
1172
  }
1030
1173
  }
1031
1174
  _chunkSMVZ3ZDJcjs.__name.call(void 0, rejectIncomingWs, "rejectIncomingWs");
1032
- function isOkWs($asai, hostdir, ws2, _req, hostcfg) {
1175
+ async function isOkWs($asai, hostdir, ws2, _req, hostcfg) {
1033
1176
  const [us, , tk] = ws2.Userinfo || [];
1034
1177
  if (!us) {
1035
1178
  ws2.close();
1036
1179
  return false;
1037
1180
  }
1038
- if (us !== "asai" && _optionalChain([$asai, 'access', _121 => _121.connectionsws, 'access', _122 => _122[hostdir], 'optionalAccess', _123 => _123[us]])) {
1181
+ if (us !== "asai" && _optionalChain([$asai, 'access', _144 => _144.connectionsws, 'access', _145 => _145[hostdir], 'optionalAccess', _146 => _146[us]])) {
1039
1182
  const existingWs = $asai.connectionsws[hostdir][us];
1040
- if (_optionalChain([existingWs, 'optionalAccess', _124 => _124.Userinfo, 'optionalAccess', _125 => _125[2]]) === tk) {
1183
+ if (_optionalChain([existingWs, 'optionalAccess', _147 => _147.Userinfo, 'optionalAccess', _148 => _148[2]]) === tk) {
1041
1184
  if (isWsStillActive(existingWs)) {
1042
1185
  rejectIncomingWs(ws2, {
1043
1186
  lang: "pageworking",
1044
1187
  langpm: `${us}`,
1045
- con: `${us} page already running`
1188
+ con: `${us} page already running`,
1189
+ online: listOnlineWsEntries($asai, hostdir)
1046
1190
  });
1047
1191
  return false;
1048
1192
  }
1049
1193
  try {
1050
1194
  existingWs.close();
1051
- } catch (e22) {
1195
+ } catch (e31) {
1052
1196
  }
1053
1197
  delete $asai.connectionsws[hostdir][us];
1054
1198
  return true;
1055
1199
  }
1056
- rejectIncomingWs(ws2, {
1057
- lang: "logged",
1058
- langpm: `${us}`,
1059
- con: `${us} logged in!`
1060
- });
1061
- return false;
1200
+ const cleared = await clearStaleWsIfDead($asai, hostdir, us, existingWs);
1201
+ if (!cleared) {
1202
+ rejectIncomingWs(ws2, {
1203
+ lang: "logged",
1204
+ langpm: `${us}`,
1205
+ con: `${us} logged in!`,
1206
+ online: listOnlineWsEntries($asai, hostdir)
1207
+ });
1208
+ return false;
1209
+ }
1210
+ return true;
1062
1211
  }
1063
1212
  if (us !== "asai") {
1064
1213
  const connections = $asai.connectionsws[hostdir] || {};
1065
1214
  const sameTkWs = Object.values(connections).find(
1066
- (item) => _optionalChain([item, 'access', _126 => _126.Userinfo, 'optionalAccess', _127 => _127[2]]) === tk && _optionalChain([item, 'access', _128 => _128.Userinfo, 'optionalAccess', _129 => _129[0]]) !== us
1215
+ (item) => _optionalChain([item, 'access', _149 => _149.Userinfo, 'optionalAccess', _150 => _150[2]]) === tk && _optionalChain([item, 'access', _151 => _151.Userinfo, 'optionalAccess', _152 => _152[0]]) !== us
1067
1216
  );
1068
1217
  const maxOnline = hostcfg.maxonline || 100;
1218
+ const online = listOnlineWsEntries($asai, hostdir);
1069
1219
  if (sameTkWs) {
1070
1220
  rejectIncomingWs(ws2, {
1071
1221
  lang: "loggedsametk",
1072
1222
  langpm: `${us}(${sameTkWs.Userinfo[0]})`,
1073
- con: `${us}(${sameTkWs.Userinfo[0]}) logged in!`
1223
+ con: `${us}(${sameTkWs.Userinfo[0]}) logged in!`,
1224
+ online
1074
1225
  });
1075
1226
  return false;
1076
1227
  }
1077
- if (Object.keys(connections).length >= maxOnline) {
1228
+ if (online.length >= maxOnline) {
1078
1229
  rejectIncomingWs(ws2, {
1079
1230
  lang: "maxlogged",
1080
1231
  langpm: `${maxOnline}`,
1081
- con: `max ${maxOnline} users online!`
1232
+ con: `max ${maxOnline} users online!`,
1233
+ online
1082
1234
  });
1083
1235
  return false;
1084
1236
  }
@@ -1097,15 +1249,15 @@ function loginWs($asai, hostdir, ws2, req, hostcfg, wsWorkHandler, logWsMessage)
1097
1249
  }
1098
1250
  ws2.on("message", (msg) => {
1099
1251
  if (logWsMessage) $asai.$log("WS", "message", msg.toString());
1100
- _optionalChain([wsWorkHandler, 'optionalCall', _130 => _130(msg, ws2, hostdir, req)]);
1252
+ _optionalChain([wsWorkHandler, 'optionalCall', _153 => _153(msg, ws2, hostdir, req)]);
1101
1253
  });
1102
1254
  ws2.on("close", () => {
1103
- const token = _optionalChain([ws2, 'access', _131 => _131.Userinfo, 'optionalAccess', _132 => _132[2]]);
1255
+ const token = _optionalChain([ws2, 'access', _154 => _154.Userinfo, 'optionalAccess', _155 => _155[2]]);
1104
1256
  if (hostcfg.ckws && ws2.tasksws) {
1105
1257
  Object.values(ws2.tasksws).forEach((el) => el && clearInterval(el));
1106
1258
  ws2.tasksws = void 0;
1107
1259
  }
1108
- if (us && _optionalChain([$asai, 'access', _133 => _133.connectionsws, 'access', _134 => _134[hostdir], 'optionalAccess', _135 => _135[us]]) === ws2) delete $asai.connectionsws[hostdir][us];
1260
+ if (us && _optionalChain([$asai, 'access', _156 => _156.connectionsws, 'access', _157 => _157[hostdir], 'optionalAccess', _158 => _158[us]]) === ws2) delete $asai.connectionsws[hostdir][us];
1109
1261
  if (us && token && !isUserOnlineOnWs($asai, us, hostdir)) {
1110
1262
  void removeSessionOnWsClose($asai, us, String(token));
1111
1263
  }
@@ -1129,7 +1281,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, clearWsServerTasks, "clearWsServerTasks");
1129
1281
  function resWsMsg(msg, $asai) {
1130
1282
  if (msg === "ping" || msg === "pong") return msg;
1131
1283
  if (typeof msg !== "object" || msg === null) return msg;
1132
- if ((_optionalChain([msg, 'optionalAccess', _136 => _136.aes]) || _optionalChain([$asai, 'access', _137 => _137.$lib, 'access', _138 => _138.aesfns, 'optionalAccess', _139 => _139.allaes])) && _optionalChain([msg, 'optionalAccess', _140 => _140.db]) && _optionalChain([$asai, 'access', _141 => _141.$lib, 'optionalAccess', _142 => _142.aesfns, 'optionalAccess', _143 => _143.resAES])) {
1284
+ if ((_optionalChain([msg, 'optionalAccess', _159 => _159.aes]) || _optionalChain([$asai, 'access', _160 => _160.$lib, 'access', _161 => _161.aesfns, 'optionalAccess', _162 => _162.allaes])) && _optionalChain([msg, 'optionalAccess', _163 => _163.db]) && _optionalChain([$asai, 'access', _164 => _164.$lib, 'optionalAccess', _165 => _165.aesfns, 'optionalAccess', _166 => _166.resAES])) {
1133
1285
  msg.db = $asai.$lib.aesfns.resAES(msg.db);
1134
1286
  }
1135
1287
  return JSON.stringify(msg);
@@ -1151,7 +1303,7 @@ function attachWssHelpers(wss, $asai) {
1151
1303
  wss.broadws = (msg) => {
1152
1304
  const data = resWsMsg(msg, $asai);
1153
1305
  wss.clients.forEach((client) => {
1154
- if (_optionalChain([client, 'optionalAccess', _144 => _144.readyState]) === _ws.WebSocket.OPEN) client.send(data);
1306
+ if (_optionalChain([client, 'optionalAccess', _167 => _167.readyState]) === _ws.WebSocket.OPEN) client.send(data);
1155
1307
  });
1156
1308
  };
1157
1309
  }
@@ -1164,7 +1316,7 @@ var apiPerIp = /* @__PURE__ */ new Map();
1164
1316
  var apiRatePerIp = /* @__PURE__ */ new Map();
1165
1317
  var wsPerIp = /* @__PURE__ */ new Map();
1166
1318
  function getQuota($asai) {
1167
- return _optionalChain([$asai, 'optionalAccess', _145 => _145.hostconfig, 'optionalAccess', _146 => _146.security, 'optionalAccess', _147 => _147.quota]) || {};
1319
+ return _optionalChain([$asai, 'optionalAccess', _168 => _168.hostconfig, 'optionalAccess', _169 => _169.security, 'optionalAccess', _170 => _170.quota]) || {};
1168
1320
  }
1169
1321
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getQuota, "getQuota");
1170
1322
  function isEnabled($asai) {
@@ -1254,7 +1406,7 @@ function getMaxWebConnections($asai, hostcfg) {
1254
1406
  const q = getQuota($asai);
1255
1407
  const fromQuota = Number(q.maxWebConnections);
1256
1408
  if (fromQuota > 0) return fromQuota;
1257
- return Number(_optionalChain([hostcfg, 'optionalAccess', _148 => _148.maxws])) > 0 ? Number(hostcfg.maxws) : 100;
1409
+ return Number(_optionalChain([hostcfg, 'optionalAccess', _171 => _171.maxws])) > 0 ? Number(hostcfg.maxws) : 100;
1258
1410
  }
1259
1411
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getMaxWebConnections, "getMaxWebConnections");
1260
1412
  function countActiveWsConnections(wss, incoming, $asai, hostdir, hostcfg, userinfo) {
@@ -1264,12 +1416,12 @@ function countActiveWsConnections(wss, incoming, $asai, hostdir, hostcfg, userin
1264
1416
  if (client === incoming) continue;
1265
1417
  if (client.readyState === _ws.WebSocket.CLOSED || client.readyState === _ws.WebSocket.CLOSING) continue;
1266
1418
  const cInfo = client.Userinfo;
1267
- const cUs = _optionalChain([cInfo, 'optionalAccess', _149 => _149[0]]);
1268
- const cTk = _optionalChain([cInfo, 'optionalAccess', _150 => _150[2]]);
1419
+ const cUs = _optionalChain([cInfo, 'optionalAccess', _172 => _172[0]]);
1420
+ const cTk = _optionalChain([cInfo, 'optionalAccess', _173 => _173[2]]);
1269
1421
  if (us && tk && cUs === us && cTk === tk) continue;
1270
- if (_optionalChain([hostcfg, 'optionalAccess', _151 => _151.ckws]) && us && tk) {
1271
- const existing = _optionalChain([$asai, 'optionalAccess', _152 => _152.connectionsws, 'optionalAccess', _153 => _153[hostdir], 'optionalAccess', _154 => _154[us]]);
1272
- if (existing === client && _optionalChain([existing, 'optionalAccess', _155 => _155.Userinfo, 'optionalAccess', _156 => _156[2]]) === tk) continue;
1422
+ if (_optionalChain([hostcfg, 'optionalAccess', _174 => _174.ckws]) && us && tk) {
1423
+ const existing = _optionalChain([$asai, 'optionalAccess', _175 => _175.connectionsws, 'optionalAccess', _176 => _176[hostdir], 'optionalAccess', _177 => _177[us]]);
1424
+ if (existing === client && _optionalChain([existing, 'optionalAccess', _178 => _178.Userinfo, 'optionalAccess', _179 => _179[2]]) === tk) continue;
1273
1425
  }
1274
1426
  count += 1;
1275
1427
  }
@@ -1281,7 +1433,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, countActiveWsConnections, "countActiveWsCo
1281
1433
  function createWSHost($asai, hostdir) {
1282
1434
  const hostcfg = getHostCFG(hostdir, $asai);
1283
1435
  const wsWorkHandler = getWorkHandler("wsWork");
1284
- const logWsMessage = !!_optionalChain([$asai, 'access', _157 => _157.hostconfig, 'access', _158 => _158.logger, 'optionalAccess', _159 => _159.lv, 'optionalAccess', _160 => _160.view]);
1436
+ const logWsMessage = !!_optionalChain([$asai, 'access', _180 => _180.hostconfig, 'access', _181 => _181.logger, 'optionalAccess', _182 => _182.lv, 'optionalAccess', _183 => _183.view]);
1285
1437
  try {
1286
1438
  if ($asai.serversws[hostdir]) return;
1287
1439
  if (hostcfg.ckws && !$asai.connectionsws[hostdir]) {
@@ -1293,14 +1445,14 @@ function createWSHost($asai, hostdir) {
1293
1445
  wss.on("error", (err) => {
1294
1446
  clearWsServerTasks($asai, hostdir);
1295
1447
  $asai.$log("WS", "WS Server error!", err);
1296
- _optionalChain([wss, 'access', _161 => _161.close, 'optionalCall', _162 => _162(() => {
1448
+ _optionalChain([wss, 'access', _184 => _184.close, 'optionalCall', _185 => _185(() => {
1297
1449
  $asai.$log("WS", "WS Server closed");
1298
1450
  delete $asai.serversws[hostdir];
1299
1451
  })]);
1300
1452
  });
1301
1453
  wss.on("close", (code, reason) => {
1302
1454
  try {
1303
- $asai.$log("WS", `WebSocket closed, server ${hostdir}, code: ${code}, reason: ${_optionalChain([reason, 'optionalAccess', _163 => _163.toString, 'call', _164 => _164()])}`);
1455
+ $asai.$log("WS", `WebSocket closed, server ${hostdir}, code: ${code}, reason: ${_optionalChain([reason, 'optionalAccess', _186 => _186.toString, 'call', _187 => _187()])}`);
1304
1456
  clearWsServerTasks($asai, hostdir);
1305
1457
  } catch (err) {
1306
1458
  $asai.$log("WS", "WS close handler error:", err);
@@ -1331,12 +1483,14 @@ function createWSHost($asai, hostdir) {
1331
1483
  ws2.send(wsmsg, () => ws2.close(1013, "Server busy"));
1332
1484
  return;
1333
1485
  }
1334
- const isOpen = !hostcfg.ckws || isOkWs($asai, hostdir, ws2, req, hostcfg);
1335
- if (isOpen) {
1336
- loginWs($asai, hostdir, ws2, req, hostcfg, wsWorkHandler, logWsMessage);
1337
- } else {
1338
- ws2.close();
1339
- }
1486
+ void (async () => {
1487
+ const isOpen = !hostcfg.ckws || await isOkWs($asai, hostdir, ws2, req, hostcfg);
1488
+ if (isOpen) {
1489
+ loginWs($asai, hostdir, ws2, req, hostcfg, wsWorkHandler, logWsMessage);
1490
+ } else {
1491
+ ws2.close();
1492
+ }
1493
+ })();
1340
1494
  });
1341
1495
  $asai.serversws[hostdir] = wss;
1342
1496
  } catch (err) {
@@ -1388,7 +1542,7 @@ var StaticPathCache = class {
1388
1542
  const stat = fs3.statSync(entry.filePath);
1389
1543
  if (!stat.isFile() || stat.mtimeMs !== entry.mtimeMs) return null;
1390
1544
  return stat;
1391
- } catch (e23) {
1545
+ } catch (e32) {
1392
1546
  return null;
1393
1547
  }
1394
1548
  }
@@ -1407,8 +1561,8 @@ function applySecurityHeaders(res, isHttps = false, hostconfig) {
1407
1561
  if (isHttps) {
1408
1562
  res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
1409
1563
  }
1410
- const sec = _optionalChain([hostconfig, 'optionalAccess', _165 => _165.security]);
1411
- if (_optionalChain([sec, 'optionalAccess', _166 => _166.csp])) {
1564
+ const sec = _optionalChain([hostconfig, 'optionalAccess', _188 => _188.security]);
1565
+ if (_optionalChain([sec, 'optionalAccess', _189 => _189.csp])) {
1412
1566
  const csp = typeof sec.cspPolicy === "string" && sec.cspPolicy.length > 0 ? sec.cspPolicy : DEFAULT_CSP;
1413
1567
  res.setHeader("Content-Security-Policy", csp);
1414
1568
  }
@@ -1416,9 +1570,9 @@ function applySecurityHeaders(res, isHttps = false, hostconfig) {
1416
1570
  _chunkSMVZ3ZDJcjs.__name.call(void 0, applySecurityHeaders, "applySecurityHeaders");
1417
1571
  function getHttpUserinfo(req, $asai) {
1418
1572
  try {
1419
- const userinfo = _optionalChain([req, 'access', _167 => _167.headers, 'optionalAccess', _168 => _168["userinfo"], 'optionalAccess', _169 => _169.split, 'call', _170 => _170("##")]);
1573
+ const userinfo = _optionalChain([req, 'access', _190 => _190.headers, 'optionalAccess', _191 => _191["userinfo"], 'optionalAccess', _192 => _192.split, 'call', _193 => _193("##")]);
1420
1574
  return deUserInfoWithAsai(userinfo, $asai);
1421
- } catch (e24) {
1575
+ } catch (e33) {
1422
1576
  return "";
1423
1577
  }
1424
1578
  }
@@ -1449,7 +1603,7 @@ function normalizeRequestPath(url) {
1449
1603
  }
1450
1604
  _chunkSMVZ3ZDJcjs.__name.call(void 0, normalizeRequestPath, "normalizeRequestPath");
1451
1605
  function createSkipChecker($asai) {
1452
- const skip = _optionalChain([$asai, 'access', _171 => _171.hostconfig, 'optionalAccess', _172 => _172.logger, 'optionalAccess', _173 => _173.skip]);
1606
+ const skip = _optionalChain([$asai, 'access', _194 => _194.hostconfig, 'optionalAccess', _195 => _195.logger, 'optionalAccess', _196 => _196.skip]);
1453
1607
  if (!Array.isArray(skip) || skip.length === 0) return () => false;
1454
1608
  const exact = /* @__PURE__ */ new Set();
1455
1609
  const prefixes = [];
@@ -1460,11 +1614,11 @@ function createSkipChecker($asai) {
1460
1614
  }
1461
1615
  if (exact.size === 0 && prefixes.length === 0) return () => false;
1462
1616
  return (url) => {
1463
- const path8 = normalizeRequestPath(url);
1464
- if (!path8) return false;
1465
- if (exact.has(path8)) return true;
1617
+ const path9 = normalizeRequestPath(url);
1618
+ if (!path9) return false;
1619
+ if (exact.has(path9)) return true;
1466
1620
  for (let i = 0; i < prefixes.length; i++) {
1467
- if (path8.startsWith(prefixes[i])) return true;
1621
+ if (path9.startsWith(prefixes[i])) return true;
1468
1622
  }
1469
1623
  return false;
1470
1624
  };
@@ -1485,7 +1639,7 @@ function attachAccessLog($asai, req, res, logType) {
1485
1639
  try {
1486
1640
  const entry = _chunkOCEBEEP5cjs.buildAccessEntry.call(void 0, req, res, logType);
1487
1641
  void $asai.appendAccessLog(_chunkOCEBEEP5cjs.formatCLF.call(void 0, entry), _chunkOCEBEEP5cjs.formatW3CAccessRecord.call(void 0, entry));
1488
- } catch (e25) {
1642
+ } catch (e34) {
1489
1643
  }
1490
1644
  }, "onFinish");
1491
1645
  if (res.writableEnded || res.finished) onFinish();
@@ -1544,7 +1698,7 @@ function findExistingFileUnderRoots(requestedPath, allowedRoots) {
1544
1698
  if (stat.isFile()) {
1545
1699
  return { filePath: absTarget, stat };
1546
1700
  }
1547
- } catch (e26) {
1701
+ } catch (e35) {
1548
1702
  }
1549
1703
  }
1550
1704
  return null;
@@ -1557,13 +1711,13 @@ function getHostAllowedRoots(hostconfig) {
1557
1711
  try {
1558
1712
  const abs = path2.resolve("./" + dir.replace(/\\/g, "/"));
1559
1713
  if (fs4.existsSync(abs)) roots.add(abs);
1560
- } catch (e27) {
1714
+ } catch (e36) {
1561
1715
  }
1562
1716
  }, "push");
1563
- for (const dir of _optionalChain([hostconfig, 'optionalAccess', _174 => _174.hostdirs]) || []) push(dir);
1717
+ for (const dir of _optionalChain([hostconfig, 'optionalAccess', _197 => _197.hostdirs]) || []) push(dir);
1564
1718
  push("webdata");
1565
1719
  push("websys");
1566
- if (_optionalChain([hostconfig, 'optionalAccess', _175 => _175.weburls, 'optionalAccess', _176 => _176.webdir])) push(hostconfig.weburls.webdir);
1720
+ if (_optionalChain([hostconfig, 'optionalAccess', _198 => _198.weburls, 'optionalAccess', _199 => _199.webdir])) push(hostconfig.weburls.webdir);
1567
1721
  const result = [];
1568
1722
  roots.forEach((r) => result.push(r));
1569
1723
  return result;
@@ -1594,7 +1748,7 @@ function getStaticBaseDirs($asai) {
1594
1748
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getStaticBaseDirs, "getStaticBaseDirs");
1595
1749
  function shouldForceHostdirs($asai) {
1596
1750
  if ($asai.pkgSnapshotDir) return true;
1597
- return _optionalChain([$asai, 'access', _177 => _177.hostconfig, 'optionalAccess', _178 => _178.pkg, 'optionalAccess', _179 => _179.type]) === 1;
1751
+ return _optionalChain([$asai, 'access', _200 => _200.hostconfig, 'optionalAccess', _201 => _201.pkg, 'optionalAccess', _202 => _202.type]) === 1;
1598
1752
  }
1599
1753
  _chunkSMVZ3ZDJcjs.__name.call(void 0, shouldForceHostdirs, "shouldForceHostdirs");
1600
1754
  function buildStaticSearchDirs(hostcfg, $asai) {
@@ -1615,12 +1769,12 @@ function buildStaticSearchDirs(hostcfg, $asai) {
1615
1769
  ordered.push(dir);
1616
1770
  return;
1617
1771
  }
1618
- } catch (e28) {
1772
+ } catch (e37) {
1619
1773
  }
1620
1774
  }
1621
1775
  }, "pushDir");
1622
1776
  for (const dir of hostcfg.hostdirs || []) pushDir(dir);
1623
- if (_optionalChain([hostcfg, 'access', _180 => _180.weburls, 'optionalAccess', _181 => _181.webdir])) pushDir(hostcfg.weburls.webdir);
1777
+ if (_optionalChain([hostcfg, 'access', _203 => _203.weburls, 'optionalAccess', _204 => _204.webdir])) pushDir(hostcfg.weburls.webdir);
1624
1778
  return ordered;
1625
1779
  }
1626
1780
  _chunkSMVZ3ZDJcjs.__name.call(void 0, buildStaticSearchDirs, "buildStaticSearchDirs");
@@ -1648,7 +1802,7 @@ function parseUrlPath(requrl) {
1648
1802
  if (!requrl) return "/";
1649
1803
  const safeUrl = requrl.startsWith("http") ? requrl : encodeURI(requrl);
1650
1804
  return new URL(safeUrl, "http://localhost").pathname;
1651
- } catch (e29) {
1805
+ } catch (e38) {
1652
1806
  return requrl;
1653
1807
  }
1654
1808
  }
@@ -1747,8 +1901,8 @@ function serveStaticFile(req, res, foundPath, mimeType, stat, $asai, urlPath = "
1747
1901
  _chunkSMVZ3ZDJcjs.__name.call(void 0, serveStaticFile, "serveStaticFile");
1748
1902
  function createStaticHandler(ctx) {
1749
1903
  const { hostcfg, hostdir, indexFile, $asai, staticPathCache } = ctx;
1750
- const hasRewrite = !!(_optionalChain([hostcfg, 'access', _182 => _182.weburls, 'optionalAccess', _183 => _183.rewrite]) && _optionalChain([hostcfg, 'access', _184 => _184.weburls, 'optionalAccess', _185 => _185.webdir]) && _optionalChain([hostcfg, 'access', _186 => _186.weburls, 'optionalAccess', _187 => _187.keys, 'optionalAccess', _188 => _188.length]));
1751
- const rewriteKeys = hasRewrite ? _optionalChain([hostcfg, 'access', _189 => _189.weburls, 'optionalAccess', _190 => _190.keys]) || [] : [];
1904
+ const hasRewrite = !!(_optionalChain([hostcfg, 'access', _205 => _205.weburls, 'optionalAccess', _206 => _206.rewrite]) && _optionalChain([hostcfg, 'access', _207 => _207.weburls, 'optionalAccess', _208 => _208.webdir]) && _optionalChain([hostcfg, 'access', _209 => _209.weburls, 'optionalAccess', _210 => _210.keys, 'optionalAccess', _211 => _211.length]));
1905
+ const rewriteKeys = hasRewrite ? _optionalChain([hostcfg, 'access', _212 => _212.weburls, 'optionalAccess', _213 => _213.keys]) || [] : [];
1752
1906
  const checkWebUrls = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (rurl) => {
1753
1907
  if (!hasRewrite || !rurl) return false;
1754
1908
  for (let i = 0; i < rewriteKeys.length; i++) {
@@ -1763,7 +1917,7 @@ function createStaticHandler(ctx) {
1763
1917
  const roots = rhostdirs.join("|") === primaryDirs.join("|") ? buildStaticRoots(primaryDirs, $asai) : buildStaticRoots(rhostdirs, $asai);
1764
1918
  const findValidFile = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (urlPath) => {
1765
1919
  const hit = staticPathCache.get(cacheKey);
1766
- if (_optionalChain([hit, 'optionalAccess', _191 => _191.is404])) return null;
1920
+ if (_optionalChain([hit, 'optionalAccess', _214 => _214.is404])) return null;
1767
1921
  if (hit && !hit.is404) {
1768
1922
  const verified = staticPathCache.verify(hit);
1769
1923
  if (verified) return { filePath: hit.filePath, stat: verified };
@@ -1787,7 +1941,7 @@ function createStaticHandler(ctx) {
1787
1941
  showHostDirs(req, res, [hostcfg.weburls.webdir], "/" + indexFile, primaryDirs, rtm + 1);
1788
1942
  return;
1789
1943
  }
1790
- const mimeType = _optionalChain([hostcfg, 'access', _192 => _192.mimetypes, 'optionalAccess', _193 => _193[nodePath2.extname(found.filePath)]]) || "application/octet-stream";
1944
+ const mimeType = _optionalChain([hostcfg, 'access', _215 => _215.mimetypes, 'optionalAccess', _216 => _216[nodePath2.extname(found.filePath)]]) || "application/octet-stream";
1791
1945
  serveStaticFile(req, res, found.filePath, mimeType, found.stat, $asai, processedUrl);
1792
1946
  }, "showHostDirs");
1793
1947
  return (req, res, url) => {
@@ -1812,7 +1966,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, createStaticHandler, "createStaticHandler"
1812
1966
  function setupHttpConnectionMonitor($asai, hostdir, server, hostcfg) {
1813
1967
  const maxHttp = hostcfg.maxhttp || 100;
1814
1968
  const monitorInterval = setInterval(() => {
1815
- const connCount = _optionalChain([$asai, 'access', _194 => _194.connectionshttp, 'access', _195 => _195[hostdir], 'optionalAccess', _196 => _196.size]) || 0;
1969
+ const connCount = _optionalChain([$asai, 'access', _217 => _217.connectionshttp, 'access', _218 => _218[hostdir], 'optionalAccess', _219 => _219.size]) || 0;
1816
1970
  if (connCount > maxHttp * 0.8) {
1817
1971
  $asai.$log("HTTP", `HTTP Connection HIGH (${connCount}/${maxHttp})`);
1818
1972
  }
@@ -1883,10 +2037,10 @@ function findListeningPids(port) {
1883
2037
  stdio: ["pipe", "pipe", "ignore"]
1884
2038
  });
1885
2039
  return out.split(/\r?\n/).map((s) => parseInt(s.trim(), 10)).filter((n) => n > 0);
1886
- } catch (e30) {
2040
+ } catch (e39) {
1887
2041
  return [];
1888
2042
  }
1889
- } catch (e31) {
2043
+ } catch (e40) {
1890
2044
  return [];
1891
2045
  }
1892
2046
  }
@@ -1897,10 +2051,10 @@ function formatOccupants(port, exclude) {
1897
2051
  }
1898
2052
  _chunkSMVZ3ZDJcjs.__name.call(void 0, formatOccupants, "formatOccupants");
1899
2053
  function releasePort(port, opts) {
1900
- const exclude = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _197 => _197.excludePid]), () => ( OWN_PID));
2054
+ const exclude = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _220 => _220.excludePid]), () => ( OWN_PID));
1901
2055
  const occupants = formatOccupants(port, exclude);
1902
2056
  if (!occupants) return true;
1903
- const label = _optionalChain([opts, 'optionalAccess', _198 => _198.label]) ? `[${opts.label}] ` : "";
2057
+ const label = _optionalChain([opts, 'optionalAccess', _221 => _221.label]) ? `[${opts.label}] ` : "";
1904
2058
  console.warn(
1905
2059
  `[AsaiHostNodejs] ${label}\u7AEF\u53E3 ${port} \u88AB\u5360\u7528\uFF08PID: ${occupants}\uFF09\uFF0C\u8BF7\u624B\u52A8\u7ED3\u675F\u5360\u7528\u8FDB\u7A0B\u540E\u91CD\u8BD5`
1906
2060
  );
@@ -1909,23 +2063,23 @@ function releasePort(port, opts) {
1909
2063
  _chunkSMVZ3ZDJcjs.__name.call(void 0, releasePort, "releasePort");
1910
2064
  function collectStartupPorts($asai) {
1911
2065
  const ports = /* @__PURE__ */ new Set();
1912
- const hosts = _optionalChain([$asai, 'access', _199 => _199.hostconfig, 'optionalAccess', _200 => _200.hosts]);
2066
+ const hosts = _optionalChain([$asai, 'access', _222 => _222.hostconfig, 'optionalAccess', _223 => _223.hosts]);
1913
2067
  if (hosts) {
1914
2068
  for (const el of Object.keys(hosts)) {
1915
2069
  if (el === "default") continue;
1916
2070
  if (el !== "asai" && !validateHostdir(el)) continue;
1917
2071
  const cfg = getHostCFG(el, $asai);
1918
- if (_optionalChain([cfg, 'optionalAccess', _201 => _201.close])) continue;
1919
- if (_optionalChain([cfg, 'optionalAccess', _202 => _202.port])) ports.add(Number(cfg.port));
2072
+ if (_optionalChain([cfg, 'optionalAccess', _224 => _224.close])) continue;
2073
+ if (_optionalChain([cfg, 'optionalAccess', _225 => _225.port])) ports.add(Number(cfg.port));
1920
2074
  }
1921
2075
  }
1922
- const proxyhosts = _optionalChain([$asai, 'access', _203 => _203.hostconfig, 'optionalAccess', _204 => _204.proxyhosts]);
2076
+ const proxyhosts = _optionalChain([$asai, 'access', _226 => _226.hostconfig, 'optionalAccess', _227 => _227.proxyhosts]);
1923
2077
  if (proxyhosts) {
1924
2078
  for (const el of Object.keys(proxyhosts)) {
1925
2079
  if (el === "default") continue;
1926
2080
  if (!validateHostdir(el)) continue;
1927
2081
  const cfg = getProxyHostCFG(el, $asai);
1928
- if (_optionalChain([cfg, 'optionalAccess', _205 => _205.proxyport])) ports.add(Number(cfg.proxyport));
2082
+ if (_optionalChain([cfg, 'optionalAccess', _228 => _228.proxyport])) ports.add(Number(cfg.proxyport));
1929
2083
  }
1930
2084
  }
1931
2085
  return [...ports];
@@ -1950,7 +2104,7 @@ function scheduleHttpRetry($asai, hostdir) {
1950
2104
  clearTimeout($asai.hostconfig.guardtm);
1951
2105
  $asai.hostconfig.guardtm = null;
1952
2106
  }
1953
- }, _optionalChain([$asai, 'access', _206 => _206.hostconfig, 'access', _207 => _207.tm, 'optionalAccess', _208 => _208.d]) || 2e3);
2107
+ }, _optionalChain([$asai, 'access', _229 => _229.hostconfig, 'access', _230 => _230.tm, 'optionalAccess', _231 => _231.d]) || 2e3);
1954
2108
  }
1955
2109
  _chunkSMVZ3ZDJcjs.__name.call(void 0, scheduleHttpRetry, "scheduleHttpRetry");
1956
2110
  function clearFailedHttpHost($asai, hostdir, ws2) {
@@ -1963,7 +2117,7 @@ function getHTTPServer(httptype = "", cfg, $asai) {
1963
2117
  if (httptype.startsWith("https")) {
1964
2118
  return {
1965
2119
  AsCreateServer: /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (callback) => {
1966
- return https.createServer(_optionalChain([cfg, 'optionalAccess', _209 => _209.httpscert]) || $asai.hostconfig.httpscert, callback);
2120
+ return https.createServer(_optionalChain([cfg, 'optionalAccess', _232 => _232.httpscert]) || $asai.hostconfig.httpscert, callback);
1967
2121
  }, "AsCreateServer"),
1968
2122
  Agent: https.Agent,
1969
2123
  request: https.request
@@ -2015,13 +2169,13 @@ function startHTTPServer($asai, hostdir) {
2015
2169
  return;
2016
2170
  }
2017
2171
  applySecurityHeaders(res, isHttps, $asai.hostconfig);
2018
- if (_optionalChain([req, 'access', _210 => _210.url, 'optionalAccess', _211 => _211.startsWith, 'call', _212 => _212("/sys")]) && sysWork) {
2172
+ if (_optionalChain([req, 'access', _233 => _233.url, 'optionalAccess', _234 => _234.startsWith, 'call', _235 => _235("/sys")]) && sysWork) {
2019
2173
  logHttp($asai, "SYS", req.method, req.url, skipChecker, req, res);
2020
2174
  sysWork(req, res, hostdir);
2021
- } else if (_optionalChain([req, 'access', _213 => _213.url, 'optionalAccess', _214 => _214.startsWith, 'call', _215 => _215("/api")]) && apiWork) {
2175
+ } else if (_optionalChain([req, 'access', _236 => _236.url, 'optionalAccess', _237 => _237.startsWith, 'call', _238 => _238("/api")]) && apiWork) {
2022
2176
  logHttp($asai, "API", req.method, req.url, skipChecker, req, res);
2023
2177
  apiWork(req, res, hostdir);
2024
- } else if (_optionalChain([req, 'access', _216 => _216.url, 'optionalAccess', _217 => _217.startsWith, 'call', _218 => _218("/jsonp")]) && jsonpWork) {
2178
+ } else if (_optionalChain([req, 'access', _239 => _239.url, 'optionalAccess', _240 => _240.startsWith, 'call', _241 => _241("/jsonp")]) && jsonpWork) {
2025
2179
  logHttp($asai, "JSONP", req.method, req.url, skipChecker, req, res);
2026
2180
  jsonpWork(req, res, hostdir);
2027
2181
  } else if (handleStatic) {
@@ -2092,7 +2246,7 @@ function findSameProcessPortOwner($asai, port, excludeHostdir) {
2092
2246
  for (const hostdir of Object.keys($asai.servershttp || {})) {
2093
2247
  if (hostdir === excludeHostdir) continue;
2094
2248
  const cfg = getHostCFG(hostdir, $asai);
2095
- if (_optionalChain([cfg, 'optionalAccess', _219 => _219.port]) === port) return hostdir;
2249
+ if (_optionalChain([cfg, 'optionalAccess', _242 => _242.port]) === port) return hostdir;
2096
2250
  }
2097
2251
  return null;
2098
2252
  }
@@ -2100,7 +2254,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, findSameProcessPortOwner, "findSameProcess
2100
2254
  function asaiGuard($asai, failedHostdir = "asai") {
2101
2255
  const conflictPorts = $asai.hostconfig.asaiport || [];
2102
2256
  const hostcfg = getHostCFG(failedHostdir, $asai);
2103
- const port = _optionalChain([hostcfg, 'optionalAccess', _220 => _220.port]);
2257
+ const port = _optionalChain([hostcfg, 'optionalAccess', _243 => _243.port]);
2104
2258
  if (!port || !conflictPorts.includes(port)) {
2105
2259
  scheduleHttpRetry($asai, failedHostdir);
2106
2260
  return;
@@ -2132,7 +2286,7 @@ var PROXY_SKIP_HEADERS = /* @__PURE__ */ new Set([
2132
2286
  function startProxyServer($asai, proxyhostdir) {
2133
2287
  const proxycfg = getProxyHostCFG(proxyhostdir, $asai);
2134
2288
  if (!proxycfg.url) return;
2135
- if (_optionalChain([$asai, 'access', _221 => _221.serversproxy, 'optionalAccess', _222 => _222[proxyhostdir]])) return;
2289
+ if (_optionalChain([$asai, 'access', _244 => _244.serversproxy, 'optionalAccess', _245 => _245[proxyhostdir]])) return;
2136
2290
  try {
2137
2291
  const httpServer = getHTTPServer(proxycfg.proxyhttptype, proxycfg, $asai);
2138
2292
  const targetHttp = getHTTPServer(proxycfg.url, proxycfg, $asai);
@@ -2214,12 +2368,12 @@ function startProxyServer($asai, proxyhostdir) {
2214
2368
  proxyServer.on("error", (err) => {
2215
2369
  if (err.code === "EADDRINUSE") {
2216
2370
  $asai.$log("PROXY", `\x1B[41mPort ${proxycfg.proxyport} is already start!\x1B[0m`);
2217
- _optionalChainDelete([$asai, 'access', _223 => _223.serversproxy, 'optionalAccess', _224 => delete _224[proxyhostdir]]);
2371
+ _optionalChainDelete([$asai, 'access', _246 => _246.serversproxy, 'optionalAccess', _247 => delete _247[proxyhostdir]]);
2218
2372
  releasePort(proxycfg.proxyport, {
2219
2373
  excludePid: process.pid,
2220
2374
  label: proxyhostdir
2221
2375
  });
2222
- setTimeout(() => startProxyServer($asai, proxyhostdir), _optionalChain([$asai, 'access', _225 => _225.hostconfig, 'access', _226 => _226.tm, 'optionalAccess', _227 => _227.d]) || 2e3);
2376
+ setTimeout(() => startProxyServer($asai, proxyhostdir), _optionalChain([$asai, 'access', _248 => _248.hostconfig, 'access', _249 => _249.tm, 'optionalAccess', _250 => _250.d]) || 2e3);
2223
2377
  } else {
2224
2378
  $asai.$log("PROXY", "Proxy server error:", err);
2225
2379
  }
@@ -2259,7 +2413,7 @@ function src_default($asai, opt) {
2259
2413
  initAsaiHostNodejs($asai, opt);
2260
2414
  console.log(`\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B`);
2261
2415
  releaseConfiguredPorts($asai);
2262
- if (_optionalChain([$asai, 'access', _228 => _228.hostconfig, 'optionalAccess', _229 => _229.hosts])) {
2416
+ if (_optionalChain([$asai, 'access', _251 => _251.hostconfig, 'optionalAccess', _252 => _252.hosts])) {
2263
2417
  $asai.startHTTPServer = (hostdir) => startHTTPServer($asai, hostdir);
2264
2418
  Object.keys($asai.hostconfig.hosts).forEach((el) => {
2265
2419
  if (validateHostdir(el)) {
@@ -2270,7 +2424,7 @@ function src_default($asai, opt) {
2270
2424
  startHTTPServer($asai, "asai");
2271
2425
  }
2272
2426
  }
2273
- if (_optionalChain([$asai, 'access', _230 => _230.hostconfig, 'optionalAccess', _231 => _231.proxyhosts])) {
2427
+ if (_optionalChain([$asai, 'access', _253 => _253.hostconfig, 'optionalAccess', _254 => _254.proxyhosts])) {
2274
2428
  Object.keys($asai.hostconfig.proxyhosts).forEach((el) => {
2275
2429
  if (validateHostdir(el)) {
2276
2430
  startProxyServer($asai, el);
@@ -2293,22 +2447,22 @@ _chunkSMVZ3ZDJcjs.__export.call(void 0, utils_exports, {
2293
2447
  // src/utils/ws-mock.ts
2294
2448
  function wsMock($asai) {
2295
2449
  function getKeyByData(reqdata, hostdir) {
2296
- return "_wstask_" + (hostdir || "") + "_" + (_optionalChain([reqdata, 'optionalAccess', _232 => _232.id]) || _optionalChain([reqdata, 'optionalAccess', _233 => _233.ty]) + "." + _optionalChain([reqdata, 'optionalAccess', _234 => _234.ac]));
2450
+ return "_wstask_" + (hostdir || "") + "_" + (_optionalChain([reqdata, 'optionalAccess', _255 => _255.id]) || _optionalChain([reqdata, 'optionalAccess', _256 => _256.ty]) + "." + _optionalChain([reqdata, 'optionalAccess', _257 => _257.ac]));
2297
2451
  }
2298
2452
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getKeyByData, "getKeyByData");
2299
2453
  function getMockDb(workopt) {
2300
2454
  const { reqdata, mockdata } = workopt;
2301
- const wsfn = _optionalChain([mockdata, 'optionalAccess', _235 => _235.fn]) ? _optionalChain([$asai, 'access', _236 => _236.asaimock, 'access', _237 => _237.fn, 'optionalAccess', _238 => _238[mockdata.fn]]) : null;
2455
+ const wsfn = _optionalChain([mockdata, 'optionalAccess', _258 => _258.fn]) ? _optionalChain([$asai, 'access', _259 => _259.asaimock, 'access', _260 => _260.fn, 'optionalAccess', _261 => _261[mockdata.fn]]) : null;
2302
2456
  if (wsfn) return wsfn({ workopt, $asai, mockName: mockdata.fn });
2303
2457
  return { ...reqdata, ...mockdata || {} };
2304
2458
  }
2305
2459
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getMockDb, "getMockDb");
2306
2460
  function wsWorkApi(workopt) {
2307
- _optionalChain([$asai, 'access', _239 => _239.serversws, 'access', _240 => _240[workopt.hostdir], 'optionalAccess', _241 => _241.sendws, 'optionalCall', _242 => _242(workopt.reqdataisobj ? getMockDb(workopt) : workopt.reqdata, 0, workopt.ws)]);
2461
+ _optionalChain([$asai, 'access', _262 => _262.serversws, 'access', _263 => _263[workopt.hostdir], 'optionalAccess', _264 => _264.sendws, 'optionalCall', _265 => _265(workopt.reqdataisobj ? getMockDb(workopt) : workopt.reqdata, 0, workopt.ws)]);
2308
2462
  }
2309
2463
  _chunkSMVZ3ZDJcjs.__name.call(void 0, wsWorkApi, "wsWorkApi");
2310
2464
  function wsWorkListen(workopt, reqkey) {
2311
- if (_optionalChain([workopt, 'access', _243 => _243.reqdata, 'optionalAccess', _244 => _244.off])) {
2465
+ if (_optionalChain([workopt, 'access', _266 => _266.reqdata, 'optionalAccess', _267 => _267.off])) {
2312
2466
  if ($asai.tasksws[workopt.hostdir][reqkey]) {
2313
2467
  clearInterval($asai.tasksws[workopt.hostdir][reqkey]);
2314
2468
  $asai.tasksws[workopt.hostdir][reqkey] = null;
@@ -2323,9 +2477,9 @@ function wsMock($asai) {
2323
2477
  if (!$asai.tasksws[workopt.hostdir][reqkey]) {
2324
2478
  clearInterval($asai.tasksws[workopt.hostdir][reqkey]);
2325
2479
  }
2326
- }, _optionalChain([newDataMock, 'optionalAccess', _245 => _245.tc]) || 2e3);
2327
- _optionalChain([workopt, 'access', _246 => _246.ws, 'optionalAccess', _247 => _247.once, 'optionalCall', _248 => _248("close", () => {
2328
- if (_optionalChain([$asai, 'access', _249 => _249.tasksws, 'access', _250 => _250[workopt.hostdir], 'optionalAccess', _251 => _251[reqkey]])) {
2480
+ }, _optionalChain([newDataMock, 'optionalAccess', _268 => _268.tc]) || 2e3);
2481
+ _optionalChain([workopt, 'access', _269 => _269.ws, 'optionalAccess', _270 => _270.once, 'optionalCall', _271 => _271("close", () => {
2482
+ if (_optionalChain([$asai, 'access', _272 => _272.tasksws, 'access', _273 => _273[workopt.hostdir], 'optionalAccess', _274 => _274[reqkey]])) {
2329
2483
  clearInterval($asai.tasksws[workopt.hostdir][reqkey]);
2330
2484
  delete $asai.tasksws[workopt.hostdir][reqkey];
2331
2485
  }
@@ -2333,8 +2487,8 @@ function wsMock($asai) {
2333
2487
  }
2334
2488
  _chunkSMVZ3ZDJcjs.__name.call(void 0, wsWorkListen, "wsWorkListen");
2335
2489
  function wsWorkMock(workopt) {
2336
- workopt.mockdata = workopt.reqdataisobj && _optionalChain([$asai, 'access', _252 => _252.asaimock, 'optionalAccess', _253 => _253.db, 'optionalAccess', _254 => _254[workopt.hostdir], 'optionalAccess', _255 => _255[_optionalChain([workopt, 'access', _256 => _256.reqdata, 'optionalAccess', _257 => _257.ty])]]) || {};
2337
- if (_optionalChain([workopt, 'access', _258 => _258.mockdata, 'optionalAccess', _259 => _259.wc])) {
2490
+ workopt.mockdata = workopt.reqdataisobj && _optionalChain([$asai, 'access', _275 => _275.asaimock, 'optionalAccess', _276 => _276.db, 'optionalAccess', _277 => _277[workopt.hostdir], 'optionalAccess', _278 => _278[_optionalChain([workopt, 'access', _279 => _279.reqdata, 'optionalAccess', _280 => _280.ty])]]) || {};
2491
+ if (_optionalChain([workopt, 'access', _281 => _281.mockdata, 'optionalAccess', _282 => _282.wc])) {
2338
2492
  wsWorkListen(workopt, getKeyByData(workopt.reqdata, workopt.hostdir));
2339
2493
  } else {
2340
2494
  wsWorkApi(workopt);
@@ -2347,11 +2501,11 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, wsMock, "wsMock");
2347
2501
 
2348
2502
  // src/infra/user-auth.ts
2349
2503
  async function attachServerUserLevel(req, $asai) {
2350
- const userinfo = _optionalChain([req, 'optionalAccess', _260 => _260.Userinfo]);
2504
+ const userinfo = _optionalChain([req, 'optionalAccess', _283 => _283.Userinfo]);
2351
2505
  if (!Array.isArray(userinfo) || !userinfo[0]) return;
2352
2506
  const us = String(userinfo[0]);
2353
2507
  try {
2354
- const { createUserStore: createUserStore2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./user-store-55HOLHEM.cjs")));
2508
+ const { createUserStore: createUserStore2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./user-store-6QNAL4CK.cjs")));
2355
2509
  const user = await createUserStore2($asai).findByUsername(us);
2356
2510
  if (user && user.status === "active") {
2357
2511
  req._serverUser = { us: user.us, lv: user.lv, status: user.status };
@@ -2359,34 +2513,34 @@ async function attachServerUserLevel(req, $asai) {
2359
2513
  } else {
2360
2514
  req._serverUser = null;
2361
2515
  }
2362
- } catch (e32) {
2516
+ } catch (e41) {
2363
2517
  req._serverUser = null;
2364
2518
  }
2365
2519
  }
2366
2520
  _chunkSMVZ3ZDJcjs.__name.call(void 0, attachServerUserLevel, "attachServerUserLevel");
2367
2521
  function getRequestUserLevel(req) {
2368
- if (_optionalChain([req, 'optionalAccess', _261 => _261._serverUser, 'optionalAccess', _262 => _262.lv]) != null) return Number(req._serverUser.lv);
2369
- const n = Number(_nullishCoalesce(_optionalChain([req, 'optionalAccess', _263 => _263.Userinfo, 'optionalAccess', _264 => _264[1]]), () => ( -1)));
2522
+ if (_optionalChain([req, 'optionalAccess', _284 => _284._serverUser, 'optionalAccess', _285 => _285.lv]) != null) return Number(req._serverUser.lv);
2523
+ const n = Number(_nullishCoalesce(_optionalChain([req, 'optionalAccess', _286 => _286.Userinfo, 'optionalAccess', _287 => _287[1]]), () => ( -1)));
2370
2524
  return Number.isFinite(n) ? n : -1;
2371
2525
  }
2372
2526
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getRequestUserLevel, "getRequestUserLevel");
2373
2527
  function getRequestUsername(req) {
2374
- if (_optionalChain([req, 'optionalAccess', _265 => _265._serverUser, 'optionalAccess', _266 => _266.us])) return String(req._serverUser.us);
2375
- const us = _optionalChain([req, 'optionalAccess', _267 => _267.Userinfo, 'optionalAccess', _268 => _268[0]]);
2528
+ if (_optionalChain([req, 'optionalAccess', _288 => _288._serverUser, 'optionalAccess', _289 => _289.us])) return String(req._serverUser.us);
2529
+ const us = _optionalChain([req, 'optionalAccess', _290 => _290.Userinfo, 'optionalAccess', _291 => _291[0]]);
2376
2530
  return us ? String(us) : void 0;
2377
2531
  }
2378
2532
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getRequestUsername, "getRequestUsername");
2379
2533
 
2380
2534
  // src/infra/access-control.ts
2381
2535
  function getSecurityConfig($asai) {
2382
- return _optionalChain([$asai, 'optionalAccess', _269 => _269.hostconfig, 'optionalAccess', _270 => _270.security]) || {};
2536
+ return _optionalChain([$asai, 'optionalAccess', _292 => _292.hostconfig, 'optionalAccess', _293 => _293.security]) || {};
2383
2537
  }
2384
2538
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getSecurityConfig, "getSecurityConfig");
2385
- function pathMatchesPattern(path8, pattern) {
2539
+ function pathMatchesPattern(path9, pattern) {
2386
2540
  if (pattern.endsWith("*")) {
2387
- return path8.startsWith(pattern.slice(0, -1));
2541
+ return path9.startsWith(pattern.slice(0, -1));
2388
2542
  }
2389
- return path8 === pattern;
2543
+ return path9 === pattern;
2390
2544
  }
2391
2545
  _chunkSMVZ3ZDJcjs.__name.call(void 0, pathMatchesPattern, "pathMatchesPattern");
2392
2546
  function isAuthSkipped($asai, pathname) {
@@ -2413,13 +2567,13 @@ function validateHttpAuth(req, $asai, pathname) {
2413
2567
  if (!isAuthRequired($asai, pathname)) {
2414
2568
  return { ok: true };
2415
2569
  }
2416
- const userinfo = _optionalChain([req, 'optionalAccess', _271 => _271.Userinfo]);
2570
+ const userinfo = _optionalChain([req, 'optionalAccess', _294 => _294.Userinfo]);
2417
2571
  const ip = getClientIp(req);
2418
2572
  if (!Array.isArray(userinfo) || userinfo.length < 3 || !userinfo[0]) {
2419
2573
  logSecurityEvent($asai, {
2420
2574
  type: "AUTH_MISSING",
2421
2575
  path: pathname,
2422
- method: _optionalChain([req, 'optionalAccess', _272 => _272.method]),
2576
+ method: _optionalChain([req, 'optionalAccess', _295 => _295.method]),
2423
2577
  ip,
2424
2578
  detail: "Userinfo header missing or invalid"
2425
2579
  });
@@ -2433,7 +2587,7 @@ function validateHttpAuth(req, $asai, pathname) {
2433
2587
  logSecurityEvent($asai, {
2434
2588
  type: "ACCESS_DENIED",
2435
2589
  path: pathname,
2436
- method: _optionalChain([req, 'optionalAccess', _273 => _273.method]),
2590
+ method: _optionalChain([req, 'optionalAccess', _296 => _296.method]),
2437
2591
  user: String(us),
2438
2592
  level: userLevel,
2439
2593
  ip,
@@ -2445,13 +2599,13 @@ function validateHttpAuth(req, $asai, pathname) {
2445
2599
  }
2446
2600
  _chunkSMVZ3ZDJcjs.__name.call(void 0, validateHttpAuth, "validateHttpAuth");
2447
2601
  async function validateHttpAuthAsync(req, $asai, pathname) {
2448
- if (Array.isArray(_optionalChain([req, 'optionalAccess', _274 => _274.Userinfo])) && req.Userinfo[0]) {
2602
+ if (Array.isArray(_optionalChain([req, 'optionalAccess', _297 => _297.Userinfo])) && req.Userinfo[0]) {
2449
2603
  await attachServerUserLevel(req, $asai);
2450
2604
  if (!req._serverUser && isAuthRequired($asai, pathname)) {
2451
2605
  logSecurityEvent($asai, {
2452
2606
  type: "ACCESS_DENIED",
2453
2607
  path: pathname,
2454
- method: _optionalChain([req, 'optionalAccess', _275 => _275.method]),
2608
+ method: _optionalChain([req, 'optionalAccess', _298 => _298.method]),
2455
2609
  user: String(req.Userinfo[0]),
2456
2610
  ip: getClientIp(req),
2457
2611
  detail: "User not found or inactive"
@@ -2513,7 +2667,7 @@ function resolveApiCorsOrigin(req, hostcfg, getHeader) {
2513
2667
  if (referer) {
2514
2668
  try {
2515
2669
  origin = new URL(referer).origin;
2516
- } catch (e33) {
2670
+ } catch (e42) {
2517
2671
  const parts = referer.split("/");
2518
2672
  if (parts.length >= 3) origin = `${parts[0]}//${parts[2]}`;
2519
2673
  }
@@ -2525,7 +2679,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, resolveApiCorsOrigin, "resolveApiCorsOrigi
2525
2679
  function isApiCorsAllowed(origin, hostcfg, hostHeader) {
2526
2680
  if (!origin) return false;
2527
2681
  if (origin === "*") return true;
2528
- const corsList = _optionalChain([hostcfg, 'optionalAccess', _276 => _276.cors]);
2682
+ const corsList = _optionalChain([hostcfg, 'optionalAccess', _299 => _299.cors]);
2529
2683
  if (!Array.isArray(corsList) || !corsList.length) return true;
2530
2684
  if (corsList.includes(origin)) return true;
2531
2685
  if (hostHeader && origin.includes(hostHeader)) return true;
@@ -2571,19 +2725,19 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, isPlainSourcePost, "isPlainSourcePost");
2571
2725
  function processPostPayload($asai, req, postdata, pm) {
2572
2726
  let isAes = false;
2573
2727
  let out = postdata;
2574
- if ($asai.$lib.aesfns && _optionalChain([out, 'optionalAccess', _277 => _277.startsWith, 'optionalCall', _278 => _278('{"aes":')])) {
2728
+ if ($asai.$lib.aesfns && _optionalChain([out, 'optionalAccess', _300 => _300.startsWith, 'optionalCall', _301 => _301('{"aes":')])) {
2575
2729
  isAes = true;
2576
2730
  const aesData = JSON.parse(out);
2577
2731
  out = $asai.$lib.aesfns.reqAES({ data: aesData });
2578
- if (_optionalChain([aesData, 'optionalAccess', _279 => _279.aes]) === 2 && typeof out === "string") {
2732
+ if (_optionalChain([aesData, 'optionalAccess', _302 => _302.aes]) === 2 && typeof out === "string") {
2579
2733
  try {
2580
2734
  out = JSON.parse(out);
2581
- } catch (e34) {
2735
+ } catch (e43) {
2582
2736
  }
2583
2737
  }
2584
2738
  }
2585
2739
  const plainJson = typeof out === "string" && out.trimStart().startsWith("{");
2586
- if (_optionalChain([req, 'optionalAccess', _280 => _280.Userinfo, 'optionalAccess', _281 => _281[2]]) && !plainJson && !isRawUploadPost(_optionalChain([req, 'optionalAccess', _282 => _282.url])) && !isPlainSourcePost(_optionalChain([req, 'optionalAccess', _283 => _283.url]))) {
2740
+ if (_optionalChain([req, 'optionalAccess', _303 => _303.Userinfo, 'optionalAccess', _304 => _304[2]]) && !plainJson && !isRawUploadPost(_optionalChain([req, 'optionalAccess', _305 => _305.url])) && !isPlainSourcePost(_optionalChain([req, 'optionalAccess', _306 => _306.url]))) {
2587
2741
  pm = req.Userinfo[2];
2588
2742
  out = $asai.$lib.AsCode.asdecode(out, pm);
2589
2743
  }
@@ -2591,7 +2745,7 @@ function processPostPayload($asai, req, postdata, pm) {
2591
2745
  }
2592
2746
  _chunkSMVZ3ZDJcjs.__name.call(void 0, processPostPayload, "processPostPayload");
2593
2747
  var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, opt = {}) => {
2594
- _optionalChain([opt, 'optionalAccess', _284 => _284.fn, 'optionalCall', _285 => _285($asai)]);
2748
+ _optionalChain([opt, 'optionalAccess', _307 => _307.fn, 'optionalCall', _308 => _308($asai)]);
2595
2749
  function getHeader(req, key) {
2596
2750
  return req.headers[key.toLowerCase()] || "";
2597
2751
  }
@@ -2600,7 +2754,7 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2600
2754
  let apiRouteCacheLen = -1;
2601
2755
  function findApiHandler($asai2, pathname) {
2602
2756
  const apis = $asai2.hostserverapis;
2603
- if (!_optionalChain([apis, 'optionalAccess', _286 => _286.length])) return void 0;
2757
+ if (!_optionalChain([apis, 'optionalAccess', _309 => _309.length])) return void 0;
2604
2758
  if (!apiRouteCache || apiRouteCacheLen !== apis.length) {
2605
2759
  apiRouteCache = apis.map((elp) => ({ key: elp, path: `/api/${elp}` }));
2606
2760
  apiRouteCacheLen = apis.length;
@@ -2648,9 +2802,9 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2648
2802
  pm: decodeURIComponent(urlParse.search.substring(4))
2649
2803
  };
2650
2804
  if (req.url.indexOf("binary") === -1) {
2651
- if (_optionalChain([req, 'optionalAccess', _287 => _287.Userinfo]) && _optionalChain([req, 'optionalAccess', _288 => _288.Userinfo, 'access', _289 => _289[2]]) && _optionalChain([query, 'optionalAccess', _290 => _290.pm])) {
2805
+ if (_optionalChain([req, 'optionalAccess', _310 => _310.Userinfo]) && _optionalChain([req, 'optionalAccess', _311 => _311.Userinfo, 'access', _312 => _312[2]]) && _optionalChain([query, 'optionalAccess', _313 => _313.pm])) {
2652
2806
  pm = req.Userinfo[2];
2653
- query = $asai.$lib.AsCode.asdecode(_optionalChain([query, 'optionalAccess', _291 => _291.pm]), pm);
2807
+ query = $asai.$lib.AsCode.asdecode(_optionalChain([query, 'optionalAccess', _314 => _314.pm]), pm);
2654
2808
  query = Object.fromEntries(new URLSearchParams("?" + query).entries());
2655
2809
  }
2656
2810
  }
@@ -2669,7 +2823,7 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2669
2823
  const releaseSlot = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, () => releaseApiSlot(hostdir, clientIp), "releaseSlot");
2670
2824
  res.once("finish", releaseSlot);
2671
2825
  res.once("close", releaseSlot);
2672
- const maxBody = _optionalChain([$asai, 'access', _292 => _292.hostconfig, 'optionalAccess', _293 => _293.maxbody]) || 100 * 1024 * 1024;
2826
+ const maxBody = _optionalChain([$asai, 'access', _315 => _315.hostconfig, 'optionalAccess', _316 => _316.maxbody]) || 100 * 1024 * 1024;
2673
2827
  const isTextPost = req.method === "POST" && req.url.indexOf("binary") === -1;
2674
2828
  const bodyPromise = isTextPost ? readRequestBody(req, maxBody) : null;
2675
2829
  void (async () => {
@@ -2683,16 +2837,16 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2683
2837
  ]);
2684
2838
  } catch (err) {
2685
2839
  releaseSlot();
2686
- if (_optionalChain([err, 'optionalAccess', _294 => _294.message]) === "PAYLOAD_TOO_LARGE") {
2840
+ if (_optionalChain([err, 'optionalAccess', _317 => _317.message]) === "PAYLOAD_TOO_LARGE") {
2687
2841
  return sendError(res, 413, "Payload Too Large");
2688
2842
  }
2689
- return sendError(res, 400, _optionalChain([err, 'optionalAccess', _295 => _295.message]) || "Bad Request");
2843
+ return sendError(res, 400, _optionalChain([err, 'optionalAccess', _318 => _318.message]) || "Bad Request");
2690
2844
  }
2691
2845
  if (!authResult.ok) {
2692
2846
  releaseSlot();
2693
2847
  return sendAuthError(res, authResult);
2694
2848
  }
2695
- let apiFn = _optionalChain([$asai, 'access', _296 => _296.hostserverapi, 'access', _297 => _297[apiHandlerKey], 'optionalCall', _298 => _298($asai, query)]);
2849
+ let apiFn = _optionalChain([$asai, 'access', _319 => _319.hostserverapi, 'access', _320 => _320[apiHandlerKey], 'optionalCall', _321 => _321($asai, query)]);
2696
2850
  if (!apiFn) {
2697
2851
  return sendError(res, 501, "Not Implemented");
2698
2852
  }
@@ -2708,23 +2862,23 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2708
2862
  postdata = processed.postdata;
2709
2863
  pm = processed.pm;
2710
2864
  isAes = processed.isAes;
2711
- } catch (e35) {
2865
+ } catch (e44) {
2712
2866
  return sendError(res, 400, "AES decrypt failed");
2713
2867
  }
2714
- if (_optionalChain([apiFn, 'optionalAccess', _299 => _299.post]) && typeof _optionalChain([apiFn, 'optionalAccess', _300 => _300.post]) === "function") {
2868
+ if (_optionalChain([apiFn, 'optionalAccess', _322 => _322.post]) && typeof _optionalChain([apiFn, 'optionalAccess', _323 => _323.post]) === "function") {
2715
2869
  const optTmp = { qrdata, data: postdata, pm };
2716
- if (isAes || _optionalChain([$asai, 'access', _301 => _301.$lib, 'access', _302 => _302.aesfns, 'optionalAccess', _303 => _303.allaes])) {
2717
- optTmp.resAES = _optionalChain([$asai, 'access', _304 => _304.$lib, 'access', _305 => _305.aesfns, 'optionalAccess', _306 => _306.resAES]);
2870
+ if (isAes || _optionalChain([$asai, 'access', _324 => _324.$lib, 'access', _325 => _325.aesfns, 'optionalAccess', _326 => _326.allaes])) {
2871
+ optTmp.resAES = _optionalChain([$asai, 'access', _327 => _327.$lib, 'access', _328 => _328.aesfns, 'optionalAccess', _329 => _329.resAES]);
2718
2872
  }
2719
2873
  apiFn.post(req, res, hostdir, optTmp);
2720
2874
  } else {
2721
2875
  res.end(typeof postdata === "string" ? postdata : JSON.stringify(_nullishCoalesce(postdata, () => ( ""))));
2722
2876
  }
2723
2877
  } else if (req.method === "GET") {
2724
- if (_optionalChain([apiFn, 'optionalAccess', _307 => _307.get]) && typeof _optionalChain([apiFn, 'optionalAccess', _308 => _308.get]) === "function") {
2878
+ if (_optionalChain([apiFn, 'optionalAccess', _330 => _330.get]) && typeof _optionalChain([apiFn, 'optionalAccess', _331 => _331.get]) === "function") {
2725
2879
  const optTmp = { qrdata, data: qrdata, pm };
2726
- if (isAes || _optionalChain([$asai, 'access', _309 => _309.$lib, 'access', _310 => _310.aesfns, 'optionalAccess', _311 => _311.allaes])) {
2727
- optTmp.resAES = _optionalChain([$asai, 'access', _312 => _312.$lib, 'access', _313 => _313.aesfns, 'optionalAccess', _314 => _314.resAES]);
2880
+ if (isAes || _optionalChain([$asai, 'access', _332 => _332.$lib, 'access', _333 => _333.aesfns, 'optionalAccess', _334 => _334.allaes])) {
2881
+ optTmp.resAES = _optionalChain([$asai, 'access', _335 => _335.$lib, 'access', _336 => _336.aesfns, 'optionalAccess', _337 => _337.resAES]);
2728
2882
  }
2729
2883
  apiFn.get(req, res, hostdir, optTmp);
2730
2884
  } else {
@@ -2732,12 +2886,12 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2732
2886
  }
2733
2887
  }
2734
2888
  } else {
2735
- if (_optionalChain([Object, 'access', _315 => _315.keys, 'call', _316 => _316(query), 'optionalAccess', _317 => _317.length])) {
2889
+ if (_optionalChain([Object, 'access', _338 => _338.keys, 'call', _339 => _339(query), 'optionalAccess', _340 => _340.length])) {
2736
2890
  qrdata = query;
2737
2891
  }
2738
2892
  if (req.method === "POST") {
2739
2893
  $asai.$lib.AsNodeTool.upBinary(req).then((postdata2) => {
2740
- if (_optionalChain([apiFn, 'optionalAccess', _318 => _318.post]) && typeof _optionalChain([apiFn, 'optionalAccess', _319 => _319.post]) === "function") {
2894
+ if (_optionalChain([apiFn, 'optionalAccess', _341 => _341.post]) && typeof _optionalChain([apiFn, 'optionalAccess', _342 => _342.post]) === "function") {
2741
2895
  apiFn.post(req, res, hostdir, {
2742
2896
  qrdata,
2743
2897
  data: postdata2
@@ -2753,13 +2907,13 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2753
2907
  } catch (err) {
2754
2908
  releaseSlot();
2755
2909
  if (!res.headersSent) {
2756
- return sendError(res, 500, _optionalChain([err, 'optionalAccess', _320 => _320.message]) || "Internal Server Error");
2910
+ return sendError(res, 500, _optionalChain([err, 'optionalAccess', _343 => _343.message]) || "Internal Server Error");
2757
2911
  }
2758
2912
  }
2759
2913
  })().catch((err) => {
2760
2914
  releaseSlot();
2761
2915
  if (!res.headersSent) {
2762
- sendError(res, 500, _optionalChain([err, 'optionalAccess', _321 => _321.message]) || "Internal Server Error");
2916
+ sendError(res, 500, _optionalChain([err, 'optionalAccess', _344 => _344.message]) || "Internal Server Error");
2763
2917
  }
2764
2918
  });
2765
2919
  } else {
@@ -2772,12 +2926,12 @@ var Api_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2772
2926
 
2773
2927
  // src/common/server/Ws.ts
2774
2928
  var Ws_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, opt = {}) => {
2775
- _optionalChain([opt, 'optionalAccess', _322 => _322.fn, 'optionalCall', _323 => _323($asai)]);
2929
+ _optionalChain([opt, 'optionalAccess', _345 => _345.fn, 'optionalCall', _346 => _346($asai)]);
2776
2930
  const wsHandlerCache = /* @__PURE__ */ new Map();
2777
2931
  const routeIndex = ensureWsRouteIndex($asai);
2778
2932
  function getWsHandler(handlerKey) {
2779
2933
  if (!wsHandlerCache.has(handlerKey)) {
2780
- wsHandlerCache.set(handlerKey, _optionalChain([$asai, 'access', _324 => _324.hostserverws, 'access', _325 => _325[handlerKey], 'optionalCall', _326 => _326($asai)]));
2934
+ wsHandlerCache.set(handlerKey, _optionalChain([$asai, 'access', _347 => _347.hostserverws, 'access', _348 => _348[handlerKey], 'optionalCall', _349 => _349($asai)]));
2781
2935
  }
2782
2936
  return wsHandlerCache.get(handlerKey);
2783
2937
  }
@@ -2801,21 +2955,21 @@ var Ws_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, o
2801
2955
  let reqdata = parseMessage(msg);
2802
2956
  let handlerKey;
2803
2957
  if (reqdata === "ping") {
2804
- _optionalChain([ws2, 'access', _327 => _327.send, 'optionalCall', _328 => _328("pong")]);
2958
+ _optionalChain([ws2, 'access', _350 => _350.send, 'optionalCall', _351 => _351("pong")]);
2805
2959
  return;
2806
2960
  } else {
2807
2961
  const reqdataisobj = typeof reqdata === "object" && reqdata !== null;
2808
- handlerKey = reqdataisobj ? routeIndex.matchTy(_optionalChain([reqdata, 'optionalAccess', _329 => _329.ty])) : routeIndex.matchString(reqdata);
2809
- if (!handlerKey && _optionalChain([$asai, 'access', _330 => _330.hostserverwss, 'optionalAccess', _331 => _331.length])) {
2962
+ handlerKey = reqdataisobj ? routeIndex.matchTy(_optionalChain([reqdata, 'optionalAccess', _352 => _352.ty])) : routeIndex.matchString(reqdata);
2963
+ if (!handlerKey && _optionalChain([$asai, 'access', _353 => _353.hostserverwss, 'optionalAccess', _354 => _354.length])) {
2810
2964
  handlerKey = $asai.hostserverwss.find((elp) => {
2811
2965
  if (reqdataisobj) {
2812
- return _optionalChain([reqdata, 'optionalAccess', _332 => _332.ty, 'optionalAccess', _333 => _333.startsWith, 'call', _334 => _334(elp)]);
2966
+ return _optionalChain([reqdata, 'optionalAccess', _355 => _355.ty, 'optionalAccess', _356 => _356.startsWith, 'call', _357 => _357(elp)]);
2813
2967
  }
2814
2968
  return typeof reqdata === "string" && reqdata.startsWith(elp);
2815
2969
  });
2816
2970
  }
2817
2971
  if (!handlerKey) {
2818
- _optionalChain([$asai, 'access', _335 => _335.asaimock, 'optionalAccess', _336 => _336.wsWorkMock, 'call', _337 => _337({
2972
+ _optionalChain([$asai, 'access', _358 => _358.asaimock, 'optionalAccess', _359 => _359.wsWorkMock, 'call', _360 => _360({
2819
2973
  msg,
2820
2974
  ws: ws2,
2821
2975
  hostdir,
@@ -2827,14 +2981,14 @@ var Ws_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, o
2827
2981
  }
2828
2982
  }
2829
2983
  if (!handlerKey) return;
2830
- _optionalChain([getWsHandler, 'call', _338 => _338(handlerKey), 'optionalAccess', _339 => _339.work, 'optionalCall', _340 => _340(reqdata, ws2, hostdir, req)]);
2984
+ _optionalChain([getWsHandler, 'call', _361 => _361(handlerKey), 'optionalAccess', _362 => _362.work, 'optionalCall', _363 => _363(reqdata, ws2, hostdir, req)]);
2831
2985
  } catch (err) {
2832
- _optionalChain([($asai.$log || console.error), 'optionalCall', _341 => _341("WS", "handler error", err instanceof Error ? err.message : err)]);
2986
+ _optionalChain([($asai.$log || console.error), 'optionalCall', _364 => _364("WS", "handler error", err instanceof Error ? err.message : err)]);
2833
2987
  }
2834
2988
  }
2835
2989
  _chunkSMVZ3ZDJcjs.__name.call(void 0, wsWork, "wsWork");
2836
2990
  function _getMessage(msg) {
2837
- if (_optionalChain([msg, 'optionalAccess', _342 => _342.db, 'optionalAccess', _343 => _343.aes]) && _optionalChain([$asai, 'access', _344 => _344.$lib, 'optionalAccess', _345 => _345.aesfns, 'optionalAccess', _346 => _346.reqAES])) {
2991
+ if (_optionalChain([msg, 'optionalAccess', _365 => _365.db, 'optionalAccess', _366 => _366.aes]) && _optionalChain([$asai, 'access', _367 => _367.$lib, 'optionalAccess', _368 => _368.aesfns, 'optionalAccess', _369 => _369.reqAES])) {
2838
2992
  msg.db = $asai.$lib.aesfns.reqAES({ data: msg.db });
2839
2993
  }
2840
2994
  return msg;
@@ -2861,12 +3015,12 @@ var Ws_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, o
2861
3015
 
2862
3016
  // src/common/server/Sys.ts
2863
3017
  var Sys_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, opt = {}) => {
2864
- _optionalChain([opt, 'optionalAccess', _347 => _347.fn, 'optionalCall', _348 => _348($asai)]);
3018
+ _optionalChain([opt, 'optionalAccess', _370 => _370.fn, 'optionalCall', _371 => _371($asai)]);
2865
3019
  let sysRouteCache = null;
2866
3020
  let sysRouteCacheLen = -1;
2867
3021
  function findSystemHandler(req) {
2868
3022
  const routes = $asai.hostserversyss;
2869
- if (!_optionalChain([routes, 'optionalAccess', _349 => _349.length])) return void 0;
3023
+ if (!_optionalChain([routes, 'optionalAccess', _372 => _372.length])) return void 0;
2870
3024
  if (!sysRouteCache || sysRouteCacheLen !== routes.length) {
2871
3025
  sysRouteCache = routes.map((elp) => ({ key: elp, route: `/${elp}` }));
2872
3026
  sysRouteCacheLen = routes.length;
@@ -2900,21 +3054,21 @@ var Sys_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2900
3054
  if (!authResult.ok) {
2901
3055
  return sendAuthError(res, authResult);
2902
3056
  }
2903
- const handler = _optionalChain([$asai, 'access', _350 => _350.hostserversys, 'access', _351 => _351[handlerKey], 'optionalCall', _352 => _352($asai)]);
3057
+ const handler = _optionalChain([$asai, 'access', _373 => _373.hostserversys, 'access', _374 => _374[handlerKey], 'optionalCall', _375 => _375($asai)]);
2904
3058
  if (!handler) {
2905
3059
  return sendError(res, 500, "Handler Initialization Failed");
2906
3060
  }
2907
- if (_optionalChain([handler, 'optionalAccess', _353 => _353.show]) && typeof _optionalChain([handler, 'optionalAccess', _354 => _354.show]) === "function") {
3061
+ if (_optionalChain([handler, 'optionalAccess', _376 => _376.show]) && typeof _optionalChain([handler, 'optionalAccess', _377 => _377.show]) === "function") {
2908
3062
  handler.show(req, res, hostdir);
2909
3063
  } else {
2910
3064
  res.end("postdata");
2911
3065
  }
2912
3066
  } catch (err) {
2913
- return sendError(res, 500, _optionalChain([err, 'optionalAccess', _355 => _355.message]) || "Internal Server Error");
3067
+ return sendError(res, 500, _optionalChain([err, 'optionalAccess', _378 => _378.message]) || "Internal Server Error");
2914
3068
  }
2915
3069
  })().catch((err) => {
2916
3070
  if (!res.headersSent) {
2917
- sendError(res, 500, _optionalChain([err, 'optionalAccess', _356 => _356.message]) || "Internal Server Error");
3071
+ sendError(res, 500, _optionalChain([err, 'optionalAccess', _379 => _379.message]) || "Internal Server Error");
2918
3072
  }
2919
3073
  });
2920
3074
  }
@@ -2924,14 +3078,14 @@ var Sys_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
2924
3078
 
2925
3079
  // src/common/server/WsClient.ts
2926
3080
  var WsClient_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, wsname) => {
2927
- if (!_optionalChain([$asai, 'optionalAccess', _357 => _357.clientws])) {
3081
+ if (!_optionalChain([$asai, 'optionalAccess', _380 => _380.clientws])) {
2928
3082
  $asai.clientws = {};
2929
3083
  }
2930
3084
  if (!$asai.clientws[wsname]) {
2931
3085
  $asai.clientws[wsname] = { tasks: /* @__PURE__ */ new Map() };
2932
3086
  }
2933
3087
  function getKeyByData(msgdata) {
2934
- return _optionalChain([msgdata, 'optionalAccess', _358 => _358.id]) || _optionalChain([msgdata, 'optionalAccess', _359 => _359.ty]);
3088
+ return _optionalChain([msgdata, 'optionalAccess', _381 => _381.id]) || _optionalChain([msgdata, 'optionalAccess', _382 => _382.ty]);
2935
3089
  }
2936
3090
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getKeyByData, "getKeyByData");
2937
3091
  function clientwsInit() {
@@ -2944,7 +3098,7 @@ var WsClient_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($a
2944
3098
  };
2945
3099
  $asai.clientws[wsname].socket.on("error", (err) => {
2946
3100
  $asai.clientws[wsname].open = 0;
2947
- _optionalChain([$asai, 'access', _360 => _360.hostconfig, 'access', _361 => _361.logger, 'optionalAccess', _362 => _362.lv, 'optionalAccess', _363 => _363.view]) && console.error(
3101
+ _optionalChain([$asai, 'access', _383 => _383.hostconfig, 'access', _384 => _384.logger, 'optionalAccess', _385 => _385.lv, 'optionalAccess', _386 => _386.view]) && console.error(
2948
3102
  666.2203,
2949
3103
  `${wsname}=${$asai.command.commandconfig.clientws[wsname]} is error.`,
2950
3104
  err
@@ -2953,14 +3107,14 @@ var WsClient_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($a
2953
3107
  });
2954
3108
  $asai.clientws[wsname].socket.on("close", () => {
2955
3109
  $asai.clientws[wsname].open = 0;
2956
- _optionalChain([$asai, 'access', _364 => _364.hostconfig, 'access', _365 => _365.logger, 'optionalAccess', _366 => _366.lv, 'optionalAccess', _367 => _367.view]) && console.error(
3110
+ _optionalChain([$asai, 'access', _387 => _387.hostconfig, 'access', _388 => _388.logger, 'optionalAccess', _389 => _389.lv, 'optionalAccess', _390 => _390.view]) && console.error(
2957
3111
  666.2205,
2958
3112
  `${wsname}=${$asai.command.commandconfig.clientws[wsname]} is close.`
2959
3113
  );
2960
3114
  reject();
2961
3115
  });
2962
3116
  $asai.clientws[wsname].socket.onopen = () => {
2963
- _optionalChain([$asai, 'access', _368 => _368.hostconfig, 'access', _369 => _369.logger, 'optionalAccess', _370 => _370.lv, 'optionalAccess', _371 => _371.view]) && console.log(
3117
+ _optionalChain([$asai, 'access', _391 => _391.hostconfig, 'access', _392 => _392.logger, 'optionalAccess', _393 => _393.lv, 'optionalAccess', _394 => _394.view]) && console.log(
2964
3118
  666.2201,
2965
3119
  `${wsname}=${$asai.command.commandconfig.clientws[wsname]} is open.`
2966
3120
  );
@@ -2983,7 +3137,7 @@ var WsClient_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($a
2983
3137
  const key = getKeyByData(messageData);
2984
3138
  const task = $asai.clientws[wsname].tasks.get(key);
2985
3139
  if (task) {
2986
- _optionalChain([task, 'optionalAccess', _372 => _372.callback, 'call', _373 => _373(messageData)]);
3140
+ _optionalChain([task, 'optionalAccess', _395 => _395.callback, 'call', _396 => _396(messageData)]);
2987
3141
  if (messageData.ty && !messageData.id) {
2988
3142
  } else {
2989
3143
  $asai.clientws[wsname].tasks.delete(key);
@@ -3037,7 +3191,7 @@ var WsClient_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($a
3037
3191
  }
3038
3192
  _chunkSMVZ3ZDJcjs.__name.call(void 0, clientwsWatch, "clientwsWatch");
3039
3193
  function clientwsWatchOff(messageData) {
3040
- if (_optionalChain([messageData, 'optionalAccess', _374 => _374.ty]) === "clear") {
3194
+ if (_optionalChain([messageData, 'optionalAccess', _397 => _397.ty]) === "clear") {
3041
3195
  $asai.clientws[wsname].tasks = /* @__PURE__ */ new Map();
3042
3196
  } else {
3043
3197
  const key = getKeyByData(messageData);
@@ -3078,7 +3232,7 @@ var ping_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai)
3078
3232
  var web_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3079
3233
  function chatBoard(msgdata, ws2, hostdir, req) {
3080
3234
  let room;
3081
- if (_optionalChain([msgdata, 'access', _375 => _375.db, 'optionalAccess', _376 => _376.room]) && typeof msgdata.db.room === "string") {
3235
+ if (_optionalChain([msgdata, 'access', _398 => _398.db, 'optionalAccess', _399 => _399.room]) && typeof msgdata.db.room === "string") {
3082
3236
  room = msgdata.db.room;
3083
3237
  delete msgdata.db.room;
3084
3238
  } else {
@@ -3135,26 +3289,26 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3135
3289
  removeFile: removeFile2,
3136
3290
  resolvePathUnderBase: resolvePathUnderBase2
3137
3291
  } = $asai.$lib.AsFs;
3138
- const { sendSuccess, sendFail, mnLog } = _optionalChain([$asai, 'access', _377 => _377.$lib, 'optionalAccess', _378 => _378.reqWork, 'optionalCall', _379 => _379($asai)]);
3292
+ const { sendSuccess, sendFail, mnLog } = _optionalChain([$asai, 'access', _400 => _400.$lib, 'optionalAccess', _401 => _401.reqWork, 'optionalCall', _402 => _402($asai)]);
3139
3293
  function mgLog(...arg) {
3140
3294
  mnLog("LOG", ...arg);
3141
3295
  }
3142
3296
  _chunkSMVZ3ZDJcjs.__name.call(void 0, mgLog, "mgLog");
3143
3297
  function getDir(opt) {
3144
- let tmpDir = _optionalChain([opt, 'access', _380 => _380.qrdata, 'optionalAccess', _381 => _381.dir]) || _optionalChain([opt, 'access', _382 => _382.data, 'optionalAccess', _383 => _383.dir]);
3298
+ let tmpDir = _optionalChain([opt, 'access', _403 => _403.qrdata, 'optionalAccess', _404 => _404.dir]) || _optionalChain([opt, 'access', _405 => _405.data, 'optionalAccess', _406 => _406.dir]);
3145
3299
  if (tmpDir) {
3146
3300
  tmpDir = decodeURIComponent(tmpDir);
3147
3301
  } else {
3148
- tmpDir = _optionalChain([opt, 'access', _384 => _384.qrdata, 'optionalAccess', _385 => _385.ty]) || _optionalChain([opt, 'access', _386 => _386.data, 'optionalAccess', _387 => _387.ty]);
3302
+ tmpDir = _optionalChain([opt, 'access', _407 => _407.qrdata, 'optionalAccess', _408 => _408.ty]) || _optionalChain([opt, 'access', _409 => _409.data, 'optionalAccess', _410 => _410.ty]);
3149
3303
  if (tmpDir) {
3150
3304
  tmpDir = decodeURIComponent(tmpDir);
3151
3305
  if (tmpDir === "access-clf" || tmpDir === "access-w3c") {
3152
- tmpDir = _optionalChain([$asai, 'access', _388 => _388.hostconfig, 'access', _389 => _389.logger, 'optionalAccess', _390 => _390.path, 'optionalAccess', _391 => _391.access]) || "";
3306
+ tmpDir = _optionalChain([$asai, 'access', _411 => _411.hostconfig, 'access', _412 => _412.logger, 'optionalAccess', _413 => _413.path, 'optionalAccess', _414 => _414.access]) || "";
3153
3307
  } else {
3154
- tmpDir = _optionalChain([$asai, 'access', _392 => _392.hostconfig, 'access', _393 => _393.logger, 'optionalAccess', _394 => _394.path, 'optionalAccess', _395 => _395[tmpDir]]) || "";
3308
+ tmpDir = _optionalChain([$asai, 'access', _415 => _415.hostconfig, 'access', _416 => _416.logger, 'optionalAccess', _417 => _417.path, 'optionalAccess', _418 => _418[tmpDir]]) || "";
3155
3309
  }
3156
3310
  } else {
3157
- tmpDir = _optionalChain([$asai, 'access', _396 => _396.hostconfig, 'access', _397 => _397.logger, 'optionalAccess', _398 => _398.path, 'optionalAccess', _399 => _399.client]) || "";
3311
+ tmpDir = _optionalChain([$asai, 'access', _419 => _419.hostconfig, 'access', _420 => _420.logger, 'optionalAccess', _421 => _421.path, 'optionalAccess', _422 => _422.client]) || "";
3158
3312
  }
3159
3313
  }
3160
3314
  return tmpDir;
@@ -3172,7 +3326,7 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3172
3326
  return;
3173
3327
  }
3174
3328
  if (url.startsWith("/api/asailog/manage/add/")) {
3175
- if (!await ensureLv(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3329
+ if (!await ensureLv(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3176
3330
  try {
3177
3331
  mgLog("add", "server:", opt.data);
3178
3332
  await $asai.$log("LOG", "ADD", opt.data);
@@ -3186,7 +3340,7 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3186
3340
  if (!await ensureLv(req, $asai, 3)) return sendFail(res, "Forbidden", opt);
3187
3341
  try {
3188
3342
  const baseDir = getDir(opt);
3189
- const relPath = decodeURIComponent(_optionalChain([opt, 'access', _400 => _400.qrdata, 'optionalAccess', _401 => _401.path]) || _optionalChain([opt, 'access', _402 => _402.data, 'optionalAccess', _403 => _403.path]));
3343
+ const relPath = decodeURIComponent(_optionalChain([opt, 'access', _423 => _423.qrdata, 'optionalAccess', _424 => _424.path]) || _optionalChain([opt, 'access', _425 => _425.data, 'optionalAccess', _426 => _426.path]));
3190
3344
  const jsonpath = resolvePathUnderBase2(baseDir, relPath);
3191
3345
  await ensureFile2(jsonpath);
3192
3346
  mgLog("ENSURE", jsonpath);
@@ -3205,9 +3359,9 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3205
3359
  async function get(req, res, hostdir, opt) {
3206
3360
  const url = req.url;
3207
3361
  if (url.startsWith("/api/asailog/manage/selectlist/")) {
3208
- if (!await ensureLv(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3362
+ if (!await ensureLv(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3209
3363
  try {
3210
- const ty = decodeURIComponent(_optionalChain([opt, 'access', _404 => _404.qrdata, 'optionalAccess', _405 => _405.ty]) || _optionalChain([opt, 'access', _406 => _406.data, 'optionalAccess', _407 => _407.ty]) || "client");
3364
+ const ty = decodeURIComponent(_optionalChain([opt, 'access', _427 => _427.qrdata, 'optionalAccess', _428 => _428.ty]) || _optionalChain([opt, 'access', _429 => _429.data, 'optionalAccess', _430 => _430.ty]) || "client");
3211
3365
  if (!_chunkHR5JKN7Ycjs.prefersDiskLogAccess.call(void 0, $asai) && _chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai) && (ty === "client" || ty === "server" || ty === "sec")) {
3212
3366
  const kind = ty === "sec" ? "sec" : "web";
3213
3367
  const groups = await _chunkHR5JKN7Ycjs.listUnifiedGroups.call(void 0, $asai, { kind, source: ty === "sec" ? "sec" : ty });
@@ -3233,10 +3387,10 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3233
3387
  return;
3234
3388
  }
3235
3389
  if (url.startsWith("/api/asailog/manage/select/")) {
3236
- if (!await ensureLv(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3390
+ if (!await ensureLv(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3237
3391
  try {
3238
- const ty = decodeURIComponent(_optionalChain([opt, 'access', _408 => _408.qrdata, 'optionalAccess', _409 => _409.ty]) || _optionalChain([opt, 'access', _410 => _410.data, 'optionalAccess', _411 => _411.ty]) || "client");
3239
- const relPath = decodeURIComponent(_optionalChain([opt, 'access', _412 => _412.qrdata, 'optionalAccess', _413 => _413.path]) || _optionalChain([opt, 'access', _414 => _414.data, 'optionalAccess', _415 => _415.path]));
3392
+ const ty = decodeURIComponent(_optionalChain([opt, 'access', _431 => _431.qrdata, 'optionalAccess', _432 => _432.ty]) || _optionalChain([opt, 'access', _433 => _433.data, 'optionalAccess', _434 => _434.ty]) || "client");
3393
+ const relPath = decodeURIComponent(_optionalChain([opt, 'access', _435 => _435.qrdata, 'optionalAccess', _436 => _436.path]) || _optionalChain([opt, 'access', _437 => _437.data, 'optionalAccess', _438 => _438.path]));
3240
3394
  if (!_chunkHR5JKN7Ycjs.prefersDiskLogAccess.call(void 0, $asai) && _chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai) && (ty === "client" || ty === "server" || ty === "sec")) {
3241
3395
  const data2 = await _chunkHR5JKN7Ycjs.readWebLogFromStore.call(void 0, $asai, ty, relPath);
3242
3396
  if (data2) {
@@ -3264,7 +3418,7 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3264
3418
  if (!await ensureLv(req, $asai, 3)) return sendFail(res, "Forbidden", opt);
3265
3419
  try {
3266
3420
  const baseDir = getDir(opt);
3267
- const relPath = decodeURIComponent(_optionalChain([opt, 'access', _416 => _416.qrdata, 'optionalAccess', _417 => _417.path]) || _optionalChain([opt, 'access', _418 => _418.data, 'optionalAccess', _419 => _419.path]));
3421
+ const relPath = decodeURIComponent(_optionalChain([opt, 'access', _439 => _439.qrdata, 'optionalAccess', _440 => _440.path]) || _optionalChain([opt, 'access', _441 => _441.data, 'optionalAccess', _442 => _442.path]));
3268
3422
  const fileName = relPath.split(/[/\\]/).pop() || relPath;
3269
3423
  if (_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai)) {
3270
3424
  await _chunkHR5JKN7Ycjs.purgeStoreEntriesForFile.call(void 0, $asai, fileName).catch(() => void 0);
@@ -3287,14 +3441,14 @@ var logmanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($
3287
3441
 
3288
3442
  // src/infra/siem-auth.ts
3289
3443
  function isSiemEnabled($asai) {
3290
- const cfg = _optionalChain([$asai, 'optionalAccess', _420 => _420.hostconfig, 'optionalAccess', _421 => _421.logger, 'optionalAccess', _422 => _422.siem]);
3291
- return !!(_optionalChain([cfg, 'optionalAccess', _423 => _423.enabled]) && getSiemToken($asai));
3444
+ const cfg = _optionalChain([$asai, 'optionalAccess', _443 => _443.hostconfig, 'optionalAccess', _444 => _444.logger, 'optionalAccess', _445 => _445.siem]);
3445
+ return !!(_optionalChain([cfg, 'optionalAccess', _446 => _446.enabled]) && getSiemToken($asai));
3292
3446
  }
3293
3447
  _chunkSMVZ3ZDJcjs.__name.call(void 0, isSiemEnabled, "isSiemEnabled");
3294
3448
  function getSiemToken($asai) {
3295
3449
  const fromEnv = process.env.ASAI_SIEM_TOKEN;
3296
3450
  if (typeof fromEnv === "string" && fromEnv.trim()) return fromEnv.trim();
3297
- const fromCfg = _optionalChain([$asai, 'optionalAccess', _424 => _424.hostconfig, 'optionalAccess', _425 => _425.logger, 'optionalAccess', _426 => _426.siem, 'optionalAccess', _427 => _427.token]);
3451
+ const fromCfg = _optionalChain([$asai, 'optionalAccess', _447 => _447.hostconfig, 'optionalAccess', _448 => _448.logger, 'optionalAccess', _449 => _449.siem, 'optionalAccess', _450 => _450.token]);
3298
3452
  return typeof fromCfg === "string" ? fromCfg.trim() : "";
3299
3453
  }
3300
3454
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getSiemToken, "getSiemToken");
@@ -3302,9 +3456,9 @@ function isSiemTokenValid($asai, req) {
3302
3456
  if (!isSiemEnabled($asai)) return false;
3303
3457
  const expected = getSiemToken($asai);
3304
3458
  if (!expected) return false;
3305
- const header = _optionalChain([req, 'optionalAccess', _428 => _428.headers, 'optionalAccess', _429 => _429["x-siem-token"]]) || _optionalChain([req, 'optionalAccess', _430 => _430.headers, 'optionalAccess', _431 => _431["x-api-key"]]);
3459
+ const header = _optionalChain([req, 'optionalAccess', _451 => _451.headers, 'optionalAccess', _452 => _452["x-siem-token"]]) || _optionalChain([req, 'optionalAccess', _453 => _453.headers, 'optionalAccess', _454 => _454["x-api-key"]]);
3306
3460
  if (typeof header === "string" && header === expected) return true;
3307
- const q = _optionalChain([req, 'optionalAccess', _432 => _432.query]) || {};
3461
+ const q = _optionalChain([req, 'optionalAccess', _455 => _455.query]) || {};
3308
3462
  const qToken = q.siem_token || q.token;
3309
3463
  return typeof qToken === "string" && qToken === expected;
3310
3464
  }
@@ -3328,20 +3482,20 @@ function getNs(raw) {
3328
3482
  }
3329
3483
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getNs, "getNs");
3330
3484
  async function ensureServerUser(req, $asai) {
3331
- if (Array.isArray(_optionalChain([req, 'optionalAccess', _433 => _433.Userinfo])) && req.Userinfo[0]) {
3485
+ if (Array.isArray(_optionalChain([req, 'optionalAccess', _456 => _456.Userinfo])) && req.Userinfo[0]) {
3332
3486
  await attachServerUserLevel(req, $asai);
3333
3487
  }
3334
3488
  }
3335
3489
  _chunkSMVZ3ZDJcjs.__name.call(void 0, ensureServerUser, "ensureServerUser");
3336
3490
  var interventionlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3337
- const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _434 => _434.$lib, 'optionalAccess', _435 => _435.reqWork, 'optionalCall', _436 => _436($asai)]) || {};
3491
+ const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _457 => _457.$lib, 'optionalAccess', _458 => _458.reqWork, 'optionalCall', _459 => _459($asai)]) || {};
3338
3492
  const IL = $asai.$lib.InterventionLog;
3339
3493
  async function get(req, res, hostdir, opt) {
3340
3494
  const url = req.url || "";
3341
3495
  if (url.startsWith("/api/asailog/intervention/selectlist/")) {
3342
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3496
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3343
3497
  try {
3344
- const ns = getNs(_optionalChain([opt, 'access', _437 => _437.qrdata, 'optionalAccess', _438 => _438.ns]) || _optionalChain([opt, 'access', _439 => _439.data, 'optionalAccess', _440 => _440.ns]));
3498
+ const ns = getNs(_optionalChain([opt, 'access', _460 => _460.qrdata, 'optionalAccess', _461 => _461.ns]) || _optionalChain([opt, 'access', _462 => _462.data, 'optionalAccess', _463 => _463.ns]));
3345
3499
  let list = await IL.listInterventionFiles($asai, ns);
3346
3500
  if (_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai) && !_chunkHR5JKN7Ycjs.prefersDiskLogAccess.call(void 0, $asai)) {
3347
3501
  const groups = await _chunkHR5JKN7Ycjs.listUnifiedGroups.call(void 0, $asai, { kind: "intervention", ns });
@@ -3353,27 +3507,27 @@ var interventionlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void
3353
3507
  }
3354
3508
  return sendSuccess(res, { ns, files: list }, opt);
3355
3509
  } catch (err) {
3356
- return sendFail(res, _optionalChain([err, 'optionalAccess', _441 => _441.message]) || err, opt);
3510
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _464 => _464.message]) || err, opt);
3357
3511
  }
3358
3512
  }
3359
3513
  if (url.startsWith("/api/asailog/intervention/select/")) {
3360
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3514
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3361
3515
  try {
3362
- const name = decodeURIComponent(_optionalChain([opt, 'access', _442 => _442.qrdata, 'optionalAccess', _443 => _443.name]) || _optionalChain([opt, 'access', _444 => _444.data, 'optionalAccess', _445 => _445.name]) || "");
3363
- const ns = getNs(_optionalChain([opt, 'access', _446 => _446.qrdata, 'optionalAccess', _447 => _447.ns]) || _optionalChain([opt, 'access', _448 => _448.data, 'optionalAccess', _449 => _449.ns]));
3516
+ const name = decodeURIComponent(_optionalChain([opt, 'access', _465 => _465.qrdata, 'optionalAccess', _466 => _466.name]) || _optionalChain([opt, 'access', _467 => _467.data, 'optionalAccess', _468 => _468.name]) || "");
3517
+ const ns = getNs(_optionalChain([opt, 'access', _469 => _469.qrdata, 'optionalAccess', _470 => _470.ns]) || _optionalChain([opt, 'access', _471 => _471.data, 'optionalAccess', _472 => _472.ns]));
3364
3518
  if (!name) return sendFail(res, "name required", opt);
3365
3519
  const content = await IL.readInterventionFile($asai, name, ns);
3366
3520
  return sendSuccess(res, { ns, ...content }, opt);
3367
3521
  } catch (err) {
3368
- return sendFail(res, _optionalChain([err, 'optionalAccess', _450 => _450.message]) || err, opt);
3522
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _473 => _473.message]) || err, opt);
3369
3523
  }
3370
3524
  }
3371
3525
  if (url.startsWith("/api/asailog/intervention/types/")) {
3372
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3526
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3373
3527
  try {
3374
3528
  return sendSuccess(res, IL.getInterventionTaxonomy($asai), opt);
3375
3529
  } catch (err) {
3376
- return sendFail(res, _optionalChain([err, 'optionalAccess', _451 => _451.message]) || err, opt);
3530
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _474 => _474.message]) || err, opt);
3377
3531
  }
3378
3532
  }
3379
3533
  }
@@ -3381,7 +3535,7 @@ var interventionlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void
3381
3535
  async function post(req, res, hostdir, opt) {
3382
3536
  const url = req.url || "";
3383
3537
  if (url.startsWith("/api/asailog/intervention/delete/")) {
3384
- if (!await ensureLogWriteAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) return sendFail(res, "Forbidden", opt);
3538
+ if (!await ensureLogWriteAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) return sendFail(res, "Forbidden", opt);
3385
3539
  await ensureServerUser(req, $asai);
3386
3540
  const lv = getRequestUserLevel(req);
3387
3541
  const us = getRequestUsername(req);
@@ -3403,7 +3557,7 @@ var interventionlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void
3403
3557
  );
3404
3558
  return sendSuccess(res, { ns, ...result }, opt);
3405
3559
  } catch (err) {
3406
- return sendFail(res, _optionalChain([err, 'optionalAccess', _452 => _452.message]) || err, opt);
3560
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _475 => _475.message]) || err, opt);
3407
3561
  }
3408
3562
  }
3409
3563
  }
@@ -3422,11 +3576,11 @@ function parseQuery(opt) {
3422
3576
  }
3423
3577
  _chunkSMVZ3ZDJcjs.__name.call(void 0, parseQuery, "parseQuery");
3424
3578
  function parseBody(opt) {
3425
- if (!_optionalChain([opt, 'optionalAccess', _453 => _453.data])) return {};
3579
+ if (!_optionalChain([opt, 'optionalAccess', _476 => _476.data])) return {};
3426
3580
  if (typeof opt.data === "string") {
3427
3581
  try {
3428
3582
  return JSON.parse(opt.data);
3429
- } catch (e36) {
3583
+ } catch (e45) {
3430
3584
  return {};
3431
3585
  }
3432
3586
  }
@@ -3434,21 +3588,21 @@ function parseBody(opt) {
3434
3588
  }
3435
3589
  _chunkSMVZ3ZDJcjs.__name.call(void 0, parseBody, "parseBody");
3436
3590
  var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3437
- const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _454 => _454.$lib, 'optionalAccess', _455 => _455.reqWork, 'optionalCall', _456 => _456($asai)]) || {};
3591
+ const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _477 => _477.$lib, 'optionalAccess', _478 => _478.reqWork, 'optionalCall', _479 => _479($asai)]) || {};
3438
3592
  const IL = $asai.$lib.InterventionLog;
3439
3593
  async function get(req, res, hostdir, opt) {
3440
3594
  const url = req.url || "";
3441
3595
  const q = parseQuery(opt);
3442
3596
  if (url.startsWith("/api/asailog/store/config/")) {
3443
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3597
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3444
3598
  try {
3445
3599
  return sendSuccess(res, _chunkHR5JKN7Ycjs.getLogStoreMeta.call(void 0, $asai), opt);
3446
3600
  } catch (err) {
3447
- return sendFail(res, _optionalChain([err, 'optionalAccess', _457 => _457.message]) || err, opt);
3601
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _480 => _480.message]) || err, opt);
3448
3602
  }
3449
3603
  }
3450
3604
  if (url.startsWith("/api/asailog/store/stats/")) {
3451
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3605
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3452
3606
  if (!_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai)) {
3453
3607
  return sendSuccess(res, { store: "disabled", message: "logger.store not configured", config: _chunkHR5JKN7Ycjs.getLogStoreMeta.call(void 0, $asai) }, opt);
3454
3608
  }
@@ -3457,21 +3611,21 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3457
3611
  const stats = await _chunkHR5JKN7Ycjs.getUnifiedStats.call(void 0, $asai);
3458
3612
  return sendSuccess(res, { store: storeType, stats, config: _chunkHR5JKN7Ycjs.getLogStoreMeta.call(void 0, $asai) }, opt);
3459
3613
  } catch (err) {
3460
- return sendFail(res, _optionalChain([err, 'optionalAccess', _458 => _458.message]) || err, opt);
3614
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _481 => _481.message]) || err, opt);
3461
3615
  }
3462
3616
  }
3463
3617
  if (url.startsWith("/api/asailog/store/compliance/")) {
3464
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3618
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3465
3619
  try {
3466
3620
  const ns = q.ns === "test" ? "test" : "prod";
3467
3621
  const report = await _chunkHR5JKN7Ycjs.getComplianceReport.call(void 0, $asai, ns);
3468
3622
  return sendSuccess(res, report, opt);
3469
3623
  } catch (err) {
3470
- return sendFail(res, _optionalChain([err, 'optionalAccess', _459 => _459.message]) || err, opt);
3624
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _482 => _482.message]) || err, opt);
3471
3625
  }
3472
3626
  }
3473
3627
  if (url.startsWith("/api/asailog/store/search/")) {
3474
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3628
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3475
3629
  if (!_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai)) return sendFail(res, "Log store not enabled", opt);
3476
3630
  try {
3477
3631
  const result = await _chunkHR5JKN7Ycjs.searchUnifiedLogs.call(void 0, $asai, {
@@ -3489,11 +3643,11 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3489
3643
  });
3490
3644
  return sendSuccess(res, result, opt);
3491
3645
  } catch (err) {
3492
- return sendFail(res, _optionalChain([err, 'optionalAccess', _460 => _460.message]) || err, opt);
3646
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _483 => _483.message]) || err, opt);
3493
3647
  }
3494
3648
  }
3495
3649
  if (url.startsWith("/api/asailog/store/export/")) {
3496
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3650
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3497
3651
  try {
3498
3652
  const kind = q.kind || "intervention";
3499
3653
  const format = q.format || "raw";
@@ -3510,28 +3664,28 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3510
3664
  });
3511
3665
  return sendSuccess(res, payload, opt);
3512
3666
  } catch (err) {
3513
- return sendFail(res, _optionalChain([err, 'optionalAccess', _461 => _461.message]) || err, opt);
3667
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _484 => _484.message]) || err, opt);
3514
3668
  }
3515
3669
  }
3516
3670
  if (url.startsWith("/api/asailog/store/taxonomy/")) {
3517
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3671
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3518
3672
  try {
3519
3673
  return sendSuccess(res, IL.getInterventionTaxonomy($asai), opt);
3520
3674
  } catch (err) {
3521
- return sendFail(res, _optionalChain([err, 'optionalAccess', _462 => _462.message]) || err, opt);
3675
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _485 => _485.message]) || err, opt);
3522
3676
  }
3523
3677
  }
3524
3678
  if (url.startsWith("/api/asailog/store/formats/")) {
3525
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3679
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3526
3680
  try {
3527
3681
  const { getLogFormatTaxonomy } = await Promise.resolve().then(() => _interopRequireWildcard(require("./log-formats-TUXGMCCU.cjs")));
3528
3682
  return sendSuccess(res, getLogFormatTaxonomy($asai), opt);
3529
3683
  } catch (err) {
3530
- return sendFail(res, _optionalChain([err, 'optionalAccess', _463 => _463.message]) || err, opt);
3684
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _486 => _486.message]) || err, opt);
3531
3685
  }
3532
3686
  }
3533
3687
  if (url.startsWith("/api/asailog/store/selectlist/")) {
3534
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3688
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3535
3689
  if (!_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai)) return sendFail(res, "Log store not enabled", opt);
3536
3690
  try {
3537
3691
  const kind = q.kind ? String(q.kind) : void 0;
@@ -3554,11 +3708,11 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3554
3708
  }
3555
3709
  return sendSuccess(res, { groups }, opt);
3556
3710
  } catch (err) {
3557
- return sendFail(res, _optionalChain([err, 'optionalAccess', _464 => _464.message]) || err, opt);
3711
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _487 => _487.message]) || err, opt);
3558
3712
  }
3559
3713
  }
3560
3714
  if (url.startsWith("/api/asailog/store/select/")) {
3561
- if (!await ensureLogReadAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3715
+ if (!await ensureLogReadAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "logRead"))) return sendFail(res, "Forbidden", opt);
3562
3716
  if (!_chunkHR5JKN7Ycjs.isLogStoreEnabled.call(void 0, $asai)) return sendFail(res, "Log store not enabled", opt);
3563
3717
  try {
3564
3718
  const id = q.id;
@@ -3588,7 +3742,7 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3588
3742
  });
3589
3743
  return sendSuccess(res, { entries: rows }, opt);
3590
3744
  } catch (err) {
3591
- return sendFail(res, _optionalChain([err, 'optionalAccess', _465 => _465.message]) || err, opt);
3745
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _488 => _488.message]) || err, opt);
3592
3746
  }
3593
3747
  }
3594
3748
  }
@@ -3596,7 +3750,7 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3596
3750
  async function post(req, res, hostdir, opt) {
3597
3751
  const url = req.url || "";
3598
3752
  if (!url.startsWith("/api/asailog/store/archive/")) return;
3599
- if (!await ensureLogWriteAccess(req, $asai, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) return sendFail(res, "Forbidden", opt);
3753
+ if (!await ensureLogWriteAccess(req, $asai, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) return sendFail(res, "Forbidden", opt);
3600
3754
  try {
3601
3755
  const body = parseBody(opt);
3602
3756
  const year = Number(body.year);
@@ -3610,7 +3764,7 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3610
3764
  });
3611
3765
  return sendSuccess(res, result, opt);
3612
3766
  } catch (err) {
3613
- return sendFail(res, _optionalChain([err, 'optionalAccess', _466 => _466.message]) || err, opt);
3767
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _489 => _489.message]) || err, opt);
3614
3768
  }
3615
3769
  }
3616
3770
  _chunkSMVZ3ZDJcjs.__name.call(void 0, post, "post");
@@ -3622,7 +3776,7 @@ var unifiedlog_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3622
3776
 
3623
3777
  var registry = null;
3624
3778
  function resolveFilePath($asai) {
3625
- const root = _optionalChain([$asai, 'optionalAccess', _467 => _467.serverRoot]) || process.cwd();
3779
+ const root = _optionalChain([$asai, 'optionalAccess', _490 => _490.serverRoot]) || process.cwd();
3626
3780
  return nodePath3.join(root, "websys/sys/errorcodes.json");
3627
3781
  }
3628
3782
  _chunkSMVZ3ZDJcjs.__name.call(void 0, resolveFilePath, "resolveFilePath");
@@ -3632,7 +3786,7 @@ function loadErrorCodes($asai) {
3632
3786
  try {
3633
3787
  const raw = fs8.readFileSync(filePath, "utf8");
3634
3788
  registry = JSON.parse(raw);
3635
- } catch (e37) {
3789
+ } catch (e46) {
3636
3790
  registry = { version: "0", errors: {} };
3637
3791
  }
3638
3792
  if ($asai) $asai.errorcodes = registry;
@@ -3640,7 +3794,7 @@ function loadErrorCodes($asai) {
3640
3794
  }
3641
3795
  _chunkSMVZ3ZDJcjs.__name.call(void 0, loadErrorCodes, "loadErrorCodes");
3642
3796
  function getError(ec) {
3643
- return _optionalChain([registry, 'optionalAccess', _468 => _468.errors, 'optionalAccess', _469 => _469[ec]]) || null;
3797
+ return _optionalChain([registry, 'optionalAccess', _491 => _491.errors, 'optionalAccess', _492 => _492[ec]]) || null;
3644
3798
  }
3645
3799
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getError, "getError");
3646
3800
  function hasError(ec) {
@@ -3649,11 +3803,11 @@ function hasError(ec) {
3649
3803
  _chunkSMVZ3ZDJcjs.__name.call(void 0, hasError, "hasError");
3650
3804
  function logError($asai, ec, params) {
3651
3805
  const entry = getError(ec);
3652
- const logFn = _optionalChain([$asai, 'optionalAccess', _470 => _470.$log]) || console.warn;
3806
+ const logFn = _optionalChain([$asai, 'optionalAccess', _493 => _493.$log]) || console.warn;
3653
3807
  if (entry) {
3654
- logFn(`[EC:${ec}]`, entry.id || "", entry.detail || "", _optionalChain([params, 'optionalAccess', _471 => _471.length]) ? params : "");
3808
+ logFn(`[EC:${ec}]`, entry.id || "", entry.detail || "", _optionalChain([params, 'optionalAccess', _494 => _494.length]) ? params : "");
3655
3809
  } else {
3656
- logFn(`[EC:${ec}]`, "(unregistered)", _optionalChain([params, 'optionalAccess', _472 => _472.length]) ? params : "");
3810
+ logFn(`[EC:${ec}]`, "(unregistered)", _optionalChain([params, 'optionalAccess', _495 => _495.length]) ? params : "");
3657
3811
  }
3658
3812
  }
3659
3813
  _chunkSMVZ3ZDJcjs.__name.call(void 0, logError, "logError");
@@ -3681,14 +3835,14 @@ var ErrorCode_default = {
3681
3835
 
3682
3836
  // src/sysserver/api/common/errorcodes.ts
3683
3837
  var errorcodes_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3684
- const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _473 => _473.$lib, 'optionalAccess', _474 => _474.reqWork, 'optionalCall', _475 => _475($asai)]) || {};
3838
+ const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _496 => _496.$lib, 'optionalAccess', _497 => _497.reqWork, 'optionalCall', _498 => _498($asai)]) || {};
3685
3839
  function get(req, res, _hostdir, opt) {
3686
3840
  const url = req.url || "";
3687
3841
  if (url.startsWith("/api/sys/errorcodes/")) {
3688
3842
  try {
3689
3843
  return sendSuccess(res, loadErrorCodes($asai), opt);
3690
3844
  } catch (err) {
3691
- return sendFail(res, _optionalChain([err, 'optionalAccess', _476 => _476.message]) || err, opt);
3845
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _499 => _499.message]) || err, opt);
3692
3846
  }
3693
3847
  }
3694
3848
  }
@@ -3698,9 +3852,9 @@ var errorcodes_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (
3698
3852
 
3699
3853
  // src/sysserver/api/common/sqlitemanage.ts
3700
3854
  var sqlitemanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3701
- const { sendSuccess, sendFail, mnLog } = _optionalChain([$asai, 'optionalAccess', _477 => _477.$lib, 'optionalAccess', _478 => _478.reqWork, 'optionalCall', _479 => _479($asai)]) || {};
3855
+ const { sendSuccess, sendFail, mnLog } = _optionalChain([$asai, 'optionalAccess', _500 => _500.$lib, 'optionalAccess', _501 => _501.reqWork, 'optionalCall', _502 => _502($asai)]) || {};
3702
3856
  function mgLog(...arg) {
3703
- _optionalChain([mnLog, 'optionalCall', _480 => _480("SQLite", ...arg)]);
3857
+ _optionalChain([mnLog, 'optionalCall', _503 => _503("SQLite", ...arg)]);
3704
3858
  }
3705
3859
  _chunkSMVZ3ZDJcjs.__name.call(void 0, mgLog, "mgLog");
3706
3860
  return $asai.$lib.AsDb($asai, {
@@ -3718,7 +3872,7 @@ var sqlitemanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0,
3718
3872
  if (req.url.startsWith("/api/asaisqlite/manage/post")) {
3719
3873
  try {
3720
3874
  mgLog("POST", "custom handler triggered");
3721
- _optionalChain([sendSuccess, 'optionalCall', _481 => _481(res, { data: "post" }, opt)]);
3875
+ _optionalChain([sendSuccess, 'optionalCall', _504 => _504(res, { data: "post" }, opt)]);
3722
3876
  } catch (err) {
3723
3877
  mgLog("ERROR", "post handler", err);
3724
3878
  }
@@ -3735,10 +3889,10 @@ var sqlitemanage_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0,
3735
3889
  table: dataObj.table
3736
3890
  });
3737
3891
  mgLog("SELECT", "completed");
3738
- _optionalChain([sendSuccess, 'optionalCall', _482 => _482(res, resdb, opt)]);
3892
+ _optionalChain([sendSuccess, 'optionalCall', _505 => _505(res, resdb, opt)]);
3739
3893
  } catch (errdb) {
3740
3894
  mgLog("ERROR", "select", errdb);
3741
- _optionalChain([sendFail, 'optionalCall', _483 => _483(res, errdb, opt)]);
3895
+ _optionalChain([sendFail, 'optionalCall', _506 => _506(res, errdb, opt)]);
3742
3896
  }
3743
3897
  return "ok";
3744
3898
  }
@@ -3754,7 +3908,7 @@ function promLine(name, value, labels) {
3754
3908
  }
3755
3909
  _chunkSMVZ3ZDJcjs.__name.call(void 0, promLine, "promLine");
3756
3910
  var health_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
3757
- const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _484 => _484.$lib, 'optionalAccess', _485 => _485.reqWork, 'optionalCall', _486 => _486($asai)]) || {};
3911
+ const { sendSuccess, sendFail } = _optionalChain([$asai, 'access', _507 => _507.$lib, 'optionalAccess', _508 => _508.reqWork, 'optionalCall', _509 => _509($asai)]) || {};
3758
3912
  async function get(req, res, _hostdir, opt) {
3759
3913
  const url = req.url || "";
3760
3914
  if (url.startsWith("/api/sys/health/metrics/")) {
@@ -3763,10 +3917,10 @@ var health_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asa
3763
3917
  let httpTotal = 0;
3764
3918
  let wsTotal = 0;
3765
3919
  for (const set of Object.values($asai.connectionshttp || {})) {
3766
- httpTotal += _optionalChain([set, 'optionalAccess', _487 => _487.size]) || 0;
3920
+ httpTotal += _optionalChain([set, 'optionalAccess', _510 => _510.size]) || 0;
3767
3921
  }
3768
3922
  for (const set of Object.values($asai.connectionsws || {})) {
3769
- wsTotal += _optionalChain([set, 'optionalAccess', _488 => _488.size]) || 0;
3923
+ wsTotal += _optionalChain([set, 'optionalAccess', _511 => _511.size]) || 0;
3770
3924
  }
3771
3925
  const lines = [
3772
3926
  "# HELP asai_uptime_seconds Process uptime",
@@ -3788,7 +3942,7 @@ var health_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asa
3788
3942
  res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
3789
3943
  return res.end(lines.join("\n") + "\n");
3790
3944
  } catch (err) {
3791
- return sendFail(res, _optionalChain([err, 'optionalAccess', _489 => _489.message]) || err, opt);
3945
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _512 => _512.message]) || err, opt);
3792
3946
  }
3793
3947
  }
3794
3948
  if (url.startsWith("/api/sys/health/status/")) {
@@ -3801,10 +3955,10 @@ var health_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asa
3801
3955
  memory: process.memoryUsage(),
3802
3956
  quota: {
3803
3957
  http: Object.fromEntries(
3804
- Object.entries($asai.connectionshttp || {}).map(([k, v]) => [k, _optionalChain([v, 'optionalAccess', _490 => _490.size]) || 0])
3958
+ Object.entries($asai.connectionshttp || {}).map(([k, v]) => [k, _optionalChain([v, 'optionalAccess', _513 => _513.size]) || 0])
3805
3959
  ),
3806
3960
  ws: Object.fromEntries(
3807
- Object.entries($asai.connectionsws || {}).map(([k, v]) => [k, _optionalChain([v, 'optionalAccess', _491 => _491.size]) || 0])
3961
+ Object.entries($asai.connectionsws || {}).map(([k, v]) => [k, _optionalChain([v, 'optionalAccess', _514 => _514.size]) || 0])
3808
3962
  )
3809
3963
  }
3810
3964
  },
@@ -3845,7 +3999,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, sanitizeString, "sanitizeString");
3845
3999
  // src/sysserver/api/login/service/session.ts
3846
4000
 
3847
4001
  function getSessionTtlMs($asai) {
3848
- const hours = _nullishCoalesce(_optionalChain([$asai, 'optionalAccess', _492 => _492.hostconfig, 'optionalAccess', _493 => _493.security, 'optionalAccess', _494 => _494.sessionTtlHours]), () => ( 24));
4002
+ const hours = _nullishCoalesce(_optionalChain([$asai, 'optionalAccess', _515 => _515.hostconfig, 'optionalAccess', _516 => _516.security, 'optionalAccess', _517 => _517.sessionTtlHours]), () => ( 24));
3849
4003
  return Number(hours) * 3600 * 1e3;
3850
4004
  }
3851
4005
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getSessionTtlMs, "getSessionTtlMs");
@@ -3862,7 +4016,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, generatePriKey, "generatePriKey");
3862
4016
  function createSessionKeys($asai) {
3863
4017
  const sessionId = _crypto.randomUUID.call(void 0, );
3864
4018
  const pri = generatePriKey();
3865
- const sn = _optionalChain([$asai, 'optionalAccess', _495 => _495.hostconfig, 'optionalAccess', _496 => _496.asaisn]);
4019
+ const sn = _optionalChain([$asai, 'optionalAccess', _518 => _518.hostconfig, 'optionalAccess', _519 => _519.asaisn]);
3866
4020
  if (!sn) throw new Error("[session] ASAI_ASAISN \u672A\u914D\u7F6E");
3867
4021
  const pub = $asai.$lib.AsCode.asencode(pri, sn);
3868
4022
  return { pri, pub, sessionId };
@@ -3889,9 +4043,9 @@ var API_ADMIN_PREFIXES = ["/api/user/login/admin/"];
3889
4043
  function getMinLevelForApiPath(pathname, $asai) {
3890
4044
  if (API_ADMIN_PREFIXES.some((p) => pathname.startsWith(p))) {
3891
4045
  if (pathname.includes("/admin/update") || pathname.includes("/admin/kick") || pathname.includes("/admin/delete") || pathname.includes("/admin/resetpass")) {
3892
- return $asai ? _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite") : _chunkZK4O4Z2Ocjs.USER_LV.DEVELOPER;
4046
+ return $asai ? _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite") : _chunk5EWEKXQIcjs.USER_LV.DEVELOPER;
3893
4047
  }
3894
- return $asai ? _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminRead") : _chunkZK4O4Z2Ocjs.USER_LV.ADMIN;
4048
+ return $asai ? _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminRead") : _chunk5EWEKXQIcjs.USER_LV.ADMIN;
3895
4049
  }
3896
4050
  return 0;
3897
4051
  }
@@ -3912,20 +4066,20 @@ function unwrapJsonString(value) {
3912
4066
  if (!text.startsWith("{") && !text.startsWith("[")) return value;
3913
4067
  try {
3914
4068
  return JSON.parse(text);
3915
- } catch (e38) {
4069
+ } catch (e47) {
3916
4070
  return value;
3917
4071
  }
3918
4072
  }
3919
4073
  _chunkSMVZ3ZDJcjs.__name.call(void 0, unwrapJsonString, "unwrapJsonString");
3920
4074
  function parseAuthBody(opt) {
3921
- let raw = _optionalChain([opt, 'optionalAccess', _497 => _497.data]);
4075
+ let raw = _optionalChain([opt, 'optionalAccess', _520 => _520.data]);
3922
4076
  if (raw == null || raw === "") return {};
3923
4077
  if (typeof raw === "string") {
3924
4078
  const text = raw.trim();
3925
4079
  if (!text) return {};
3926
4080
  try {
3927
4081
  raw = JSON.parse(text);
3928
- } catch (e39) {
4082
+ } catch (e48) {
3929
4083
  if (text.includes("=") && !text.startsWith("{") && !text.startsWith("[")) {
3930
4084
  raw = Object.fromEntries(new URLSearchParams(text));
3931
4085
  } else {
@@ -3993,8 +4147,39 @@ async function purgeOfflineSessions($asai, hostdir, store) {
3993
4147
  _chunkSMVZ3ZDJcjs.__name.call(void 0, purgeOfflineSessions, "purgeOfflineSessions");
3994
4148
 
3995
4149
  // src/sysserver/api/login/index.ts
4150
+
4151
+
4152
+ async function resolveUserLv($asai, store, us, wsLv) {
4153
+ if (!us) return null;
4154
+ try {
4155
+ const user = await store.findByUsername(us);
4156
+ if (user && user.lv != null && Number.isFinite(Number(user.lv))) {
4157
+ return Number(user.lv);
4158
+ }
4159
+ } catch (e49) {
4160
+ }
4161
+ try {
4162
+ const cfg = _chunkFRPN33BYcjs.getUserStoreConfig.call(void 0, $asai);
4163
+ const dir = String(_optionalChain([cfg, 'optionalAccess', _521 => _521.opt, 'optionalAccess', _522 => _522.dir]) || "");
4164
+ if (dir) {
4165
+ const base = nodePath2.default.isAbsolute(dir) ? dir : nodePath2.default.join(process.cwd(), dir);
4166
+ const safeUs = us.replace(/[\\/:*?"<>|]/g, "");
4167
+ const file = nodePath2.default.join(base, "json", `${safeUs}.json`);
4168
+ if (safeUs && fs3.default.existsSync(file)) {
4169
+ const raw = JSON.parse(fs3.default.readFileSync(file, "utf8"));
4170
+ const lv = Number(_optionalChain([raw, 'optionalAccess', _523 => _523.lv]));
4171
+ if (Number.isFinite(lv)) return lv;
4172
+ }
4173
+ }
4174
+ } catch (e50) {
4175
+ }
4176
+ if (wsLv === null || wsLv === void 0 || wsLv === "") return null;
4177
+ const n = Number(wsLv);
4178
+ return Number.isFinite(n) ? n : null;
4179
+ }
4180
+ _chunkSMVZ3ZDJcjs.__name.call(void 0, resolveUserLv, "resolveUserLv");
3996
4181
  function getSecurity($asai) {
3997
- return _optionalChain([$asai, 'optionalAccess', _498 => _498.hostconfig, 'optionalAccess', _499 => _499.security]) || {};
4182
+ return _optionalChain([$asai, 'optionalAccess', _524 => _524.hostconfig, 'optionalAccess', _525 => _525.security]) || {};
3998
4183
  }
3999
4184
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getSecurity, "getSecurity");
4000
4185
  function getQuota2($asai) {
@@ -4005,9 +4190,9 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, getQuota2, "getQuota");
4005
4190
  async function canLogin($asai, us, hostdir) {
4006
4191
  const quota = getQuota2($asai);
4007
4192
  if (!quota.enabled) return { ok: true };
4008
- const store = _chunkZK4O4Z2Ocjs.createUserStore.call(void 0, $asai);
4193
+ const store = _chunk5EWEKXQIcjs.createUserStore.call(void 0, $asai);
4009
4194
  const total = await countOnlineSessions($asai, hostdir, store);
4010
- const maxLogin = _nullishCoalesce(_nullishCoalesce(quota.maxLoginSessions, () => ( _optionalChain([$asai, 'optionalAccess', _500 => _500.hostconfig, 'optionalAccess', _501 => _501.hosts, 'optionalAccess', _502 => _502.default, 'optionalAccess', _503 => _503.maxonline]))), () => ( 100));
4195
+ const maxLogin = _nullishCoalesce(_nullishCoalesce(quota.maxLoginSessions, () => ( _optionalChain([$asai, 'optionalAccess', _526 => _526.hostconfig, 'optionalAccess', _527 => _527.hosts, 'optionalAccess', _528 => _528.default, 'optionalAccess', _529 => _529.maxonline]))), () => ( 100));
4011
4196
  if (total >= maxLogin) {
4012
4197
  return { ok: false, message: "LOGIN_QUOTA_FULL" };
4013
4198
  }
@@ -4020,7 +4205,7 @@ async function canLogin($asai, us, hostdir) {
4020
4205
  }
4021
4206
  _chunkSMVZ3ZDJcjs.__name.call(void 0, canLogin, "canLogin");
4022
4207
  function publicUser($asai, user) {
4023
- const role = user.role || _chunkGXOFLFFWcjs.resolveRoleForLevel.call(void 0, $asai, user.lv).name;
4208
+ const role = user.role || _chunkFRPN33BYcjs.resolveRoleForLevel.call(void 0, $asai, user.lv).name;
4024
4209
  return {
4025
4210
  us: user.us,
4026
4211
  lv: user.lv,
@@ -4034,14 +4219,14 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, publicUser, "publicUser");
4034
4219
  var bootstrapPromise = null;
4035
4220
  function ensureReady($asai) {
4036
4221
  if (!bootstrapPromise) {
4037
- bootstrapPromise = Promise.all([_chunkZK4O4Z2Ocjs.ensureBootstrapAdmin.call(void 0, $asai), _chunkGXOFLFFWcjs.loadUserLevelConfig.call(void 0, $asai)]).then(() => void 0);
4222
+ bootstrapPromise = Promise.all([_chunk5EWEKXQIcjs.ensureBootstrapAdmin.call(void 0, $asai), _chunkFRPN33BYcjs.loadUserLevelConfig.call(void 0, $asai)]).then(() => void 0);
4038
4223
  }
4039
4224
  return bootstrapPromise;
4040
4225
  }
4041
4226
  _chunkSMVZ3ZDJcjs.__name.call(void 0, ensureReady, "ensureReady");
4042
4227
  var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai) => {
4043
- const { sendSuccess, sendFail, sendErr } = _optionalChain([$asai, 'access', _504 => _504.$lib, 'optionalAccess', _505 => _505.reqWork, 'optionalCall', _506 => _506($asai)]) || {};
4044
- const store = _chunkZK4O4Z2Ocjs.createUserStore.call(void 0, $asai);
4228
+ const { sendSuccess, sendFail, sendErr } = _optionalChain([$asai, 'access', _530 => _530.$lib, 'optionalAccess', _531 => _531.reqWork, 'optionalCall', _532 => _532($asai)]) || {};
4229
+ const store = _chunk5EWEKXQIcjs.createUserStore.call(void 0, $asai);
4045
4230
  async function checkAdmin(req, pathname, minOverride) {
4046
4231
  await attachServerUserLevel(req, $asai);
4047
4232
  const minLv = _nullishCoalesce(minOverride, () => ( getMinLevelForApiPath(pathname, $asai)));
@@ -4060,17 +4245,17 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4060
4245
  const newPass = sanitizeString(pickAuthField(body, "newPass", "newPassword", "newpass"), 128);
4061
4246
  if (!us || !pass || !newPass) return sendErr(res, "AUTH_CREDENTIALS_REQUIRED", void 0, opt);
4062
4247
  const user = await store.findByUsername(us);
4063
- if (!user || !_chunkWXW5DYNUcjs.verifyPassword.call(void 0, pass, user.passHash, user.passSalt)) {
4248
+ if (!user || !_chunkH2QP5J7Xcjs.verifyPassword.call(void 0, pass, user.passHash, user.passSalt)) {
4064
4249
  return sendErr(res, "AUTH_INVALID_CREDENTIALS", void 0, opt);
4065
4250
  }
4066
- const policy = _chunkGXOFLFFWcjs.getPasswordPolicy.call(void 0, $asai);
4067
- const policyErr = _chunkWXW5DYNUcjs.validatePasswordChange.call(void 0, newPass, $asai, user.passHistory);
4251
+ const policy = _chunkFRPN33BYcjs.getPasswordPolicy.call(void 0, $asai);
4252
+ const policyErr = _chunkH2QP5J7Xcjs.validatePasswordChange.call(void 0, newPass, $asai, user.passHistory);
4068
4253
  if (policyErr === "PASSWORD_TOO_SHORT") {
4069
4254
  return sendErr(res, policyErr, [String(policy.minLength)], opt);
4070
4255
  }
4071
4256
  if (policyErr) return sendErr(res, policyErr, void 0, opt);
4072
- const { passHash, passSalt } = _chunkWXW5DYNUcjs.hashPassword.call(void 0, newPass);
4073
- const passHistory = _chunkWXW5DYNUcjs.nextPassHistory.call(void 0, pass, user.passHistory, policy.historyCount);
4257
+ const { passHash, passSalt } = _chunkH2QP5J7Xcjs.hashPassword.call(void 0, newPass);
4258
+ const passHistory = _chunkH2QP5J7Xcjs.nextPassHistory.call(void 0, pass, user.passHistory, policy.historyCount);
4074
4259
  await store.updateUser(us, {
4075
4260
  passHash,
4076
4261
  passSalt,
@@ -4081,7 +4266,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4081
4266
  logSecurityEvent($asai, { type: "AUTH_SUCCESS", path: url, method: "POST", user: us, ip, detail: "password_changed" });
4082
4267
  return sendSuccess(res, { ok: true }, opt);
4083
4268
  } catch (err) {
4084
- return sendFail(res, _optionalChain([err, 'optionalAccess', _507 => _507.message]) || err, opt);
4269
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _533 => _533.message]) || err, opt);
4085
4270
  }
4086
4271
  }
4087
4272
  if (url.startsWith("/api/user/login/register/")) {
@@ -4096,12 +4281,12 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4096
4281
  const emailRaw = pickAuthField(body, "email");
4097
4282
  const email = emailRaw ? sanitizeString(emailRaw, 128) : void 0;
4098
4283
  if (!us || !pass) return sendErr(res, "AUTH_CREDENTIALS_REQUIRED", void 0, opt);
4099
- const policyErr = _chunkWXW5DYNUcjs.validatePasswordChange.call(void 0, pass, $asai);
4284
+ const policyErr = _chunkH2QP5J7Xcjs.validatePasswordChange.call(void 0, pass, $asai);
4100
4285
  if (policyErr === "PASSWORD_TOO_SHORT") {
4101
- return sendErr(res, policyErr, [String(_chunkGXOFLFFWcjs.getPasswordPolicy.call(void 0, $asai).minLength)], opt);
4286
+ return sendErr(res, policyErr, [String(_chunkFRPN33BYcjs.getPasswordPolicy.call(void 0, $asai).minLength)], opt);
4102
4287
  }
4103
4288
  if (policyErr) return sendErr(res, policyErr, void 0, opt);
4104
- const { passHash, passSalt } = _chunkWXW5DYNUcjs.hashPassword.call(void 0, pass);
4289
+ const { passHash, passSalt } = _chunkH2QP5J7Xcjs.hashPassword.call(void 0, pass);
4105
4290
  const user = await store.createUser({
4106
4291
  us,
4107
4292
  email,
@@ -4114,11 +4299,11 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4114
4299
  logSecurityEvent($asai, { type: "AUTH_SUCCESS", path: url, method: "POST", user: us, ip, detail: "register_ok" });
4115
4300
  return sendSuccess(res, { user: publicUser($asai, user) }, opt);
4116
4301
  } catch (err) {
4117
- const msg = _optionalChain([err, 'optionalAccess', _508 => _508.message]) || String(err);
4302
+ const msg = _optionalChain([err, 'optionalAccess', _534 => _534.message]) || String(err);
4118
4303
  if (msg.includes("exists") || msg.includes("\u5DF2\u5B58\u5728")) {
4119
4304
  return sendErr(res, "USER_ALREADY_EXISTS", void 0, opt);
4120
4305
  }
4121
- return sendFail(res, _optionalChain([err, 'optionalAccess', _509 => _509.message]) || err, opt);
4306
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _535 => _535.message]) || err, opt);
4122
4307
  }
4123
4308
  }
4124
4309
  if (url.startsWith("/api/user/login/auth/")) {
@@ -4128,7 +4313,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4128
4313
  const pass = sanitizeString(pickAuthField(body, "pass", "password", "pwd"), 128);
4129
4314
  if (!us || !pass) return sendErr(res, "AUTH_CREDENTIALS_REQUIRED", void 0, opt);
4130
4315
  const user = await store.findByUsername(us);
4131
- if (!user || !_chunkWXW5DYNUcjs.verifyPassword.call(void 0, pass, user.passHash, user.passSalt)) {
4316
+ if (!user || !_chunkH2QP5J7Xcjs.verifyPassword.call(void 0, pass, user.passHash, user.passSalt)) {
4132
4317
  if (user) {
4133
4318
  const sec = getSecurity($asai);
4134
4319
  const lockoutMax = _nullishCoalesce(sec.lockoutMaxFails, () => ( 5));
@@ -4150,11 +4335,14 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4150
4335
  if (user.status === "locked" && user.lockedUntil && user.lockedUntil > Date.now()) {
4151
4336
  return sendErr(res, "AUTH_ACCOUNT_LOCKED", void 0, opt);
4152
4337
  }
4153
- const policy = _chunkGXOFLFFWcjs.getPasswordPolicy.call(void 0, $asai);
4154
- const mustChange = !!user.mustChangePassword || _chunkGXOFLFFWcjs.isPasswordExpired.call(void 0, user.passwordChangedAt, policy.maxAgeDays);
4155
- const hostcfg = _optionalChain([$asai, 'access', _510 => _510.getHost, 'optionalCall', _511 => _511(hostdir)]) || {};
4156
- if (hostcfg.ckws && isUserOnlineOnWs($asai, us, hostdir)) {
4157
- kickUserWs($asai, us, hostdir);
4338
+ const policy = _chunkFRPN33BYcjs.getPasswordPolicy.call(void 0, $asai);
4339
+ const mustChange = !!user.mustChangePassword || _chunkFRPN33BYcjs.isPasswordExpired.call(void 0, user.passwordChangedAt, policy.maxAgeDays);
4340
+ const hostcfg = _optionalChain([$asai, 'access', _536 => _536.getHost, 'optionalCall', _537 => _537(hostdir)]) || {};
4341
+ if (hostcfg.ckws) {
4342
+ const existingWs = _optionalChain([$asai, 'access', _538 => _538.connectionsws, 'optionalAccess', _539 => _539[hostdir], 'optionalAccess', _540 => _540[us]]);
4343
+ if (existingWs) {
4344
+ await clearStaleWsIfDead($asai, hostdir, us, existingWs);
4345
+ }
4158
4346
  }
4159
4347
  const quotaCheck = await canLogin($asai, us, hostdir);
4160
4348
  if (!quotaCheck.ok) {
@@ -4177,13 +4365,13 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4177
4365
  opt
4178
4366
  );
4179
4367
  } catch (err) {
4180
- return sendFail(res, _optionalChain([err, 'optionalAccess', _512 => _512.message]) || err, opt);
4368
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _541 => _541.message]) || err, opt);
4181
4369
  }
4182
4370
  }
4183
4371
  if (url.startsWith("/api/user/login/logout/")) {
4184
4372
  try {
4185
4373
  const bodySid = body.sessionId ? sanitizeString(body.sessionId, 64) : "";
4186
- const us = _optionalChain([req, 'optionalAccess', _513 => _513.Userinfo, 'optionalAccess', _514 => _514[0]]);
4374
+ const us = _optionalChain([req, 'optionalAccess', _542 => _542.Userinfo, 'optionalAccess', _543 => _543[0]]);
4187
4375
  if (bodySid) {
4188
4376
  if (!us) {
4189
4377
  return sendErr(res, "AUTH_MISSING", void 0, opt);
@@ -4197,11 +4385,61 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4197
4385
  if (us) logSecurityEvent($asai, { type: "AUTH_SUCCESS", path: url, method: "POST", user: String(us), ip, detail: "logout" });
4198
4386
  return sendSuccess(res, "ok", opt);
4199
4387
  } catch (err) {
4200
- return sendFail(res, _optionalChain([err, 'optionalAccess', _515 => _515.message]) || err, opt);
4388
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _544 => _544.message]) || err, opt);
4389
+ }
4390
+ }
4391
+ if (url.startsWith("/api/user/login/force/")) {
4392
+ try {
4393
+ const us = sanitizeString(String(_optionalChain([req, 'optionalAccess', _545 => _545.Userinfo, 'optionalAccess', _546 => _546[0]]) || ""), 64);
4394
+ if (!us) return sendErr(res, "AUTH_MISSING", void 0, opt);
4395
+ const myLv = Number(_nullishCoalesce(_optionalChain([req, 'optionalAccess', _547 => _547.Userinfo, 'optionalAccess', _548 => _548[1]]), () => ( 0)));
4396
+ const targetUs = sanitizeString(String(_optionalChain([body, 'optionalAccess', _549 => _549.targetUs]) || _optionalChain([body, 'optionalAccess', _550 => _550.us]) || ""), 64);
4397
+ const kicked = [];
4398
+ if (isUserOnlineOnWs($asai, us, hostdir)) {
4399
+ await kickUserWs($asai, us, hostdir);
4400
+ kicked.push(us);
4401
+ }
4402
+ const onlineRaw = listOnlineWsEntries($asai, hostdir).filter((e) => e.us !== us);
4403
+ const online = await Promise.all(
4404
+ onlineRaw.map(async (e) => ({
4405
+ us: e.us,
4406
+ lv: await resolveUserLv($asai, store, e.us, e.lv)
4407
+ }))
4408
+ );
4409
+ const candidates = targetUs ? online.filter((e) => e.us === targetUs) : online;
4410
+ for (const entry of candidates) {
4411
+ const entryLv = entry.lv == null ? NaN : Number(entry.lv);
4412
+ if (!Number.isFinite(entryLv) || myLv < entryLv) {
4413
+ if (targetUs) {
4414
+ return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4415
+ }
4416
+ continue;
4417
+ }
4418
+ await kickUserWs($asai, entry.us, hostdir);
4419
+ kicked.push(entry.us);
4420
+ }
4421
+ if (!kicked.length && online.length) {
4422
+ return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4423
+ }
4424
+ logSecurityEvent($asai, {
4425
+ type: "AUTH_SUCCESS",
4426
+ path: url,
4427
+ method: "POST",
4428
+ user: us,
4429
+ ip,
4430
+ detail: `force_login_kick:${kicked.join(",") || "none"}`
4431
+ });
4432
+ return sendSuccess(
4433
+ res,
4434
+ { ok: true, us, kicked, online: listOnlineWsEntries($asai, hostdir) },
4435
+ opt
4436
+ );
4437
+ } catch (err) {
4438
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _551 => _551.message]) || err, opt);
4201
4439
  }
4202
4440
  }
4203
4441
  if (url.startsWith("/api/user/login/admin/kick/")) {
4204
- if (!await checkAdmin(req, url, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4442
+ if (!await checkAdmin(req, url, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4205
4443
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4206
4444
  }
4207
4445
  try {
@@ -4213,9 +4451,9 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4213
4451
  if (!isSessionUserOnline($asai, target.us, hostdir)) {
4214
4452
  return sendErr(res, "SESSION_NOT_ONLINE", void 0, opt);
4215
4453
  }
4216
- kickUserWs($asai, target.us, hostdir);
4454
+ await kickUserWs($asai, target.us, hostdir);
4217
4455
  await store.removeSession(sessionId);
4218
- const operator = String(_optionalChain([req, 'optionalAccess', _516 => _516.Userinfo, 'optionalAccess', _517 => _517[0]]) || "");
4456
+ const operator = String(_optionalChain([req, 'optionalAccess', _552 => _552.Userinfo, 'optionalAccess', _553 => _553[0]]) || "");
4219
4457
  await _chunkARHPHWT5cjs.logSessionTerminate.call(void 0, $asai, {
4220
4458
  operator,
4221
4459
  sessionId,
@@ -4224,11 +4462,11 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4224
4462
  });
4225
4463
  return sendSuccess(res, { ok: true }, opt);
4226
4464
  } catch (err) {
4227
- return sendFail(res, _optionalChain([err, 'optionalAccess', _518 => _518.message]) || err, opt);
4465
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _554 => _554.message]) || err, opt);
4228
4466
  }
4229
4467
  }
4230
4468
  if (url.startsWith("/api/user/login/admin/delete/")) {
4231
- if (!await checkAdmin(req, url, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4469
+ if (!await checkAdmin(req, url, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4232
4470
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4233
4471
  }
4234
4472
  try {
@@ -4236,15 +4474,15 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4236
4474
  if (!targetUs || targetUs === "admin") return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4237
4475
  const ok = await store.deleteUser(targetUs);
4238
4476
  if (!ok) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4239
- const operator = String(_optionalChain([req, 'optionalAccess', _519 => _519.Userinfo, 'optionalAccess', _520 => _520[0]]) || "");
4477
+ const operator = String(_optionalChain([req, 'optionalAccess', _555 => _555.Userinfo, 'optionalAccess', _556 => _556[0]]) || "");
4240
4478
  await _chunkARHPHWT5cjs.logAccountPurge.call(void 0, $asai, { operator, targetUs, ip });
4241
4479
  return sendSuccess(res, { ok: true }, opt);
4242
4480
  } catch (err) {
4243
- return sendFail(res, _optionalChain([err, 'optionalAccess', _521 => _521.message]) || err, opt);
4481
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _557 => _557.message]) || err, opt);
4244
4482
  }
4245
4483
  }
4246
4484
  if (url.startsWith("/api/user/login/admin/levels/")) {
4247
- if (!await checkAdmin(req, url, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4485
+ if (!await checkAdmin(req, url, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4248
4486
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4249
4487
  }
4250
4488
  try {
@@ -4252,8 +4490,8 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4252
4490
  const thresholds = body.thresholds && typeof body.thresholds === "object" ? body.thresholds : void 0;
4253
4491
  const routeRights = Array.isArray(body.routeRights) ? body.routeRights : void 0;
4254
4492
  const defaultResetPassword = typeof body.defaultResetPassword === "string" ? body.defaultResetPassword : void 0;
4255
- const operator = String(_optionalChain([req, 'optionalAccess', _522 => _522.Userinfo, 'optionalAccess', _523 => _523[0]]) || "");
4256
- const cfg = await _chunkGXOFLFFWcjs.saveUserLevelConfig.call(void 0,
4493
+ const operator = String(_optionalChain([req, 'optionalAccess', _558 => _558.Userinfo, 'optionalAccess', _559 => _559[0]]) || "");
4494
+ const cfg = await _chunkFRPN33BYcjs.saveUserLevelConfig.call(void 0,
4257
4495
  $asai,
4258
4496
  {
4259
4497
  levels,
@@ -4265,18 +4503,18 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4265
4503
  );
4266
4504
  await _chunkARHPHWT5cjs.logSecurityConfigIntervention.call(void 0, $asai, {
4267
4505
  section: "user_levels",
4268
- detail: JSON.stringify({ levels: _optionalChain([levels, 'optionalAccess', _524 => _524.length]), thresholds: !!thresholds, routeRights: _optionalChain([routeRights, 'optionalAccess', _525 => _525.length]) }),
4506
+ detail: JSON.stringify({ levels: _optionalChain([levels, 'optionalAccess', _560 => _560.length]), thresholds: !!thresholds, routeRights: _optionalChain([routeRights, 'optionalAccess', _561 => _561.length]) }),
4269
4507
  operator,
4270
4508
  ip
4271
4509
  });
4272
4510
  return sendSuccess(res, cfg, opt);
4273
4511
  } catch (err) {
4274
- return sendFail(res, _optionalChain([err, 'optionalAccess', _526 => _526.message]) || err, opt);
4512
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _562 => _562.message]) || err, opt);
4275
4513
  }
4276
4514
  }
4277
4515
  if (url.startsWith("/api/user/login/admin/resetpass/")) {
4278
4516
  await ensureReady($asai);
4279
- if (!await checkAdmin(req, url, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4517
+ if (!await checkAdmin(req, url, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminWrite"))) {
4280
4518
  logSecurityEvent($asai, { type: "ACCESS_DENIED", path: url, method: "POST", ip });
4281
4519
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4282
4520
  }
@@ -4284,16 +4522,16 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4284
4522
  const targetUs = sanitizeString(body.us, 64);
4285
4523
  if (!targetUs) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4286
4524
  let newPass = sanitizeString(pickAuthField(body, "newPass", "newPassword", "newpass"), 128);
4287
- if (!newPass) newPass = _chunkGXOFLFFWcjs.getDefaultResetPassword.call(void 0, $asai);
4288
- const policy = _chunkGXOFLFFWcjs.getPasswordPolicy.call(void 0, $asai);
4289
- const policyErr = _chunkGXOFLFFWcjs.validatePasswordWithPolicy.call(void 0, newPass, policy);
4525
+ if (!newPass) newPass = _chunkFRPN33BYcjs.getDefaultResetPassword.call(void 0, $asai);
4526
+ const policy = _chunkFRPN33BYcjs.getPasswordPolicy.call(void 0, $asai);
4527
+ const policyErr = _chunkFRPN33BYcjs.validatePasswordWithPolicy.call(void 0, newPass, policy);
4290
4528
  if (policyErr === "PASSWORD_TOO_SHORT") {
4291
4529
  return sendErr(res, policyErr, [String(policy.minLength)], opt);
4292
4530
  }
4293
4531
  if (policyErr) return sendErr(res, policyErr, void 0, opt);
4294
4532
  const user = await store.findByUsername(targetUs);
4295
4533
  if (!user) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4296
- const { passHash, passSalt } = _chunkWXW5DYNUcjs.hashPassword.call(void 0, newPass);
4534
+ const { passHash, passSalt } = _chunkH2QP5J7Xcjs.hashPassword.call(void 0, newPass);
4297
4535
  const updated = await store.updateUser(targetUs, {
4298
4536
  passHash,
4299
4537
  passSalt,
@@ -4305,7 +4543,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4305
4543
  passHistory: "[]"
4306
4544
  });
4307
4545
  if (!updated) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4308
- const operator = String(_optionalChain([req, 'optionalAccess', _527 => _527.Userinfo, 'optionalAccess', _528 => _528[0]]) || "");
4546
+ const operator = String(_optionalChain([req, 'optionalAccess', _563 => _563.Userinfo, 'optionalAccess', _564 => _564[0]]) || "");
4309
4547
  await _chunkARHPHWT5cjs.logUserRbacChange.call(void 0, $asai, {
4310
4548
  operator,
4311
4549
  targetUs,
@@ -4322,7 +4560,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4322
4560
  });
4323
4561
  return sendSuccess(res, { user: publicUser($asai, updated) }, opt);
4324
4562
  } catch (err) {
4325
- return sendFail(res, _optionalChain([err, 'optionalAccess', _529 => _529.message]) || err, opt);
4563
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _565 => _565.message]) || err, opt);
4326
4564
  }
4327
4565
  }
4328
4566
  if (url.startsWith("/api/user/login/admin/update/")) {
@@ -4336,11 +4574,11 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4336
4574
  const patch = {};
4337
4575
  if (body.lv != null) {
4338
4576
  const newLv = Number(body.lv);
4339
- if (!Number.isFinite(newLv) || !_chunkGXOFLFFWcjs.isValidUserLv.call(void 0, $asai, newLv)) {
4577
+ if (!Number.isFinite(newLv) || !_chunkFRPN33BYcjs.isValidUserLv.call(void 0, $asai, newLv)) {
4340
4578
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4341
4579
  }
4342
4580
  patch.lv = newLv;
4343
- patch.role = _chunkGXOFLFFWcjs.resolveRoleForLevel.call(void 0, $asai, newLv).name;
4581
+ patch.role = _chunkFRPN33BYcjs.resolveRoleForLevel.call(void 0, $asai, newLv).name;
4344
4582
  }
4345
4583
  if (body.status) patch.status = sanitizeString(body.status, 16);
4346
4584
  if (body.resetLock) {
@@ -4353,7 +4591,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4353
4591
  if (!updated) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4354
4592
  if (Object.keys(patch).length) {
4355
4593
  await _chunkARHPHWT5cjs.logUserRbacChange.call(void 0, $asai, {
4356
- operator: String(_optionalChain([req, 'optionalAccess', _530 => _530.Userinfo, 'optionalAccess', _531 => _531[0]]) || ""),
4594
+ operator: String(_optionalChain([req, 'optionalAccess', _566 => _566.Userinfo, 'optionalAccess', _567 => _567[0]]) || ""),
4357
4595
  targetUs,
4358
4596
  patch,
4359
4597
  ip
@@ -4361,33 +4599,33 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4361
4599
  }
4362
4600
  return sendSuccess(res, { user: publicUser($asai, updated) }, opt);
4363
4601
  } catch (err) {
4364
- return sendFail(res, _optionalChain([err, 'optionalAccess', _532 => _532.message]) || err, opt);
4602
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _568 => _568.message]) || err, opt);
4365
4603
  }
4366
4604
  }
4367
4605
  if (url.startsWith("/api/user/login/profile/")) {
4368
- const us = _optionalChain([req, 'optionalAccess', _533 => _533.Userinfo, 'optionalAccess', _534 => _534[0]]);
4606
+ const us = _optionalChain([req, 'optionalAccess', _569 => _569.Userinfo, 'optionalAccess', _570 => _570[0]]);
4369
4607
  if (!us) return sendErr(res, "AUTH_UNAUTHORIZED", void 0, opt);
4370
4608
  try {
4371
4609
  const user = await store.findByUsername(String(us));
4372
4610
  if (!user) return sendErr(res, "AUTH_USER_NOT_FOUND", void 0, opt);
4373
4611
  if (pickAuthField(body, "newPass", "newPassword", "newpass")) {
4374
4612
  const newPass = sanitizeString(pickAuthField(body, "newPass", "newPassword", "newpass"), 128);
4375
- const policy = _chunkGXOFLFFWcjs.getPasswordPolicy.call(void 0, $asai);
4613
+ const policy = _chunkFRPN33BYcjs.getPasswordPolicy.call(void 0, $asai);
4376
4614
  const oldPass = pickAuthField(body, "pass", "password", "pwd");
4377
4615
  if (oldPass) {
4378
- if (!_chunkWXW5DYNUcjs.verifyPassword.call(void 0, oldPass, user.passHash, user.passSalt)) {
4616
+ if (!_chunkH2QP5J7Xcjs.verifyPassword.call(void 0, oldPass, user.passHash, user.passSalt)) {
4379
4617
  return sendErr(res, "AUTH_INVALID_PASSWORD", void 0, opt);
4380
4618
  }
4381
4619
  } else if (!user.mustChangePassword) {
4382
4620
  return sendErr(res, "AUTH_INVALID_PASSWORD", void 0, opt);
4383
4621
  }
4384
- const policyErr = _chunkWXW5DYNUcjs.validatePasswordChange.call(void 0, newPass, $asai, user.passHistory);
4622
+ const policyErr = _chunkH2QP5J7Xcjs.validatePasswordChange.call(void 0, newPass, $asai, user.passHistory);
4385
4623
  if (policyErr === "PASSWORD_TOO_SHORT") {
4386
4624
  return sendErr(res, policyErr, [String(policy.minLength)], opt);
4387
4625
  }
4388
4626
  if (policyErr) return sendErr(res, policyErr, void 0, opt);
4389
- const { passHash, passSalt } = _chunkWXW5DYNUcjs.hashPassword.call(void 0, newPass);
4390
- const passHistory = _chunkWXW5DYNUcjs.nextPassHistory.call(void 0, oldPass || newPass, user.passHistory, policy.historyCount);
4627
+ const { passHash, passSalt } = _chunkH2QP5J7Xcjs.hashPassword.call(void 0, newPass);
4628
+ const passHistory = _chunkH2QP5J7Xcjs.nextPassHistory.call(void 0, oldPass || newPass, user.passHistory, policy.historyCount);
4391
4629
  await store.updateUser(String(us), {
4392
4630
  passHash,
4393
4631
  passSalt,
@@ -4399,7 +4637,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4399
4637
  const fresh = await store.findByUsername(String(us));
4400
4638
  return sendSuccess(res, { user: fresh ? publicUser($asai, fresh) : null }, opt);
4401
4639
  } catch (err) {
4402
- return sendFail(res, _optionalChain([err, 'optionalAccess', _535 => _535.message]) || err, opt);
4640
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _571 => _571.message]) || err, opt);
4403
4641
  }
4404
4642
  }
4405
4643
  }
@@ -4408,16 +4646,49 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4408
4646
  const url = req.url || "";
4409
4647
  const ip = getClientIp(req);
4410
4648
  if (url.startsWith("/api/user/login/config/")) {
4411
- const lang = String(_optionalChain([req, 'optionalAccess', _536 => _536.headers, 'optionalAccess', _537 => _537["accept-language"]]) || _optionalChain([opt, 'optionalAccess', _538 => _538.headers, 'optionalAccess', _539 => _539["accept-language"]]) || "zh-CN").split(",")[0];
4412
- await _chunkGXOFLFFWcjs.loadUserLevelConfig.call(void 0, $asai);
4413
- return sendSuccess(res, _chunkGXOFLFFWcjs.getPublicSecurityConfig.call(void 0, $asai, lang), opt);
4649
+ const lang = String(_optionalChain([req, 'optionalAccess', _572 => _572.headers, 'optionalAccess', _573 => _573["accept-language"]]) || _optionalChain([opt, 'optionalAccess', _574 => _574.headers, 'optionalAccess', _575 => _575["accept-language"]]) || "zh-CN").split(",")[0];
4650
+ await _chunkFRPN33BYcjs.loadUserLevelConfig.call(void 0, $asai);
4651
+ return sendSuccess(res, _chunkFRPN33BYcjs.getPublicSecurityConfig.call(void 0, $asai, lang), opt);
4652
+ }
4653
+ if (url.startsWith("/api/user/login/online/")) {
4654
+ try {
4655
+ const us = sanitizeString(String(_optionalChain([req, 'optionalAccess', _576 => _576.Userinfo, 'optionalAccess', _577 => _577[0]]) || ""), 64);
4656
+ if (!us) return sendErr(res, "AUTH_MISSING", void 0, opt);
4657
+ const rawOnline = listOnlineWsEntries($asai, hostdir);
4658
+ const online = await Promise.all(
4659
+ rawOnline.map(async (e) => ({
4660
+ us: e.us,
4661
+ lv: await resolveUserLv($asai, store, e.us, e.lv)
4662
+ }))
4663
+ );
4664
+ const rawMy = _optionalChain([req, 'optionalAccess', _578 => _578.Userinfo, 'optionalAccess', _579 => _579[1]]);
4665
+ const wsMyLv = rawMy === null || rawMy === void 0 || rawMy === "" ? null : Number(rawMy);
4666
+ const myLvOut = await resolveUserLv(
4667
+ $asai,
4668
+ store,
4669
+ us,
4670
+ Number.isFinite(wsMyLv) ? wsMyLv : null
4671
+ );
4672
+ return sendSuccess(
4673
+ res,
4674
+ {
4675
+ us,
4676
+ lv: myLvOut,
4677
+ online,
4678
+ maxonline: _nullishCoalesce(_optionalChain([$asai, 'access', _580 => _580.getHost, 'optionalCall', _581 => _581(hostdir), 'optionalAccess', _582 => _582.maxonline]), () => ( 100))
4679
+ },
4680
+ opt
4681
+ );
4682
+ } catch (err) {
4683
+ return sendFail(res, _optionalChain([err, 'optionalAccess', _583 => _583.message]) || err, opt);
4684
+ }
4414
4685
  }
4415
4686
  if (url.startsWith("/api/user/login/admin/levels/")) {
4416
- if (!await checkAdmin(req, url, _chunkGXOFLFFWcjs.getPermissionThreshold.call(void 0, $asai, "adminRead"))) {
4687
+ if (!await checkAdmin(req, url, _chunkFRPN33BYcjs.getPermissionThreshold.call(void 0, $asai, "adminRead"))) {
4417
4688
  return sendErr(res, "AUTH_FORBIDDEN", void 0, opt);
4418
4689
  }
4419
- await _chunkGXOFLFFWcjs.loadUserLevelConfig.call(void 0, $asai);
4420
- return sendSuccess(res, _chunkGXOFLFFWcjs.getUserLevelConfigSync.call(void 0, $asai), opt);
4690
+ await _chunkFRPN33BYcjs.loadUserLevelConfig.call(void 0, $asai);
4691
+ return sendSuccess(res, _chunkFRPN33BYcjs.getUserLevelConfigSync.call(void 0, $asai), opt);
4421
4692
  }
4422
4693
  if (url.startsWith("/api/user/login/admin/sessions/")) {
4423
4694
  if (!await checkAdmin(req, url)) {
@@ -4469,7 +4740,7 @@ var login_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4469
4740
  );
4470
4741
  }
4471
4742
  if (url.startsWith("/api/user/login/profile/")) {
4472
- const us = _optionalChain([req, 'optionalAccess', _540 => _540.Userinfo, 'optionalAccess', _541 => _541[0]]);
4743
+ const us = _optionalChain([req, 'optionalAccess', _584 => _584.Userinfo, 'optionalAccess', _585 => _585[0]]);
4473
4744
  if (!us) return sendErr(res, "AUTH_UNAUTHORIZED", void 0, opt);
4474
4745
  const user = await store.findByUsername(String(us));
4475
4746
  return sendSuccess(res, { user: user ? publicUser($asai, user) : null }, opt);
@@ -4511,16 +4782,16 @@ var As_default = {
4511
4782
  return { code: 908, data: val };
4512
4783
  },
4513
4784
  ctxSuccess(val, opt = null) {
4514
- if (typeof _optionalChain([opt, 'optionalAccess', _542 => _542.resAES]) === "function") {
4785
+ if (typeof _optionalChain([opt, 'optionalAccess', _586 => _586.resAES]) === "function") {
4515
4786
  val = opt.resAES(val);
4516
4787
  }
4517
4788
  return { code: 909, data: val };
4518
4789
  },
4519
4790
  getPath(str = "-") {
4520
- return _optionalChain([str, 'optionalAccess', _543 => _543.replace, 'call', _544 => _544(/[^a-zA-Z0-9.\-_\\\/]/g, "")]);
4791
+ return _optionalChain([str, 'optionalAccess', _587 => _587.replace, 'call', _588 => _588(/[^a-zA-Z0-9.\-_\\\/]/g, "")]);
4521
4792
  },
4522
4793
  getName(str = "-") {
4523
- return _optionalChain([str, 'optionalAccess', _545 => _545.replace, 'call', _546 => _546(/[^a-zA-Z0-9.\-_]/g, "")]);
4794
+ return _optionalChain([str, 'optionalAccess', _589 => _589.replace, 'call', _590 => _590(/[^a-zA-Z0-9.\-_]/g, "")]);
4524
4795
  },
4525
4796
  toDirPath(relativePath) {
4526
4797
  const pathArr = relativePath.split("/");
@@ -4534,10 +4805,10 @@ var As_default = {
4534
4805
  return relativePath;
4535
4806
  },
4536
4807
  //创建多层文件夹 同步
4537
- ensureDir(fs11, relativePath) {
4808
+ ensureDir(fs12, relativePath) {
4538
4809
  const absPathDir = this.toDirPath(relativePath);
4539
4810
  const absPath = this.toAbsolutePath(relativePath);
4540
- if (!fs11.existsSync(absPath)) {
4811
+ if (!fs12.existsSync(absPath)) {
4541
4812
  let pathTmp = "";
4542
4813
  absPathDir.split("/").forEach((el) => {
4543
4814
  if (el) {
@@ -4545,8 +4816,8 @@ var As_default = {
4545
4816
  pathTmp += "/";
4546
4817
  }
4547
4818
  pathTmp += el;
4548
- if (!fs11.existsSync(pathTmp)) {
4549
- if (!fs11.mkdirSync(pathTmp, { recursive: true })) {
4819
+ if (!fs12.existsSync(pathTmp)) {
4820
+ if (!fs12.mkdirSync(pathTmp, { recursive: true })) {
4550
4821
  return absPath;
4551
4822
  }
4552
4823
  }
@@ -4555,10 +4826,10 @@ var As_default = {
4555
4826
  }
4556
4827
  return absPath;
4557
4828
  },
4558
- makeDir(fs11, filePaths) {
4829
+ makeDir(fs12, filePaths) {
4559
4830
  return new Promise((resolve6, reject) => {
4560
4831
  try {
4561
- const newPath = this.ensureDir(fs11, filePaths);
4832
+ const newPath = this.ensureDir(fs12, filePaths);
4562
4833
  resolve6(newPath);
4563
4834
  } catch (err) {
4564
4835
  reject(err);
@@ -4591,7 +4862,7 @@ var As_default = {
4591
4862
  // immediate: false,
4592
4863
  // });
4593
4864
  dtImmediate(fn, opt) {
4594
- if (_optionalChain([opt, 'optionalAccess', _547 => _547.immediate])) {
4865
+ if (_optionalChain([opt, 'optionalAccess', _591 => _591.immediate])) {
4595
4866
  fn();
4596
4867
  opt.immediate = false;
4597
4868
  }
@@ -4613,7 +4884,7 @@ var As_default = {
4613
4884
  if (opt.endtime - opt.starttime < opt.wait) {
4614
4885
  this.dtClearTimeout(opt);
4615
4886
  }
4616
- if (!_optionalChain([opt, 'optionalAccess', _548 => _548.timeout])) {
4887
+ if (!_optionalChain([opt, 'optionalAccess', _592 => _592.timeout])) {
4617
4888
  opt.starttime = opt.endtime;
4618
4889
  opt.timeout = this.dtSetTimeout(fn, opt);
4619
4890
  }
@@ -4621,7 +4892,7 @@ var As_default = {
4621
4892
  // 节流:指定长度时间内有多次触发,只fn最后一次触发
4622
4893
  throttle(fn, opt) {
4623
4894
  this.dtImmediate(fn, opt);
4624
- if (!_optionalChain([opt, 'optionalAccess', _549 => _549.timeout])) {
4895
+ if (!_optionalChain([opt, 'optionalAccess', _593 => _593.timeout])) {
4625
4896
  opt.timeout = this.dtSetTimeout(fn, opt);
4626
4897
  }
4627
4898
  },
@@ -4657,8 +4928,8 @@ var As_default = {
4657
4928
  var AsCode_default = {
4658
4929
  // 加密
4659
4930
  asencode(str, keys) {
4660
- const strlen = _optionalChain([str, 'optionalAccess', _550 => _550.length]) || 0;
4661
- const keyslen = _optionalChain([keys, 'optionalAccess', _551 => _551.length]) || 0;
4931
+ const strlen = _optionalChain([str, 'optionalAccess', _594 => _594.length]) || 0;
4932
+ const keyslen = _optionalChain([keys, 'optionalAccess', _595 => _595.length]) || 0;
4662
4933
  let newstr = "";
4663
4934
  for (let i = 0; i < strlen; i++) {
4664
4935
  const rnum = Math.round(Math.random() * 1e3) % keyslen;
@@ -4683,7 +4954,7 @@ var AsCode_default = {
4683
4954
  const rnum = keys.indexOf(str[i + 3]);
4684
4955
  const rnumx = Number(rnum.toString().slice(-1)) + 1;
4685
4956
  const ylen = keyslen - rnumx;
4686
- newstr += _optionalChain([String, 'optionalAccess', _552 => _552.fromCodePoint, 'call', _553 => _553(
4957
+ newstr += _optionalChain([String, 'optionalAccess', _596 => _596.fromCodePoint, 'call', _597 => _597(
4687
4958
  (keys.indexOf(str[i++]) - rnumx) * ylen * ylen + (keys.indexOf(str[i++]) - rnumx) * ylen + (keys.indexOf(str[i++]) - rnumx)
4688
4959
  )]);
4689
4960
  }
@@ -4730,7 +5001,7 @@ var AsAES_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4730
5001
  if (typeof value !== "string") return value;
4731
5002
  try {
4732
5003
  return JSON.parse(value);
4733
- } catch (e40) {
5004
+ } catch (e51) {
4734
5005
  return value;
4735
5006
  }
4736
5007
  }
@@ -4766,7 +5037,7 @@ var AsAES_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4766
5037
  }
4767
5038
  _chunkSMVZ3ZDJcjs.__name.call(void 0, decrypt, "decrypt");
4768
5039
  function validateFields(payload, fields) {
4769
- return fields.every((key) => typeof _optionalChain([payload, 'optionalAccess', _554 => _554[key]]) === "string" && payload[key].length > 0);
5040
+ return fields.every((key) => typeof _optionalChain([payload, 'optionalAccess', _598 => _598[key]]) === "string" && payload[key].length > 0);
4770
5041
  }
4771
5042
  _chunkSMVZ3ZDJcjs.__name.call(void 0, validateFields, "validateFields");
4772
5043
  function reqAES(opt, fn = (data) => data) {
@@ -4774,7 +5045,7 @@ var AsAES_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4774
5045
  try {
4775
5046
  if (validateFields(reqData, ["data", "iv", "auth"])) {
4776
5047
  let aesData = decrypt(reqData);
4777
- if (_optionalChain([reqData, 'optionalAccess', _555 => _555.aes]) === 2) {
5048
+ if (_optionalChain([reqData, 'optionalAccess', _599 => _599.aes]) === 2) {
4778
5049
  aesData = JSON.parse(aesData);
4779
5050
  }
4780
5051
  return fn(aesData);
@@ -4808,24 +5079,24 @@ var AsAES_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai
4808
5079
  // src/sysserver/lib/common/AsDb.ts
4809
5080
  var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai, cfg) => {
4810
5081
  const DataServer = _chunk2BCIIKRGcjs.getDataServerForAsDb.call(void 0, $asai, {
4811
- type: _optionalChain([cfg, 'optionalAccess', _556 => _556.type]) || "sqlite",
5082
+ type: _optionalChain([cfg, 'optionalAccess', _600 => _600.type]) || "sqlite",
4812
5083
  opt: {
4813
- ..._optionalChain([cfg, 'optionalAccess', _557 => _557.opt]) || {
5084
+ ..._optionalChain([cfg, 'optionalAccess', _601 => _601.opt]) || {
4814
5085
  database: "./webdata/webdb/sqlite/asaisqlite.db",
4815
5086
  create: 1
4816
5087
  }
4817
5088
  },
4818
- storeKey: _optionalChain([cfg, 'optionalAccess', _558 => _558.storeKey])
5089
+ storeKey: _optionalChain([cfg, 'optionalAccess', _602 => _602.storeKey])
4819
5090
  });
4820
5091
  function reqwherestr(str) {
4821
- if (_optionalChain([cfg, 'optionalAccess', _559 => _559.type]) === "sqlite" || _optionalChain([cfg, 'optionalAccess', _560 => _560.type]) === "mysql") {
5092
+ if (_optionalChain([cfg, 'optionalAccess', _603 => _603.type]) === "sqlite" || _optionalChain([cfg, 'optionalAccess', _604 => _604.type]) === "mysql") {
4822
5093
  return `'${str}'`;
4823
5094
  }
4824
5095
  return str;
4825
5096
  }
4826
5097
  _chunkSMVZ3ZDJcjs.__name.call(void 0, reqwherestr, "reqwherestr");
4827
5098
  function reqfield(queryData) {
4828
- if (_optionalChain([queryData, 'optionalAccess', _561 => _561.fd])) {
5099
+ if (_optionalChain([queryData, 'optionalAccess', _605 => _605.fd])) {
4829
5100
  return queryData.fd.split("-");
4830
5101
  }
4831
5102
  return cfg.field.data;
@@ -4833,14 +5104,14 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4833
5104
  _chunkSMVZ3ZDJcjs.__name.call(void 0, reqfield, "reqfield");
4834
5105
  function reqwhere(queryData) {
4835
5106
  const wheretmp = [];
4836
- if ((_optionalChain([cfg, 'optionalAccess', _562 => _562.type]) === "sqlite" || _optionalChain([cfg, 'optionalAccess', _563 => _563.type]) === "mysql") && _optionalChain([queryData, 'optionalAccess', _564 => _564.wlv])) {
5107
+ if ((_optionalChain([cfg, 'optionalAccess', _606 => _606.type]) === "sqlite" || _optionalChain([cfg, 'optionalAccess', _607 => _607.type]) === "mysql") && _optionalChain([queryData, 'optionalAccess', _608 => _608.wlv])) {
4837
5108
  const wlvarr = queryData.wlv.split("-");
4838
5109
  wheretmp.push([wlvarr[0], ">", Number(wlvarr[1] || 0)]);
4839
5110
  }
4840
- if (_optionalChain([queryData, 'optionalAccess', _565 => _565.fl])) {
5111
+ if (_optionalChain([queryData, 'optionalAccess', _609 => _609.fl])) {
4841
5112
  wheretmp.push([cfg.field.class, "LIKE", reqwherestr(`${queryData.fl}%`)]);
4842
5113
  }
4843
- if (_optionalChain([queryData, 'optionalAccess', _566 => _566.ss]) && _optionalChain([queryData, 'optionalAccess', _567 => _567.ssty])) {
5114
+ if (_optionalChain([queryData, 'optionalAccess', _610 => _610.ss]) && _optionalChain([queryData, 'optionalAccess', _611 => _611.ssty])) {
4844
5115
  wheretmp.push([queryData.ssty, "LIKE", reqwherestr(`%${queryData.ss}%`)]);
4845
5116
  }
4846
5117
  if (wheretmp.length > 1) {
@@ -4851,16 +5122,16 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4851
5122
  _chunkSMVZ3ZDJcjs.__name.call(void 0, reqwhere, "reqwhere");
4852
5123
  function reqorder(queryData) {
4853
5124
  const ordertmp = [];
4854
- if (_optionalChain([queryData, 'optionalAccess', _568 => _568.sx])) {
4855
- ordertmp.push([queryData.sx, _optionalChain([queryData, 'optionalAccess', _569 => _569.sxty]) == 1 ? "DESC" : "ASC"]);
5125
+ if (_optionalChain([queryData, 'optionalAccess', _612 => _612.sx])) {
5126
+ ordertmp.push([queryData.sx, _optionalChain([queryData, 'optionalAccess', _613 => _613.sxty]) == 1 ? "DESC" : "ASC"]);
4856
5127
  }
4857
5128
  return ordertmp;
4858
5129
  }
4859
5130
  _chunkSMVZ3ZDJcjs.__name.call(void 0, reqorder, "reqorder");
4860
5131
  function reqlimit(queryData) {
4861
5132
  let limittmp = "";
4862
- let limitps = _optionalChain([queryData, 'optionalAccess', _570 => _570.ps]);
4863
- if (_optionalChain([queryData, 'optionalAccess', _571 => _571.pg])) {
5133
+ let limitps = _optionalChain([queryData, 'optionalAccess', _614 => _614.ps]);
5134
+ if (_optionalChain([queryData, 'optionalAccess', _615 => _615.pg])) {
4864
5135
  limitps = limitps || 20;
4865
5136
  limittmp = `${(queryData.pg - 1) * limitps},${limitps}`;
4866
5137
  } else if (limitps) {
@@ -4872,7 +5143,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4872
5143
  function decodePathSegment(seg) {
4873
5144
  try {
4874
5145
  return decodeURIComponent(seg);
4875
- } catch (e41) {
5146
+ } catch (e52) {
4876
5147
  return seg;
4877
5148
  }
4878
5149
  }
@@ -4888,7 +5159,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4888
5159
  if (typeof body === "string") {
4889
5160
  try {
4890
5161
  body = JSON.parse(body);
4891
- } catch (e42) {
5162
+ } catch (e53) {
4892
5163
  return { content: body };
4893
5164
  }
4894
5165
  }
@@ -4913,8 +5184,8 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4913
5184
  _chunkSMVZ3ZDJcjs.__name.call(void 0, fileKeyFromSegment, "fileKeyFromSegment");
4914
5185
  function getSqlParamsByUrl(req, opt) {
4915
5186
  let tmpSqlParams;
4916
- const reqArr = _optionalChain([req, 'optionalAccess', _572 => _572.url, 'optionalAccess', _573 => _573.split, 'call', _574 => _574("?"), 'access', _575 => _575[0], 'optionalAccess', _576 => _576.split, 'call', _577 => _577("/")]) || [];
4917
- const table = (_optionalChain([opt, 'optionalAccess', _578 => _578.qrdata, 'optionalAccess', _579 => _579.table]) || _optionalChain([opt, 'optionalAccess', _580 => _580.data, 'optionalAccess', _581 => _581.table]) || reqArr[3]).replaceAll("_", "/");
5187
+ const reqArr = _optionalChain([req, 'optionalAccess', _616 => _616.url, 'optionalAccess', _617 => _617.split, 'call', _618 => _618("?"), 'access', _619 => _619[0], 'optionalAccess', _620 => _620.split, 'call', _621 => _621("/")]) || [];
5188
+ const table = (_optionalChain([opt, 'optionalAccess', _622 => _622.qrdata, 'optionalAccess', _623 => _623.table]) || _optionalChain([opt, 'optionalAccess', _624 => _624.data, 'optionalAccess', _625 => _625.table]) || reqArr[3]).replaceAll("_", "/");
4918
5189
  if (!table) return tmpSqlParams;
4919
5190
  tmpSqlParams = {
4920
5191
  type: "select",
@@ -4923,7 +5194,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4923
5194
  if (reqArr[5]) {
4924
5195
  if (reqArr[4] === "insert") {
4925
5196
  tmpSqlParams.type = reqArr[4];
4926
- if (_optionalChain([cfg, 'optionalAccess', _582 => _582.type]) === "file") {
5197
+ if (_optionalChain([cfg, 'optionalAccess', _626 => _626.type]) === "file") {
4927
5198
  const { name: bodyName, content } = parseFileBody(opt.data);
4928
5199
  const fileKey = fileKeyFromSegment(reqArr[5], bodyName);
4929
5200
  tmpSqlParams.field = cfg.field.data;
@@ -4947,11 +5218,11 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4947
5218
  }
4948
5219
  } else if (reqArr[4] === "update") {
4949
5220
  tmpSqlParams.type = reqArr[4];
4950
- const rowKey = _optionalChain([cfg, 'optionalAccess', _583 => _583.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
5221
+ const rowKey = _optionalChain([cfg, 'optionalAccess', _627 => _627.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
4951
5222
  tmpSqlParams.where = [[cfg.field.key, "=", reqwherestr(rowKey)]];
4952
- if (_optionalChain([cfg, 'optionalAccess', _584 => _584.type]) === "file") {
5223
+ if (_optionalChain([cfg, 'optionalAccess', _628 => _628.type]) === "file") {
4953
5224
  const { content } = parseFileBody(opt.data);
4954
- const contentField = _optionalChain([cfg, 'access', _585 => _585.field, 'access', _586 => _586.data, 'optionalAccess', _587 => _587[1]]) || "content";
5225
+ const contentField = _optionalChain([cfg, 'access', _629 => _629.field, 'access', _630 => _630.data, 'optionalAccess', _631 => _631[1]]) || "content";
4955
5226
  tmpSqlParams.set = [[contentField, fileContentString(content)]];
4956
5227
  } else {
4957
5228
  tmpSqlParams.set = [];
@@ -4968,18 +5239,18 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4968
5239
  }
4969
5240
  } else if (reqArr[4] === "delete") {
4970
5241
  tmpSqlParams.type = reqArr[4];
4971
- const rowKey = _optionalChain([cfg, 'optionalAccess', _588 => _588.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
5242
+ const rowKey = _optionalChain([cfg, 'optionalAccess', _632 => _632.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
4972
5243
  tmpSqlParams.where = [[cfg.field.key, "=", reqwherestr(rowKey)]];
4973
5244
  } else {
4974
- if (_optionalChain([cfg, 'optionalAccess', _589 => _589.as]) > 1) {
5245
+ if (_optionalChain([cfg, 'optionalAccess', _633 => _633.as]) > 1) {
4975
5246
  tmpSqlParams.as = +cfg.as - 1;
4976
5247
  }
4977
5248
  tmpSqlParams.field = cfg.field.data;
4978
- const rowKey = _optionalChain([cfg, 'optionalAccess', _590 => _590.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
5249
+ const rowKey = _optionalChain([cfg, 'optionalAccess', _634 => _634.type]) === "file" ? fileKeyFromSegment(reqArr[5]) : decodePathSegment(reqArr[5]);
4979
5250
  tmpSqlParams.where = [[cfg.field.key, "=", reqwherestr(rowKey)]];
4980
5251
  }
4981
5252
  } else {
4982
- tmpSqlParams.as = _optionalChain([cfg, 'optionalAccess', _591 => _591.as]);
5253
+ tmpSqlParams.as = _optionalChain([cfg, 'optionalAccess', _635 => _635.as]);
4983
5254
  tmpSqlParams.field = reqfield(opt.data);
4984
5255
  tmpSqlParams.where = reqwhere(opt.data);
4985
5256
  tmpSqlParams.order = reqorder(opt.data);
@@ -4989,8 +5260,8 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
4989
5260
  }
4990
5261
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getSqlParamsByUrl, "getSqlParamsByUrl");
4991
5262
  function dbFresh(req, resdb) {
4992
- if (_optionalChain([req, 'optionalAccess', _592 => _592.url, 'optionalAccess', _593 => _593.includes, 'call', _594 => _594("/selectlist/")])) {
4993
- const list = Array.isArray(resdb) ? resdb : _optionalChain([resdb, 'optionalAccess', _595 => _595.data]);
5263
+ if (_optionalChain([req, 'optionalAccess', _636 => _636.url, 'optionalAccess', _637 => _637.includes, 'call', _638 => _638("/selectlist/")])) {
5264
+ const list = Array.isArray(resdb) ? resdb : _optionalChain([resdb, 'optionalAccess', _639 => _639.data]);
4994
5265
  if (Array.isArray(list)) {
4995
5266
  const names = list.map((el) => {
4996
5267
  if (typeof el === "string") {
@@ -5012,8 +5283,8 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5012
5283
  }
5013
5284
  _chunkSMVZ3ZDJcjs.__name.call(void 0, dbFresh, "dbFresh");
5014
5285
  function normalizeFileSelectRow(row) {
5015
- const nameKey = _optionalChain([cfg, 'access', _596 => _596.field, 'optionalAccess', _597 => _597.data, 'optionalAccess', _598 => _598[0]]) || "name";
5016
- const contentKey = _optionalChain([cfg, 'access', _599 => _599.field, 'optionalAccess', _600 => _600.data, 'optionalAccess', _601 => _601[1]]) || "content";
5286
+ const nameKey = _optionalChain([cfg, 'access', _640 => _640.field, 'optionalAccess', _641 => _641.data, 'optionalAccess', _642 => _642[0]]) || "name";
5287
+ const contentKey = _optionalChain([cfg, 'access', _643 => _643.field, 'optionalAccess', _644 => _644.data, 'optionalAccess', _645 => _645[1]]) || "content";
5017
5288
  if (!row || typeof row !== "object") return row;
5018
5289
  const out = { ...row };
5019
5290
  if (out[nameKey] != null) {
@@ -5027,7 +5298,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5027
5298
  }
5028
5299
  _chunkSMVZ3ZDJcjs.__name.call(void 0, normalizeFileSelectRow, "normalizeFileSelectRow");
5029
5300
  function isFileSingleNameSelect(params) {
5030
- return _optionalChain([cfg, 'optionalAccess', _602 => _602.type]) === "file" && _optionalChain([params, 'optionalAccess', _603 => _603.type]) === "select" && !!_optionalChain([params, 'optionalAccess', _604 => _604.where, 'optionalAccess', _605 => _605.length]);
5301
+ return _optionalChain([cfg, 'optionalAccess', _646 => _646.type]) === "file" && _optionalChain([params, 'optionalAccess', _647 => _647.type]) === "select" && !!_optionalChain([params, 'optionalAccess', _648 => _648.where, 'optionalAccess', _649 => _649.length]);
5031
5302
  }
5032
5303
  _chunkSMVZ3ZDJcjs.__name.call(void 0, isFileSingleNameSelect, "isFileSingleNameSelect");
5033
5304
  function normalizeSelectResult(params, resdb) {
@@ -5041,12 +5312,12 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5041
5312
  }
5042
5313
  return data;
5043
5314
  }
5044
- if (_optionalChain([params, 'optionalAccess', _606 => _606.where, 'optionalAccess', _607 => _607.length]) && Array.isArray(data) && data.length === 1) {
5315
+ if (_optionalChain([params, 'optionalAccess', _650 => _650.where, 'optionalAccess', _651 => _651.length]) && Array.isArray(data) && data.length === 1) {
5045
5316
  data = data[0];
5046
5317
  }
5047
- if (_optionalChain([cfg, 'optionalAccess', _608 => _608.type]) === "file" && data && typeof data === "object" && !Array.isArray(data)) {
5048
- const nameKey = _optionalChain([cfg, 'access', _609 => _609.field, 'optionalAccess', _610 => _610.data, 'optionalAccess', _611 => _611[0]]) || "name";
5049
- const contentKey = _optionalChain([cfg, 'access', _612 => _612.field, 'optionalAccess', _613 => _613.data, 'optionalAccess', _614 => _614[1]]) || "content";
5318
+ if (_optionalChain([cfg, 'optionalAccess', _652 => _652.type]) === "file" && data && typeof data === "object" && !Array.isArray(data)) {
5319
+ const nameKey = _optionalChain([cfg, 'access', _653 => _653.field, 'optionalAccess', _654 => _654.data, 'optionalAccess', _655 => _655[0]]) || "name";
5320
+ const contentKey = _optionalChain([cfg, 'access', _656 => _656.field, 'optionalAccess', _657 => _657.data, 'optionalAccess', _658 => _658[1]]) || "content";
5050
5321
  if (data[nameKey] != null) {
5051
5322
  data[nameKey] = bareFileName(String(data[nameKey]));
5052
5323
  }
@@ -5056,7 +5327,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5056
5327
  if (text.startsWith("{") || text.startsWith("[")) {
5057
5328
  try {
5058
5329
  data[contentKey] = JSON.parse(text);
5059
- } catch (e43) {
5330
+ } catch (e54) {
5060
5331
  }
5061
5332
  }
5062
5333
  }
@@ -5065,7 +5336,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5065
5336
  }
5066
5337
  _chunkSMVZ3ZDJcjs.__name.call(void 0, normalizeSelectResult, "normalizeSelectResult");
5067
5338
  function dbCodePm(req, resdb) {
5068
- if (_optionalChain([req, 'optionalAccess', _615 => _615.Userinfo]) && _optionalChain([req, 'optionalAccess', _616 => _616.Userinfo, 'access', _617 => _617[2]])) {
5339
+ if (_optionalChain([req, 'optionalAccess', _659 => _659.Userinfo]) && _optionalChain([req, 'optionalAccess', _660 => _660.Userinfo, 'access', _661 => _661[2]])) {
5069
5340
  if (resdb != null && typeof resdb === "object") {
5070
5341
  resdb.data = $asai.$lib.AsCode.asencode(JSON.stringify(resdb.data), req.Userinfo[2]);
5071
5342
  }
@@ -5079,8 +5350,8 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5079
5350
  DataServer.sqlDb(params).then((resdb) => {
5080
5351
  res.end(JSON.stringify($asai.$lib.As.ctxSuccess(dbCodePm(req, dbFresh(req, resdb)), opt)));
5081
5352
  }).catch((errdb) => {
5082
- const msg = String(_optionalChain([errdb, 'optionalAccess', _618 => _618.message]) || errdb || "");
5083
- if (_optionalChain([params, 'optionalAccess', _619 => _619.type]) === "select" && msg.includes("no such table")) {
5353
+ const msg = String(_optionalChain([errdb, 'optionalAccess', _662 => _662.message]) || errdb || "");
5354
+ if (_optionalChain([params, 'optionalAccess', _663 => _663.type]) === "select" && msg.includes("no such table")) {
5084
5355
  res.end(JSON.stringify($asai.$lib.As.ctxSuccess([], opt)));
5085
5356
  return;
5086
5357
  }
@@ -5097,29 +5368,29 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5097
5368
  try {
5098
5369
  DataServer.sqlDb(params).then((resdb) => {
5099
5370
  let resData = normalizeSelectResult(params, dbFresh(req, resdb));
5100
- if (_optionalChain([params, 'optionalAccess', _620 => _620.as]) === 2 && _optionalChain([params, 'optionalAccess', _621 => _621.field, 'optionalAccess', _622 => _622.length]) > 1) {
5371
+ if (_optionalChain([params, 'optionalAccess', _664 => _664.as]) === 2 && _optionalChain([params, 'optionalAccess', _665 => _665.field, 'optionalAccess', _666 => _666.length]) > 1) {
5101
5372
  let limitArr = [];
5102
- if (_optionalChain([params, 'access', _623 => _623.limit, 'optionalAccess', _624 => _624.split, 'call', _625 => _625(","), 'optionalAccess', _626 => _626.length]) < 2) {
5103
- limitArr = [0, +_optionalChain([params, 'access', _627 => _627.limit, 'optionalAccess', _628 => _628.split, 'call', _629 => _629(","), 'optionalAccess', _630 => _630[0]])];
5373
+ if (_optionalChain([params, 'access', _667 => _667.limit, 'optionalAccess', _668 => _668.split, 'call', _669 => _669(","), 'optionalAccess', _670 => _670.length]) < 2) {
5374
+ limitArr = [0, +_optionalChain([params, 'access', _671 => _671.limit, 'optionalAccess', _672 => _672.split, 'call', _673 => _673(","), 'optionalAccess', _674 => _674[0]])];
5104
5375
  } else {
5105
5376
  limitArr = params.limit.split(",");
5106
5377
  limitArr = [+limitArr[0], +limitArr[0] + +limitArr[1]];
5107
5378
  }
5108
- if (_optionalChain([resData, 'access', _631 => _631.data, 'optionalAccess', _632 => _632.length])) {
5379
+ if (_optionalChain([resData, 'access', _675 => _675.data, 'optionalAccess', _676 => _676.length])) {
5109
5380
  resData.data = resData.data.slice(+limitArr[0], +limitArr[1]);
5110
5381
  }
5111
5382
  }
5112
5383
  resData = dbCodePm(req, resData);
5113
5384
  res.end(JSON.stringify($asai.$lib.As.ctxSuccess(resData, opt)));
5114
5385
  }).catch((errdb) => {
5115
- const msg = String(_optionalChain([errdb, 'optionalAccess', _633 => _633.message]) || errdb || "");
5116
- if (_optionalChain([params, 'optionalAccess', _634 => _634.type]) === "select" && msg.includes("no such table")) {
5386
+ const msg = String(_optionalChain([errdb, 'optionalAccess', _677 => _677.message]) || errdb || "");
5387
+ if (_optionalChain([params, 'optionalAccess', _678 => _678.type]) === "select" && msg.includes("no such table")) {
5117
5388
  res.end(JSON.stringify($asai.$lib.As.ctxSuccess([], opt)));
5118
5389
  return;
5119
5390
  }
5120
5391
  res.end(JSON.stringify($asai.$lib.As.ctxFail(errdb)));
5121
5392
  });
5122
- } catch (e44) {
5393
+ } catch (e55) {
5123
5394
  res.end(JSON.stringify({ code: 901 }));
5124
5395
  }
5125
5396
  } else {
@@ -5128,7 +5399,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5128
5399
  }
5129
5400
  _chunkSMVZ3ZDJcjs.__name.call(void 0, runDefaultGet, "runDefaultGet");
5130
5401
  function post(req, res, hostdir, opt) {
5131
- if (_optionalChain([cfg, 'optionalAccess', _635 => _635.post]) && typeof cfg.post === "function") {
5402
+ if (_optionalChain([cfg, 'optionalAccess', _679 => _679.post]) && typeof cfg.post === "function") {
5132
5403
  Promise.resolve(cfg.post(req, res, hostdir, opt, DataServer)).then((reqstat) => {
5133
5404
  if (!reqstat) runDefaultPost(req, res, opt);
5134
5405
  }).catch((errdb) => {
@@ -5140,7 +5411,7 @@ var AsDb_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($asai,
5140
5411
  }
5141
5412
  _chunkSMVZ3ZDJcjs.__name.call(void 0, post, "post");
5142
5413
  function get(req, res, hostdir, opt) {
5143
- if (_optionalChain([cfg, 'optionalAccess', _636 => _636.get]) && typeof cfg.get === "function") {
5414
+ if (_optionalChain([cfg, 'optionalAccess', _680 => _680.get]) && typeof cfg.get === "function") {
5144
5415
  Promise.resolve(cfg.get(req, res, hostdir, opt, DataServer)).then((reqstat) => {
5145
5416
  if (!reqstat) runDefaultGet(req, res, opt);
5146
5417
  }).catch((errdb) => {
@@ -5166,30 +5437,30 @@ var reqWork_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($as
5166
5437
  }
5167
5438
  _chunkSMVZ3ZDJcjs.__name.call(void 0, hostDefault2, "hostDefault");
5168
5439
  function getPathFromOpt(opt) {
5169
- const rawPath = _optionalChain([opt, 'access', _637 => _637.qrdata, 'optionalAccess', _638 => _638.path]) || _optionalChain([opt, 'access', _639 => _639.data, 'optionalAccess', _640 => _640.path]);
5440
+ const rawPath = _optionalChain([opt, 'access', _681 => _681.qrdata, 'optionalAccess', _682 => _682.path]) || _optionalChain([opt, 'access', _683 => _683.data, 'optionalAccess', _684 => _684.path]);
5170
5441
  if (!rawPath) {
5171
5442
  throw new Error("Missing path");
5172
5443
  }
5173
5444
  const decoded = decodeURIComponent(String(rawPath));
5174
- if (path4.isAbsolute(decoded)) {
5175
- return path4.normalize(decoded);
5445
+ if (path5.isAbsolute(decoded)) {
5446
+ return path5.normalize(decoded);
5176
5447
  }
5177
5448
  const rel = decoded.replace(/^\.(\/)?/, "");
5178
- const serverRoot = _optionalChain([$asai, 'optionalAccess', _641 => _641.serverRoot]);
5449
+ const serverRoot = _optionalChain([$asai, 'optionalAccess', _685 => _685.serverRoot]);
5179
5450
  if (serverRoot && rel) {
5180
- const absRoot = path4.resolve(serverRoot);
5181
- const abs = path4.resolve(absRoot, rel);
5182
- const relCheck = path4.relative(absRoot, abs);
5183
- if (relCheck === "" || !relCheck.startsWith("..") && !path4.isAbsolute(relCheck)) {
5451
+ const absRoot = path5.resolve(serverRoot);
5452
+ const abs = path5.resolve(absRoot, rel);
5453
+ const relCheck = path5.relative(absRoot, abs);
5454
+ if (relCheck === "" || !relCheck.startsWith("..") && !path5.isAbsolute(relCheck)) {
5184
5455
  return abs;
5185
5456
  }
5186
5457
  }
5187
- const roots = _optionalChain([$asai, 'optionalAccess', _642 => _642.asaihost, 'optionalAccess', _643 => _643.getHostAllowedRoots, 'optionalCall', _644 => _644(_optionalChain([$asai, 'optionalAccess', _645 => _645.hostconfig]))]) || [];
5458
+ const roots = _optionalChain([$asai, 'optionalAccess', _686 => _686.asaihost, 'optionalAccess', _687 => _687.getHostAllowedRoots, 'optionalCall', _688 => _688(_optionalChain([$asai, 'optionalAccess', _689 => _689.hostconfig]))]) || [];
5188
5459
  if (!roots.length) {
5189
- const fallback = _optionalChain([$asai, 'optionalAccess', _646 => _646.serverRoot]) || process.cwd();
5460
+ const fallback = _optionalChain([$asai, 'optionalAccess', _690 => _690.serverRoot]) || process.cwd();
5190
5461
  if (fallback) roots.push(fallback);
5191
5462
  }
5192
- if (!_optionalChain([$asai, 'optionalAccess', _647 => _647.asaihost, 'optionalAccess', _648 => _648.resolvePathUnderRoots])) {
5463
+ if (!_optionalChain([$asai, 'optionalAccess', _691 => _691.asaihost, 'optionalAccess', _692 => _692.resolvePathUnderRoots])) {
5193
5464
  throw new Error("Path resolver unavailable");
5194
5465
  }
5195
5466
  return $asai.asaihost.resolvePathUnderRoots(decoded, roots);
@@ -5201,18 +5472,18 @@ var reqWork_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($as
5201
5472
  }
5202
5473
  _chunkSMVZ3ZDJcjs.__name.call(void 0, sendSuccess, "sendSuccess");
5203
5474
  function sendErr(res, ec, params, opt) {
5204
- const ErrorCode = _optionalChain([$asai, 'access', _649 => _649.$lib, 'optionalAccess', _650 => _650.ErrorCode]);
5205
- _optionalChain([ErrorCode, 'optionalAccess', _651 => _651.loadErrorCodes, 'optionalCall', _652 => _652($asai)]);
5206
- _optionalChain([ErrorCode, 'optionalAccess', _653 => _653.logError, 'optionalCall', _654 => _654($asai, ec, Array.isArray(params) ? params.map(String) : params != null ? [String(params)] : void 0)]);
5475
+ const ErrorCode = _optionalChain([$asai, 'access', _693 => _693.$lib, 'optionalAccess', _694 => _694.ErrorCode]);
5476
+ _optionalChain([ErrorCode, 'optionalAccess', _695 => _695.loadErrorCodes, 'optionalCall', _696 => _696($asai)]);
5477
+ _optionalChain([ErrorCode, 'optionalAccess', _697 => _697.logError, 'optionalCall', _698 => _698($asai, ec, Array.isArray(params) ? params.map(String) : params != null ? [String(params)] : void 0)]);
5207
5478
  const response = $asai.$lib.As.ctxErr(ec, params, opt);
5208
5479
  res.end(JSON.stringify(response));
5209
5480
  }
5210
5481
  _chunkSMVZ3ZDJcjs.__name.call(void 0, sendErr, "sendErr");
5211
5482
  function sendFail(res, err, opt) {
5212
- const ErrorCode = _optionalChain([$asai, 'access', _655 => _655.$lib, 'optionalAccess', _656 => _656.ErrorCode]);
5213
- _optionalChain([ErrorCode, 'optionalAccess', _657 => _657.loadErrorCodes, 'optionalCall', _658 => _658($asai)]);
5214
- const normalized = _optionalChain([ErrorCode, 'optionalAccess', _659 => _659.normalizeErrPayload, 'optionalCall', _660 => _660(err)]);
5215
- if (_optionalChain([normalized, 'optionalAccess', _661 => _661.ec])) {
5483
+ const ErrorCode = _optionalChain([$asai, 'access', _699 => _699.$lib, 'optionalAccess', _700 => _700.ErrorCode]);
5484
+ _optionalChain([ErrorCode, 'optionalAccess', _701 => _701.loadErrorCodes, 'optionalCall', _702 => _702($asai)]);
5485
+ const normalized = _optionalChain([ErrorCode, 'optionalAccess', _703 => _703.normalizeErrPayload, 'optionalCall', _704 => _704(err)]);
5486
+ if (_optionalChain([normalized, 'optionalAccess', _705 => _705.ec])) {
5216
5487
  return sendErr(res, normalized.ec, normalized.pm, opt);
5217
5488
  }
5218
5489
  const response = $asai.$lib.As.ctxFail(err);
@@ -5220,7 +5491,7 @@ var reqWork_default = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, ($as
5220
5491
  }
5221
5492
  _chunkSMVZ3ZDJcjs.__name.call(void 0, sendFail, "sendFail");
5222
5493
  function mnLog(...arg) {
5223
- (_optionalChain([$asai, 'optionalAccess', _662 => _662.$log]) || console.log)(...arg);
5494
+ (_optionalChain([$asai, 'optionalAccess', _706 => _706.$log]) || console.log)(...arg);
5224
5495
  }
5225
5496
  _chunkSMVZ3ZDJcjs.__name.call(void 0, mnLog, "mnLog");
5226
5497
  return { hostDefault: hostDefault2, getPathFromOpt, sendSuccess, sendFail, sendErr, mnLog };
@@ -5253,7 +5524,7 @@ async function pathExists(filePath) {
5253
5524
  try {
5254
5525
  await _promises2.default.access(nodePath2.default.normalize(filePath));
5255
5526
  return true;
5256
- } catch (e45) {
5527
+ } catch (e56) {
5257
5528
  return false;
5258
5529
  }
5259
5530
  }
@@ -5320,7 +5591,7 @@ async function removeFile(filePath) {
5320
5591
  try {
5321
5592
  await _promises2.default.unlink(nodePath2.default.normalize(filePath));
5322
5593
  } catch (err) {
5323
- if (_optionalChain([err, 'optionalAccess', _663 => _663.code]) !== "ENOENT") throw err;
5594
+ if (_optionalChain([err, 'optionalAccess', _707 => _707.code]) !== "ENOENT") throw err;
5324
5595
  }
5325
5596
  }
5326
5597
  _chunkSMVZ3ZDJcjs.__name.call(void 0, removeFile, "removeFile");
@@ -5433,11 +5704,11 @@ function toInsertRows(sql) {
5433
5704
  }
5434
5705
  _chunkSMVZ3ZDJcjs.__name.call(void 0, toInsertRows, "toInsertRows");
5435
5706
  function isPathInside(baseDir, targetPath) {
5436
- const base = path6.resolve(baseDir);
5437
- const target = path6.resolve(targetPath);
5438
- const relative5 = path6.relative(base, target);
5707
+ const base = path7.resolve(baseDir);
5708
+ const target = path7.resolve(targetPath);
5709
+ const relative5 = path7.relative(base, target);
5439
5710
  if (!relative5) return true;
5440
- return !relative5.startsWith("..") && !path6.isAbsolute(relative5);
5711
+ return !relative5.startsWith("..") && !path7.isAbsolute(relative5);
5441
5712
  }
5442
5713
  _chunkSMVZ3ZDJcjs.__name.call(void 0, isPathInside, "isPathInside");
5443
5714
  function joinTablePath(table, ...segments) {
@@ -5632,21 +5903,21 @@ function dbDriver(opt = {}) {
5632
5903
  this.fileExt = config.ext === ".*" ? "" : config.ext || "";
5633
5904
  this.fileDel = (config.del || 0) !== 0;
5634
5905
  this.createDir = config.create || false;
5635
- const root = _optionalChain([config, 'access', _664 => _664.$asai, 'optionalAccess', _665 => _665.serverRoot]) || _chunkHR5JKN7Ycjs.getPrimaryServerRoot.call(void 0, );
5636
- this.baseDirAbs = path7.resolve(root, config.dir);
5906
+ const root = _optionalChain([config, 'access', _708 => _708.$asai, 'optionalAccess', _709 => _709.serverRoot]) || _chunkHR5JKN7Ycjs.getPrimaryServerRoot.call(void 0, );
5907
+ this.baseDirAbs = path8.resolve(root, config.dir);
5637
5908
  }
5638
5909
  dbLog(...args) {
5639
- (_optionalChain([this, 'access', _666 => _666.config, 'optionalAccess', _667 => _667.$asai, 'optionalAccess', _668 => _668.$log]) || console.log)("FILE", ...args);
5910
+ (_optionalChain([this, 'access', _710 => _710.config, 'optionalAccess', _711 => _711.$asai, 'optionalAccess', _712 => _712.$log]) || console.log)("FILE", ...args);
5640
5911
  }
5641
5912
  checkFile(file) {
5642
- return fs10.existsSync(this.getAbsPath(file, false));
5913
+ return fs11.existsSync(this.getAbsPath(file, false));
5643
5914
  }
5644
5915
  /** 解析相对路径并限制在数据根目录内,防止路径穿越(跨平台) */
5645
5916
  resolvePath(relPath) {
5646
5917
  if (!relPath) {
5647
5918
  return this.baseDirAbs;
5648
5919
  }
5649
- const abs = path7.isAbsolute(relPath) ? path7.normalize(relPath) : path7.resolve(this.baseDirAbs, relPath);
5920
+ const abs = path8.isAbsolute(relPath) ? path8.normalize(relPath) : path8.resolve(this.baseDirAbs, relPath);
5650
5921
  if (!isPathInside2(this.baseDirAbs, abs)) {
5651
5922
  throw new Error("Path not allowed");
5652
5923
  }
@@ -5660,15 +5931,15 @@ function dbDriver(opt = {}) {
5660
5931
  if (!relPath) {
5661
5932
  return "";
5662
5933
  }
5663
- return path7.isAbsolute(relPath) ? path7.relative(this.baseDirAbs, relPath) : relPath;
5934
+ return path8.isAbsolute(relPath) ? path8.relative(this.baseDirAbs, relPath) : relPath;
5664
5935
  }
5665
5936
  ensureDir(relPath) {
5666
5937
  const relative5 = this.normalizeRelPath(relPath);
5667
- const dirPath = path7.dirname(relative5);
5938
+ const dirPath = path8.dirname(relative5);
5668
5939
  const absDir = this.resolvePath(dirPath === "." ? "" : dirPath);
5669
- if (this.createDir && !fs10.existsSync(absDir)) {
5940
+ if (this.createDir && !fs11.existsSync(absDir)) {
5670
5941
  this.dbLog("mkdir", "[MKDIR]", absDir);
5671
- fs10.mkdirSync(absDir, { recursive: true });
5942
+ fs11.mkdirSync(absDir, { recursive: true });
5672
5943
  }
5673
5944
  return absDir;
5674
5945
  }
@@ -5684,34 +5955,34 @@ function dbDriver(opt = {}) {
5684
5955
  }
5685
5956
  deldir(relativePath) {
5686
5957
  const absPath = this.resolvePath(relativePath);
5687
- if (!fs10.existsSync(absPath)) {
5958
+ if (!fs11.existsSync(absPath)) {
5688
5959
  return;
5689
5960
  }
5690
5961
  this.dbLog("delete", "[RMDIR]", absPath);
5691
- const entries = fs10.readdirSync(absPath, { withFileTypes: true });
5962
+ const entries = fs11.readdirSync(absPath, { withFileTypes: true });
5692
5963
  for (const entry of entries) {
5693
- const current = path7.join(absPath, entry.name);
5964
+ const current = path8.join(absPath, entry.name);
5694
5965
  if (entry.isDirectory()) {
5695
- this.deldir(path7.join(relativePath, entry.name));
5966
+ this.deldir(path8.join(relativePath, entry.name));
5696
5967
  } else {
5697
5968
  this.dbLog("delete", "[UNLINK]", current);
5698
- fs10.unlinkSync(current);
5969
+ fs11.unlinkSync(current);
5699
5970
  }
5700
5971
  }
5701
- fs10.rmdirSync(absPath);
5972
+ fs11.rmdirSync(absPath);
5702
5973
  }
5703
5974
  getReadPath(file, sql) {
5704
5975
  const candidates = [];
5705
- if (_optionalChain([sql, 'optionalAccess', _669 => _669.filename])) {
5706
- candidates.push({ dir: path7.join(file, sql.filename) });
5707
- candidates.push({ dir: path7.join(file + ".delete" + this.fileExt, sql.filename) });
5976
+ if (_optionalChain([sql, 'optionalAccess', _713 => _713.filename])) {
5977
+ candidates.push({ dir: path8.join(file, sql.filename) });
5978
+ candidates.push({ dir: path8.join(file + ".delete" + this.fileExt, sql.filename) });
5708
5979
  } else {
5709
5980
  candidates.push({ dir: file });
5710
5981
  candidates.push({ dir: file + this.fileExt + ".delete" });
5711
5982
  }
5712
5983
  for (const candidate of candidates) {
5713
5984
  const abs = this.getAbsPath(candidate.dir, false);
5714
- if (fs10.existsSync(abs)) {
5985
+ if (fs11.existsSync(abs)) {
5715
5986
  return { path: abs, dir: candidate.dir };
5716
5987
  }
5717
5988
  }
@@ -5722,22 +5993,22 @@ function dbDriver(opt = {}) {
5722
5993
  if (!read2.path) {
5723
5994
  return { path: "", dir: read2.dir };
5724
5995
  }
5725
- if (_optionalChain([sql, 'optionalAccess', _670 => _670.filename])) {
5726
- return { path: path7.dirname(read2.path), dir: path7.dirname(read2.dir) };
5996
+ if (_optionalChain([sql, 'optionalAccess', _714 => _714.filename])) {
5997
+ return { path: path8.dirname(read2.path), dir: path8.dirname(read2.dir) };
5727
5998
  }
5728
5999
  return { path: read2.path, dir: read2.dir };
5729
6000
  }
5730
6001
  getNewPath(file, sql) {
5731
- if (_optionalChain([sql, 'optionalAccess', _671 => _671.filename])) {
5732
- return this.getAbsPath(path7.join(file, sql.filename), true);
6002
+ if (_optionalChain([sql, 'optionalAccess', _715 => _715.filename])) {
6003
+ return this.getAbsPath(path8.join(file, sql.filename), true);
5733
6004
  }
5734
6005
  return this.getAbsPath(file, true);
5735
6006
  }
5736
6007
  write(file, data, sql) {
5737
6008
  try {
5738
- const filePath = _optionalChain([sql, 'optionalAccess', _672 => _672.type]) === "insert" ? this.getNewPath(file, sql) : this.getReadPath(file, sql).path || this.getNewPath(file, sql);
6009
+ const filePath = _optionalChain([sql, 'optionalAccess', _716 => _716.type]) === "insert" ? this.getNewPath(file, sql) : this.getReadPath(file, sql).path || this.getNewPath(file, sql);
5739
6010
  this.dbLog("write", "[WRITE]", filePath);
5740
- fs10.writeFileSync(filePath, data, "utf8");
6011
+ fs11.writeFileSync(filePath, data, "utf8");
5741
6012
  return "ok";
5742
6013
  } catch (e) {
5743
6014
  this.dbLog("write failed", "[WRITE ERROR]", e);
@@ -5751,7 +6022,7 @@ function dbDriver(opt = {}) {
5751
6022
  return { error: "empty" };
5752
6023
  }
5753
6024
  this.dbLog("read", "[READ]", read2.path);
5754
- const data = fs10.readFileSync(read2.path, { encoding }) || "";
6025
+ const data = fs11.readFileSync(read2.path, { encoding }) || "";
5755
6026
  const fileName = this.fileExt && read2.dir.endsWith(this.fileExt) ? read2.dir : read2.dir + this.fileExt;
5756
6027
  return [{ data, file: fileName }];
5757
6028
  } catch (e) {
@@ -5765,15 +6036,15 @@ function dbDriver(opt = {}) {
5765
6036
  if (!del.path) {
5766
6037
  return "";
5767
6038
  }
5768
- if (this.fileDel && _optionalChain([sql, 'optionalAccess', _673 => _673.deltrue])) {
6039
+ if (this.fileDel && _optionalChain([sql, 'optionalAccess', _717 => _717.deltrue])) {
5769
6040
  const target = del.path + ".delete" + this.fileExt;
5770
6041
  this.dbLog("soft delete", "[SOFT DELETE]", `${del.path} -> ${target}`);
5771
- fs10.renameSync(del.path, target);
5772
- } else if (_optionalChain([sql, 'optionalAccess', _674 => _674.filename])) {
6042
+ fs11.renameSync(del.path, target);
6043
+ } else if (_optionalChain([sql, 'optionalAccess', _718 => _718.filename])) {
5773
6044
  this.deldir(del.dir);
5774
6045
  } else {
5775
6046
  this.dbLog("delete", "[DELETE]", del.path);
5776
- fs10.unlinkSync(del.path);
6047
+ fs11.unlinkSync(del.path);
5777
6048
  }
5778
6049
  return "ok";
5779
6050
  } catch (e) {
@@ -5792,11 +6063,11 @@ function dbDriver(opt = {}) {
5792
6063
  const original = del.path.replace(new RegExp(`.delete${extPattern}$`), "");
5793
6064
  if (original !== del.path) {
5794
6065
  this.dbLog("restore", "[RESTORE]", `${del.path} -> ${original}`);
5795
- fs10.renameSync(del.path, original);
6066
+ fs11.renameSync(del.path, original);
5796
6067
  }
5797
6068
  } else {
5798
6069
  this.dbLog("force delete", "[FORCE DELETE]", del.path);
5799
- fs10.unlinkSync(del.path);
6070
+ fs11.unlinkSync(del.path);
5800
6071
  }
5801
6072
  return "ok";
5802
6073
  } catch (e) {
@@ -5810,9 +6081,9 @@ function dbDriver(opt = {}) {
5810
6081
  this.dbLog("list", "[LIST]", absDir);
5811
6082
  let entries;
5812
6083
  try {
5813
- entries = fs10.readdirSync(absDir, { withFileTypes: true });
5814
- } catch (e46) {
5815
- return _optionalChain([sql, 'optionalAccess', _675 => _675.list]) ? { open: [], delete: [] } : [];
6084
+ entries = fs11.readdirSync(absDir, { withFileTypes: true });
6085
+ } catch (e57) {
6086
+ return _optionalChain([sql, 'optionalAccess', _719 => _719.list]) ? { open: [], delete: [] } : [];
5816
6087
  }
5817
6088
  const result = { open: [], delete: [] };
5818
6089
  const deleteSuffix = ".delete" + this.fileExt;
@@ -5822,19 +6093,19 @@ function dbDriver(opt = {}) {
5822
6093
  const isDelete = fileName.endsWith(deleteSuffix);
5823
6094
  const baseName = isDelete ? fileName.slice(0, -deleteSuffix.length) : fileName;
5824
6095
  if (this.fileExt && !baseName.endsWith(this.fileExt)) continue;
5825
- const fullPath = path7.join(absDir, fileName);
6096
+ const fullPath = path8.join(absDir, fileName);
5826
6097
  try {
5827
- const data = fs10.readFileSync(fullPath, "utf8");
6098
+ const data = fs11.readFileSync(fullPath, "utf8");
5828
6099
  const entryData = { data, file: baseName };
5829
6100
  if (isDelete) {
5830
- if (_optionalChain([sql, 'optionalAccess', _676 => _676.list])) result.delete.push(entryData);
6101
+ if (_optionalChain([sql, 'optionalAccess', _720 => _720.list])) result.delete.push(entryData);
5831
6102
  } else {
5832
6103
  result.open.push(entryData);
5833
6104
  }
5834
- } catch (e47) {
6105
+ } catch (e58) {
5835
6106
  }
5836
6107
  }
5837
- return _optionalChain([sql, 'optionalAccess', _677 => _677.list]) ? result : result.open;
6108
+ return _optionalChain([sql, 'optionalAccess', _721 => _721.list]) ? result : result.open;
5838
6109
  } catch (e) {
5839
6110
  this.dbLog("list failed", "[LIST ERROR]", e);
5840
6111
  return e;
@@ -5844,7 +6115,7 @@ function dbDriver(opt = {}) {
5844
6115
  getFileNameFromWhere(where) {
5845
6116
  if (!where || !Array.isArray(where)) return "";
5846
6117
  const first = where.find((item) => Array.isArray(item));
5847
- const raw = _optionalChain([first, 'optionalAccess', _678 => _678[2]]);
6118
+ const raw = _optionalChain([first, 'optionalAccess', _722 => _722[2]]);
5848
6119
  if (typeof raw === "string") {
5849
6120
  return raw.replace(/^'+|'+$/g, "");
5850
6121
  }
@@ -5869,22 +6140,22 @@ function dbDriver(opt = {}) {
5869
6140
  const data = sql.set[0][1];
5870
6141
  result = this.write(this.tableFilePath(sql.table, file), data, sql);
5871
6142
  } else if (sql.type === "select") {
5872
- if (_optionalChain([sql, 'optionalAccess', _679 => _679.where, 'optionalAccess', _680 => _680.length]) && _optionalChain([sql, 'optionalAccess', _681 => _681.as]) !== 2) {
6143
+ if (_optionalChain([sql, 'optionalAccess', _723 => _723.where, 'optionalAccess', _724 => _724.length]) && _optionalChain([sql, 'optionalAccess', _725 => _725.as]) !== 2) {
5873
6144
  const file = this.getFileNameFromWhere(sql.where);
5874
6145
  const readRes = this.read(this.tableFilePath(sql.table, file), sql);
5875
6146
  const resObj = {};
5876
- if (_optionalChain([readRes, 'optionalAccess', _682 => _682[0], 'optionalAccess', _683 => _683.file]) && !readRes.error) {
6147
+ if (_optionalChain([readRes, 'optionalAccess', _726 => _726[0], 'optionalAccess', _727 => _727.file]) && !readRes.error) {
5877
6148
  if (sql.as === 1) {
5878
6149
  try {
5879
6150
  const parsed = JSON.parse(readRes[0].data);
5880
- if (_optionalChain([sql, 'access', _684 => _684.field, 'optionalAccess', _685 => _685.length])) {
6151
+ if (_optionalChain([sql, 'access', _728 => _728.field, 'optionalAccess', _729 => _729.length])) {
5881
6152
  sql.field.forEach((f) => {
5882
6153
  resObj[f] = _nullishCoalesce(parsed[f], () => ( ""));
5883
6154
  });
5884
6155
  } else {
5885
6156
  Object.assign(resObj, parsed);
5886
6157
  }
5887
- } catch (e48) {
6158
+ } catch (e59) {
5888
6159
  }
5889
6160
  } else {
5890
6161
  const fields = sql.field;
@@ -5898,7 +6169,7 @@ function dbDriver(opt = {}) {
5898
6169
  } else {
5899
6170
  const listRes = this.list(tableDir, sql);
5900
6171
  if (listRes && !listRes.error) {
5901
- if (_optionalChain([sql, 'optionalAccess', _686 => _686.list])) {
6172
+ if (_optionalChain([sql, 'optionalAccess', _730 => _730.list])) {
5902
6173
  const mapEntry = /* @__PURE__ */ _chunkSMVZ3ZDJcjs.__name.call(void 0, (el) => {
5903
6174
  const fields = sql.field;
5904
6175
  const item = { [fields[0]]: el.file };
@@ -5909,9 +6180,9 @@ function dbDriver(opt = {}) {
5909
6180
  if (listRes.delete) listRes.delete = listRes.delete.map(mapEntry);
5910
6181
  result = listRes;
5911
6182
  } else {
5912
- if (_optionalChain([sql, 'optionalAccess', _687 => _687.as]) === 2) {
6183
+ if (_optionalChain([sql, 'optionalAccess', _731 => _731.as]) === 2) {
5913
6184
  let items = listRes;
5914
- if (_optionalChain([sql, 'access', _688 => _688.where, 'optionalAccess', _689 => _689.length])) {
6185
+ if (_optionalChain([sql, 'access', _732 => _732.where, 'optionalAccess', _733 => _733.length])) {
5915
6186
  const where = sql.where;
5916
6187
  const whereType = typeof where[0] === "string" ? where[0] : "and";
5917
6188
  items = items.filter((el) => {
@@ -5925,7 +6196,7 @@ function dbDriver(opt = {}) {
5925
6196
  let fieldVal = "";
5926
6197
  try {
5927
6198
  fieldVal = _nullishCoalesce(JSON.parse(el.data)[field], () => ( ""));
5928
- } catch (e49) {
6199
+ } catch (e60) {
5929
6200
  }
5930
6201
  const condMatch = String(fieldVal).includes(searchVal);
5931
6202
  if (whereType === "and") {
@@ -5943,18 +6214,18 @@ function dbDriver(opt = {}) {
5943
6214
  const obj = {};
5944
6215
  try {
5945
6216
  const parsed = JSON.parse(el.data);
5946
- if (_optionalChain([sql, 'access', _690 => _690.field, 'optionalAccess', _691 => _691.length])) {
6217
+ if (_optionalChain([sql, 'access', _734 => _734.field, 'optionalAccess', _735 => _735.length])) {
5947
6218
  sql.field.forEach((f) => {
5948
6219
  obj[f] = _nullishCoalesce(parsed[f], () => ( ""));
5949
6220
  });
5950
6221
  } else {
5951
6222
  Object.assign(obj, parsed);
5952
6223
  }
5953
- } catch (e50) {
6224
+ } catch (e61) {
5954
6225
  }
5955
6226
  return obj;
5956
6227
  });
5957
- if (_optionalChain([sql, 'access', _692 => _692.order, 'optionalAccess', _693 => _693.length])) {
6228
+ if (_optionalChain([sql, 'access', _736 => _736.order, 'optionalAccess', _737 => _737.length])) {
5958
6229
  const orderField = sql.order[0];
5959
6230
  const orderFieldName = typeof orderField === "string" ? orderField : orderField[0];
5960
6231
  const direction = typeof orderField === "string" ? "ASC" : String(orderField[1]).toUpperCase();
@@ -5975,7 +6246,7 @@ function dbDriver(opt = {}) {
5975
6246
  }
5976
6247
  }
5977
6248
  } else {
5978
- result = _optionalChain([sql, 'optionalAccess', _694 => _694.list]) ? { open: [], delete: [] } : [];
6249
+ result = _optionalChain([sql, 'optionalAccess', _738 => _738.list]) ? { open: [], delete: [] } : [];
5979
6250
  }
5980
6251
  }
5981
6252
  }
@@ -6031,7 +6302,7 @@ function sysserver($asai, opt = {}) {
6031
6302
  if (!$asai.$lib) $asai.$lib = {};
6032
6303
  $asai.$lib = { ...lib_default, ...$asai.$lib, ...opt || {} };
6033
6304
  $asai.dataserver = db_default;
6034
- _optionalChain([$asai, 'access', _695 => _695.$lib, 'access', _696 => _696.ErrorCode, 'optionalAccess', _697 => _697.loadErrorCodes, 'optionalCall', _698 => _698($asai)]);
6305
+ _optionalChain([$asai, 'access', _739 => _739.$lib, 'access', _740 => _740.ErrorCode, 'optionalAccess', _741 => _741.loadErrorCodes, 'optionalCall', _742 => _742($asai)]);
6035
6306
  if (!$asai.$lib.api) $asai.$lib.api = {};
6036
6307
  $asai.$lib.api = { ...api_default, ...$asai.$lib.api };
6037
6308
  if (!$asai.$lib.ws) $asai.$lib.ws = {};
@@ -6224,7 +6495,7 @@ function normalizeDataStoresConfig(cfg) {
6224
6495
  }
6225
6496
  if (userStore.opt.create == null) userStore.opt.create = 1;
6226
6497
  }
6227
- if (!stores.log && _optionalChain([cfg, 'access', _699 => _699.logger, 'optionalAccess', _700 => _700.store])) {
6498
+ if (!stores.log && _optionalChain([cfg, 'access', _743 => _743.logger, 'optionalAccess', _744 => _744.store])) {
6228
6499
  const s = cfg.logger.store;
6229
6500
  stores.log = {
6230
6501
  type: s.type || "file",
@@ -6288,13 +6559,13 @@ function validateHostConfig(cfg) {
6288
6559
  if (cfg.asaisn != null) {
6289
6560
  errors.push("asaisn \u7981\u6B62\u5199\u5165 asaihost.json\uFF0C\u8BF7\u4F7F\u7528 ASAI_ASAISN");
6290
6561
  }
6291
- if (_optionalChain([cfg, 'access', _701 => _701.aes, 'optionalAccess', _702 => _702.keybase64]) != null) {
6562
+ if (_optionalChain([cfg, 'access', _745 => _745.aes, 'optionalAccess', _746 => _746.keybase64]) != null) {
6292
6563
  errors.push("aes.keybase64 \u7981\u6B62\u5199\u5165 asaihost.json\uFF0C\u8BF7\u4F7F\u7528 ASAI_AES_KEYBASE64");
6293
6564
  }
6294
- if (_optionalChain([cfg, 'access', _703 => _703.httpscert, 'optionalAccess', _704 => _704.key]) != null || _optionalChain([cfg, 'access', _705 => _705.httpscert, 'optionalAccess', _706 => _706.cert]) != null) {
6565
+ if (_optionalChain([cfg, 'access', _747 => _747.httpscert, 'optionalAccess', _748 => _748.key]) != null || _optionalChain([cfg, 'access', _749 => _749.httpscert, 'optionalAccess', _750 => _750.cert]) != null) {
6295
6566
  errors.push("httpscert.key/cert \u7981\u6B62\u5185\u8054\u4E8E asaihost.json\uFF0C\u8BF7\u4F7F\u7528 keyPath/certPath \u6216\u73AF\u5883\u53D8\u91CF");
6296
6567
  }
6297
- if (_optionalChain([cfg, 'access', _707 => _707.security, 'optionalAccess', _708 => _708.sessionSecret]) != null) {
6568
+ if (_optionalChain([cfg, 'access', _751 => _751.security, 'optionalAccess', _752 => _752.sessionSecret]) != null) {
6298
6569
  errors.push("security.sessionSecret \u7981\u6B62\u5199\u5165 asaihost.json\uFF0C\u8BF7\u4F7F\u7528 ASAI_SESSION_SECRET");
6299
6570
  }
6300
6571
  if (Array.isArray(cfg.wssec) && typeof cfg.wssec[0] === "string" && cfg.wssec[0].length > 0) {
@@ -6349,10 +6620,10 @@ function validateHostConfig(cfg) {
6349
6620
  validateHostSiteLimits(name, h, errors);
6350
6621
  }
6351
6622
  }
6352
- if (_optionalChain([cfg, 'access', _709 => _709.logger, 'optionalAccess', _710 => _710.sample]) && typeof cfg.logger.sample !== "object") {
6623
+ if (_optionalChain([cfg, 'access', _753 => _753.logger, 'optionalAccess', _754 => _754.sample]) && typeof cfg.logger.sample !== "object") {
6353
6624
  errors.push('logger.sample \u5FC5\u987B\u4E3A\u5BF9\u8C61\uFF08\u5982 { "REQ_OTHER": 0.1 }\uFF09');
6354
6625
  }
6355
- if (_optionalChain([cfg, 'access', _711 => _711.logger, 'optionalAccess', _712 => _712.skip]) != null && !Array.isArray(cfg.logger.skip)) {
6626
+ if (_optionalChain([cfg, 'access', _755 => _755.logger, 'optionalAccess', _756 => _756.skip]) != null && !Array.isArray(cfg.logger.skip)) {
6356
6627
  errors.push('logger.skip \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4\uFF08\u5982 ["/sys/info/metrics"]\uFF09');
6357
6628
  }
6358
6629
  if (cfg.proxyhosts && typeof cfg.proxyhosts === "object") {
@@ -6386,7 +6657,7 @@ _chunkSMVZ3ZDJcjs.__name.call(void 0, validateHostSiteLimits, "validateHostSiteL
6386
6657
  function validateProductionSecurity(cfg) {
6387
6658
  const errors = [];
6388
6659
  if (process.env.NODE_ENV !== "production") return errors;
6389
- const sec = _optionalChain([cfg, 'optionalAccess', _713 => _713.security]);
6660
+ const sec = _optionalChain([cfg, 'optionalAccess', _757 => _757.security]);
6390
6661
  if (!sec || typeof sec !== "object") {
6391
6662
  errors.push("\u751F\u4EA7\u73AF\u5883\u5FC5\u987B\u914D\u7F6E security \u5BF9\u8C61");
6392
6663
  return errors;
@@ -6397,7 +6668,7 @@ function validateProductionSecurity(cfg) {
6397
6668
  if (sec.allowRegister === 1) {
6398
6669
  errors.push("\u751F\u4EA7\u73AF\u5883 security.allowRegister \u5E94\u4E3A 0\uFF08CR 1.3 \u7981\u6B62\u5F00\u653E\u6CE8\u518C\uFF09");
6399
6670
  }
6400
- if (!_optionalChain([sec, 'access', _714 => _714.quota, 'optionalAccess', _715 => _715.enabled])) {
6671
+ if (!_optionalChain([sec, 'access', _758 => _758.quota, 'optionalAccess', _759 => _759.enabled])) {
6401
6672
  errors.push("\u751F\u4EA7\u73AF\u5883 security.quota.enabled \u5E94\u4E3A 1\uFF08CR 7.1 \u8D44\u6E90\u9650\u5236\uFF09");
6402
6673
  }
6403
6674
  if (sec.csp !== 1) {
@@ -6406,7 +6677,7 @@ function validateProductionSecurity(cfg) {
6406
6677
  if (typeof sec.minUserLevel !== "number" || sec.minUserLevel < 0) {
6407
6678
  errors.push("\u751F\u4EA7\u73AF\u5883 security.minUserLevel \u5E94\u663E\u5F0F\u914D\u7F6E");
6408
6679
  }
6409
- if (sec.forceWss === 1 && !_optionalChain([cfg, 'optionalAccess', _716 => _716.httpscert, 'optionalAccess', _717 => _717.keyPath]) && !_optionalChain([cfg, 'optionalAccess', _718 => _718.httpscert, 'optionalAccess', _719 => _719.key])) {
6680
+ if (sec.forceWss === 1 && !_optionalChain([cfg, 'optionalAccess', _760 => _760.httpscert, 'optionalAccess', _761 => _761.keyPath]) && !_optionalChain([cfg, 'optionalAccess', _762 => _762.httpscert, 'optionalAccess', _763 => _763.key])) {
6410
6681
  errors.push("\u751F\u4EA7\u73AF\u5883 security.forceWss=1 \u65F6\u9700\u914D\u7F6E HTTPS \u8BC1\u4E66");
6411
6682
  }
6412
6683
  return errors;
@@ -6425,12 +6696,12 @@ var DEFAULT_RECONNECT = {
6425
6696
  rs485: { enabled: true, maxRetries: 60, initialDelay: 3e3, maxDelay: 3e4, factor: 2 }
6426
6697
  };
6427
6698
  function getTransportBlock(cfg, kind) {
6428
- const block = _optionalChain([cfg, 'optionalAccess', _720 => _720[kind]]);
6699
+ const block = _optionalChain([cfg, 'optionalAccess', _764 => _764[kind]]);
6429
6700
  return block && typeof block === "object" ? block : null;
6430
6701
  }
6431
6702
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getTransportBlock, "getTransportBlock");
6432
6703
  function getTransportDefault(cfg, kind) {
6433
- const def = _optionalChain([getTransportBlock, 'call', _721 => _721(cfg, kind), 'optionalAccess', _722 => _722.default]);
6704
+ const def = _optionalChain([getTransportBlock, 'call', _765 => _765(cfg, kind), 'optionalAccess', _766 => _766.default]);
6434
6705
  return def && typeof def === "object" ? def : null;
6435
6706
  }
6436
6707
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getTransportDefault, "getTransportDefault");
@@ -6440,7 +6711,7 @@ function hasTransportDefault(cfg, kind) {
6440
6711
  _chunkSMVZ3ZDJcjs.__name.call(void 0, hasTransportDefault, "hasTransportDefault");
6441
6712
  function getDefaultConnId(cfg, kind) {
6442
6713
  const def = getTransportDefault(cfg, kind);
6443
- const id = _optionalChain([def, 'optionalAccess', _723 => _723.id]);
6714
+ const id = _optionalChain([def, 'optionalAccess', _767 => _767.id]);
6444
6715
  return typeof id === "string" && id.length > 0 ? id : DEFAULT_CONN_ID[kind];
6445
6716
  }
6446
6717
  _chunkSMVZ3ZDJcjs.__name.call(void 0, getDefaultConnId, "getDefaultConnId");
@@ -6451,14 +6722,14 @@ function shouldAutoConnect(def) {
6451
6722
  _chunkSMVZ3ZDJcjs.__name.call(void 0, shouldAutoConnect, "shouldAutoConnect");
6452
6723
  function resolveReconnectOptions(def, kind, cfg) {
6453
6724
  const base = DEFAULT_RECONNECT[kind];
6454
- const rc = _optionalChain([def, 'optionalAccess', _724 => _724.reconnect]);
6455
- const tmMaxTry = _optionalChain([cfg, 'optionalAccess', _725 => _725.tm, 'optionalAccess', _726 => _726.maxtry]);
6725
+ const rc = _optionalChain([def, 'optionalAccess', _768 => _768.reconnect]);
6726
+ const tmMaxTry = _optionalChain([cfg, 'optionalAccess', _769 => _769.tm, 'optionalAccess', _770 => _770.maxtry]);
6456
6727
  return {
6457
- enabled: _optionalChain([rc, 'optionalAccess', _727 => _727.enabled]) !== false && base.enabled !== false,
6458
- maxRetries: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _728 => _728.maxRetries]), () => ( tmMaxTry)), () => ( base.maxRetries)), () => ( 60)),
6459
- initialDelay: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _729 => _729.initialDelay]), () => ( base.initialDelay)), () => ( 1e3)),
6460
- maxDelay: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _730 => _730.maxDelay]), () => ( base.maxDelay)), () => ( 3e4)),
6461
- factor: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _731 => _731.factor]), () => ( base.factor)), () => ( 2))
6728
+ enabled: _optionalChain([rc, 'optionalAccess', _771 => _771.enabled]) !== false && base.enabled !== false,
6729
+ maxRetries: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _772 => _772.maxRetries]), () => ( tmMaxTry)), () => ( base.maxRetries)), () => ( 60)),
6730
+ initialDelay: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _773 => _773.initialDelay]), () => ( base.initialDelay)), () => ( 1e3)),
6731
+ maxDelay: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _774 => _774.maxDelay]), () => ( base.maxDelay)), () => ( 3e4)),
6732
+ factor: _nullishCoalesce(_nullishCoalesce(_optionalChain([rc, 'optionalAccess', _775 => _775.factor]), () => ( base.factor)), () => ( 2))
6462
6733
  };
6463
6734
  }
6464
6735
  _chunkSMVZ3ZDJcjs.__name.call(void 0, resolveReconnectOptions, "resolveReconnectOptions");
@@ -6508,17 +6779,17 @@ function createTransportDataHandler($asai, manager) {
6508
6779
  if (typeof event.data === "string") {
6509
6780
  try {
6510
6781
  event.data = JSON.parse(event.data);
6511
- } catch (e51) {
6782
+ } catch (e62) {
6512
6783
  }
6513
6784
  }
6514
- if (_optionalChain([event, 'access', _732 => _732.data, 'optionalAccess', _733 => _733.id])) {
6785
+ if (_optionalChain([event, 'access', _776 => _776.data, 'optionalAccess', _777 => _777.id])) {
6515
6786
  manager.watch(event.id, event.data);
6516
6787
  return;
6517
6788
  }
6518
6789
  try {
6519
- const wsKey = _optionalChain([$asai, 'optionalAccess', _734 => _734.command, 'optionalAccess', _735 => _735.commandconfig, 'optionalAccess', _736 => _736.config, 'optionalAccess', _737 => _737.commandclient]);
6520
- _optionalChain([$asai, 'access', _738 => _738.serversws, 'optionalAccess', _739 => _739[wsKey], 'optionalAccess', _740 => _740.broadws, 'optionalCall', _741 => _741(event.data)]);
6521
- } catch (e52) {
6790
+ const wsKey = _optionalChain([$asai, 'optionalAccess', _778 => _778.command, 'optionalAccess', _779 => _779.commandconfig, 'optionalAccess', _780 => _780.config, 'optionalAccess', _781 => _781.commandclient]);
6791
+ _optionalChain([$asai, 'access', _782 => _782.serversws, 'optionalAccess', _783 => _783[wsKey], 'optionalAccess', _784 => _784.broadws, 'optionalCall', _785 => _785(event.data)]);
6792
+ } catch (e63) {
6522
6793
  }
6523
6794
  };
6524
6795
  }
@@ -6565,20 +6836,20 @@ var initAsaiHostNodejs2 = {
6565
6836
  initHostserverWs,
6566
6837
  syncApiRouteKeys,
6567
6838
  syncWsRouteKeys,
6568
- secureCompare: _chunkWXW5DYNUcjs.secureCompare,
6839
+ secureCompare: _chunkH2QP5J7Xcjs.secureCompare,
6569
6840
  resolvePathUnderRoots,
6570
6841
  getHostAllowedRoots,
6571
6842
  logSecurityEvent,
6572
6843
  sanitizeString,
6573
6844
  validateHttpAuth,
6574
6845
  normalizeSecurityConfig,
6575
- stripForbiddenSecretsFromHostConfig: _chunkZK4O4Z2Ocjs.stripForbiddenSecretsFromHostConfig,
6576
- loadAsaiSecrets: _chunkZK4O4Z2Ocjs.loadAsaiSecrets,
6577
- loadDotEnvFile: _chunkZK4O4Z2Ocjs.loadDotEnvFile,
6578
- applySecretsToHostConfig: _chunkZK4O4Z2Ocjs.applySecretsToHostConfig,
6579
- resolveHttpsCertFromPaths: _chunkZK4O4Z2Ocjs.resolveHttpsCertFromPaths,
6580
- validateAsaiSecrets: _chunkZK4O4Z2Ocjs.validateAsaiSecrets,
6581
- isDevDefaultPassword: _chunkZK4O4Z2Ocjs.isDevDefaultPassword,
6846
+ stripForbiddenSecretsFromHostConfig: _chunk5EWEKXQIcjs.stripForbiddenSecretsFromHostConfig,
6847
+ loadAsaiSecrets: _chunk5EWEKXQIcjs.loadAsaiSecrets,
6848
+ loadDotEnvFile: _chunk5EWEKXQIcjs.loadDotEnvFile,
6849
+ applySecretsToHostConfig: _chunk5EWEKXQIcjs.applySecretsToHostConfig,
6850
+ resolveHttpsCertFromPaths: _chunk5EWEKXQIcjs.resolveHttpsCertFromPaths,
6851
+ validateAsaiSecrets: _chunk5EWEKXQIcjs.validateAsaiSecrets,
6852
+ isDevDefaultPassword: _chunk5EWEKXQIcjs.isDevDefaultPassword,
6582
6853
  getTransportBlock,
6583
6854
  getTransportDefault,
6584
6855
  hasTransportDefault,
@@ -6590,7 +6861,7 @@ var initAsaiHostNodejs2 = {
6590
6861
  createTransportDataHandler,
6591
6862
  wireTransportConnectionLogs
6592
6863
  };
6593
- var PLUGIN_VERSION = true ? "0.0.8" : "0.0.1";
6864
+ var PLUGIN_VERSION = true ? "0.0.10" : "0.0.1";
6594
6865
  var index_default = initAsaiHostNodejs2;
6595
6866
 
6596
6867
 
@@ -6633,5 +6904,5 @@ var index_default = initAsaiHostNodejs2;
6633
6904
 
6634
6905
 
6635
6906
 
6636
- exports.AsaiCommon = Index_default; exports.AsaiUtils = utils_exports; exports.PLUGIN_NAME = PLUGIN_NAME; exports.PLUGIN_VERSION = PLUGIN_VERSION; exports.applySecretsToHostConfig = _chunkZK4O4Z2Ocjs.applySecretsToHostConfig; exports.createTransportDataHandler = createTransportDataHandler; exports.default = index_default; exports.ensureDefaultConnection = ensureDefaultConnection; exports.getDefaultConnId = getDefaultConnId; exports.getHostAllowedRoots = getHostAllowedRoots; exports.getTransportBlock = getTransportBlock; exports.getTransportDefault = getTransportDefault; exports.hasTransportDefault = hasTransportDefault; exports.initAsaiHostNodejs = initAsaiHostNodejs2; exports.initHostserverApi = initHostserverApi; exports.initHostserverWs = initHostserverWs; exports.initTransportBridge = initTransportBridge; exports.isDevDefaultPassword = _chunkZK4O4Z2Ocjs.isDevDefaultPassword; exports.loadAsaiSecrets = _chunkZK4O4Z2Ocjs.loadAsaiSecrets; exports.loadDotEnvFile = _chunkZK4O4Z2Ocjs.loadDotEnvFile; exports.logSecurityEvent = logSecurityEvent; exports.normalizeHostConfig = normalizeHostConfig; exports.normalizeSecurityConfig = normalizeSecurityConfig; exports.registerApi = registerApi; exports.registerWs = registerWs; exports.resolveHttpsCertFromPaths = _chunkZK4O4Z2Ocjs.resolveHttpsCertFromPaths; exports.resolvePathUnderRoots = resolvePathUnderRoots; exports.resolveReconnectOptions = resolveReconnectOptions; exports.sanitizeString = sanitizeString; exports.secureCompare = _chunkWXW5DYNUcjs.secureCompare; exports.shouldAutoConnect = shouldAutoConnect; exports.stripForbiddenSecretsFromHostConfig = _chunkZK4O4Z2Ocjs.stripForbiddenSecretsFromHostConfig; exports.syncApiRouteKeys = syncApiRouteKeys; exports.syncWsRouteKeys = syncWsRouteKeys; exports.sysserver = sysserver; exports.validateAsaiSecrets = _chunkZK4O4Z2Ocjs.validateAsaiSecrets; exports.validateHostConfig = validateHostConfig; exports.validateHttpAuth = validateHttpAuth; exports.validateProductionSecurity = validateProductionSecurity; exports.wireTransportConnectionLogs = wireTransportConnectionLogs;
6907
+ exports.AsaiCommon = Index_default; exports.AsaiUtils = utils_exports; exports.PLUGIN_NAME = PLUGIN_NAME; exports.PLUGIN_VERSION = PLUGIN_VERSION; exports.applySecretsToHostConfig = _chunk5EWEKXQIcjs.applySecretsToHostConfig; exports.createTransportDataHandler = createTransportDataHandler; exports.default = index_default; exports.ensureDefaultConnection = ensureDefaultConnection; exports.getDefaultConnId = getDefaultConnId; exports.getHostAllowedRoots = getHostAllowedRoots; exports.getTransportBlock = getTransportBlock; exports.getTransportDefault = getTransportDefault; exports.hasTransportDefault = hasTransportDefault; exports.initAsaiHostNodejs = initAsaiHostNodejs2; exports.initHostserverApi = initHostserverApi; exports.initHostserverWs = initHostserverWs; exports.initTransportBridge = initTransportBridge; exports.isDevDefaultPassword = _chunk5EWEKXQIcjs.isDevDefaultPassword; exports.loadAsaiSecrets = _chunk5EWEKXQIcjs.loadAsaiSecrets; exports.loadDotEnvFile = _chunk5EWEKXQIcjs.loadDotEnvFile; exports.logSecurityEvent = logSecurityEvent; exports.normalizeHostConfig = normalizeHostConfig; exports.normalizeSecurityConfig = normalizeSecurityConfig; exports.registerApi = registerApi; exports.registerWs = registerWs; exports.resolveHttpsCertFromPaths = _chunk5EWEKXQIcjs.resolveHttpsCertFromPaths; exports.resolvePathUnderRoots = resolvePathUnderRoots; exports.resolveReconnectOptions = resolveReconnectOptions; exports.sanitizeString = sanitizeString; exports.secureCompare = _chunkH2QP5J7Xcjs.secureCompare; exports.shouldAutoConnect = shouldAutoConnect; exports.stripForbiddenSecretsFromHostConfig = _chunk5EWEKXQIcjs.stripForbiddenSecretsFromHostConfig; exports.syncApiRouteKeys = syncApiRouteKeys; exports.syncWsRouteKeys = syncWsRouteKeys; exports.sysserver = sysserver; exports.validateAsaiSecrets = _chunk5EWEKXQIcjs.validateAsaiSecrets; exports.validateHostConfig = validateHostConfig; exports.validateHttpAuth = validateHttpAuth; exports.validateProductionSecurity = validateProductionSecurity; exports.wireTransportConnectionLogs = wireTransportConnectionLogs;
6637
6908
  //# sourceMappingURL=asaihost-nodejs.cjs.map