cyberia 3.0.3 → 3.2.5

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 (296) hide show
  1. package/{.env.production → .env.example} +20 -4
  2. package/.github/workflows/engine-cyberia.cd.yml +43 -10
  3. package/.github/workflows/engine-cyberia.ci.yml +48 -26
  4. package/.github/workflows/ghpkg.ci.yml +5 -5
  5. package/.github/workflows/gitlab.ci.yml +1 -1
  6. package/.github/workflows/hardhat.ci.yml +82 -0
  7. package/.github/workflows/npmpkg.ci.yml +60 -14
  8. package/.github/workflows/publish.ci.yml +26 -7
  9. package/.github/workflows/publish.cyberia.ci.yml +5 -5
  10. package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -7
  11. package/.github/workflows/pwa-microservices-template-test.ci.yml +4 -4
  12. package/.github/workflows/release.cd.yml +14 -8
  13. package/.vscode/extensions.json +9 -8
  14. package/.vscode/settings.json +3 -2
  15. package/CHANGELOG.md +643 -1
  16. package/CLI-HELP.md +132 -57
  17. package/Dockerfile +4 -2
  18. package/README.md +347 -22
  19. package/WHITE-PAPER.md +1540 -0
  20. package/bin/build.js +21 -12
  21. package/bin/cyberia.js +2640 -106
  22. package/bin/deploy.js +258 -372
  23. package/bin/file.js +5 -1
  24. package/bin/index.js +2640 -106
  25. package/bin/vs.js +3 -3
  26. package/conf.js +169 -105
  27. package/deployment.yaml +236 -20
  28. package/hardhat/.env.example +31 -0
  29. package/hardhat/README.md +531 -0
  30. package/hardhat/WHITE-PAPER.md +1540 -0
  31. package/hardhat/contracts/ObjectLayerToken.sol +391 -0
  32. package/hardhat/deployments/.gitkeep +0 -0
  33. package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
  34. package/hardhat/hardhat.config.js +136 -0
  35. package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
  36. package/hardhat/networks/besu-object-layer.network.json +138 -0
  37. package/hardhat/package-lock.json +4323 -0
  38. package/hardhat/package.json +36 -0
  39. package/hardhat/scripts/deployObjectLayerToken.js +98 -0
  40. package/hardhat/test/ObjectLayerToken.js +592 -0
  41. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  42. package/hardhat/types/ethers-contracts/common.ts +92 -0
  43. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  44. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  45. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  46. package/hardhat/types/ethers-contracts/index.ts +6 -0
  47. package/jsdoc.dd-cyberia.json +68 -0
  48. package/jsdoc.json +65 -49
  49. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -4
  50. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +5 -4
  51. package/manifests/deployment/dd-cyberia-development/deployment.yaml +562 -0
  52. package/manifests/deployment/dd-cyberia-development/proxy.yaml +297 -0
  53. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
  54. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  55. package/manifests/deployment/dd-test-development/deployment.yaml +88 -74
  56. package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
  57. package/manifests/deployment/playwright/deployment.yaml +1 -1
  58. package/manifests/pv-pvc-dd.yaml +1 -1
  59. package/nodemon.json +1 -1
  60. package/package.json +60 -48
  61. package/proxy.yaml +118 -10
  62. package/pv-pvc.yaml +132 -0
  63. package/scripts/k3s-node-setup.sh +1 -1
  64. package/scripts/ports-ls.sh +2 -0
  65. package/scripts/rhel-grpc-setup.sh +56 -0
  66. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +47 -1
  67. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +17 -2
  68. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  69. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +80 -7
  70. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  71. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  72. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  73. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  74. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  75. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  76. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  77. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  78. package/src/api/cyberia-instance/cyberia-fallback-world.js +368 -0
  79. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  80. package/src/api/cyberia-instance/cyberia-instance.model.js +84 -0
  81. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  82. package/src/api/cyberia-instance/cyberia-instance.service.js +191 -0
  83. package/src/api/cyberia-instance/cyberia-portal-connector.js +486 -0
  84. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  85. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +413 -0
  86. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +228 -0
  87. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  88. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +42 -0
  89. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  90. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  91. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  92. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  93. package/src/api/document/document.service.js +1 -1
  94. package/src/api/file/file.controller.js +3 -1
  95. package/src/api/file/file.ref.json +18 -0
  96. package/src/api/file/file.service.js +28 -5
  97. package/src/api/ipfs/ipfs.controller.js +4 -25
  98. package/src/api/ipfs/ipfs.model.js +43 -34
  99. package/src/api/ipfs/ipfs.router.js +8 -13
  100. package/src/api/ipfs/ipfs.service.js +56 -104
  101. package/src/api/object-layer/README.md +347 -22
  102. package/src/api/object-layer/object-layer.controller.js +6 -2
  103. package/src/api/object-layer/object-layer.model.js +12 -8
  104. package/src/api/object-layer/object-layer.router.js +698 -42
  105. package/src/api/object-layer/object-layer.service.js +119 -37
  106. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
  107. package/src/api/user/user.router.js +10 -5
  108. package/src/api/user/user.service.js +15 -14
  109. package/src/cli/baremetal.js +6 -10
  110. package/src/cli/cloud-init.js +0 -3
  111. package/src/cli/cluster.js +7 -7
  112. package/src/cli/db.js +723 -857
  113. package/src/cli/deploy.js +215 -105
  114. package/src/cli/env.js +34 -5
  115. package/src/cli/fs.js +5 -4
  116. package/src/cli/image.js +0 -3
  117. package/src/cli/index.js +83 -15
  118. package/src/cli/kubectl.js +211 -0
  119. package/src/cli/monitor.js +5 -6
  120. package/src/cli/release.js +284 -0
  121. package/src/cli/repository.js +708 -62
  122. package/src/cli/run.js +371 -151
  123. package/src/cli/secrets.js +73 -2
  124. package/src/cli/ssh.js +1 -1
  125. package/src/cli/test.js +3 -3
  126. package/src/client/Cryptokoyn.index.js +3 -4
  127. package/src/client/CyberiaPortal.index.js +3 -4
  128. package/src/client/Default.index.js +3 -4
  129. package/src/client/Itemledger.index.js +4 -963
  130. package/src/client/Underpost.index.js +3 -4
  131. package/src/client/components/core/AgGrid.js +20 -5
  132. package/src/client/components/core/Alert.js +2 -2
  133. package/src/client/components/core/AppStore.js +69 -0
  134. package/src/client/components/core/CalendarCore.js +2 -2
  135. package/src/client/components/core/Content.js +22 -3
  136. package/src/client/components/core/Docs.js +30 -6
  137. package/src/client/components/core/DropDown.js +137 -17
  138. package/src/client/components/core/FileExplorer.js +71 -4
  139. package/src/client/components/core/Input.js +1 -1
  140. package/src/client/components/core/Keyboard.js +2 -2
  141. package/src/client/components/core/LogIn.js +2 -2
  142. package/src/client/components/core/LogOut.js +2 -2
  143. package/src/client/components/core/Modal.js +20 -7
  144. package/src/client/components/core/Panel.js +0 -1
  145. package/src/client/components/core/PanelForm.js +19 -19
  146. package/src/client/components/core/RichText.js +1 -2
  147. package/src/client/components/core/SocketIo.js +82 -29
  148. package/src/client/components/core/SocketIoHandler.js +75 -0
  149. package/src/client/components/core/Stream.js +143 -95
  150. package/src/client/components/core/Webhook.js +40 -7
  151. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  152. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +3 -3
  153. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +2 -2
  154. package/src/client/components/cryptokoyn/MenuCryptokoyn.js +3 -3
  155. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  156. package/src/client/components/cyberia/InstanceEngineCyberia.js +700 -0
  157. package/src/client/components/cyberia/MapEngineCyberia.js +1359 -2
  158. package/src/client/components/cyberia/ObjectLayerEngineModal.js +17 -6
  159. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +92 -54
  160. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  161. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +217 -30
  162. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
  163. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +3 -4
  164. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +2 -2
  165. package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +104 -9
  166. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +5 -0
  167. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  168. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
  169. package/src/client/components/default/AppStoreDefault.js +5 -0
  170. package/src/client/components/default/LogInDefault.js +3 -3
  171. package/src/client/components/default/LogOutDefault.js +2 -2
  172. package/src/client/components/default/MenuDefault.js +5 -5
  173. package/src/client/components/default/SocketIoDefault.js +3 -51
  174. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  175. package/src/client/components/itemledger/LogInItemledger.js +3 -3
  176. package/src/client/components/itemledger/LogOutItemledger.js +2 -2
  177. package/src/client/components/itemledger/MenuItemledger.js +3 -3
  178. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  179. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  180. package/src/client/components/underpost/CssUnderpost.js +59 -0
  181. package/src/client/components/underpost/LogInUnderpost.js +6 -3
  182. package/src/client/components/underpost/LogOutUnderpost.js +4 -2
  183. package/src/client/components/underpost/MenuUnderpost.js +104 -18
  184. package/src/client/components/underpost/RoutesUnderpost.js +2 -0
  185. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  186. package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
  187. package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
  188. package/src/client/public/cryptokoyn/microdata.json +85 -0
  189. package/src/client/public/cryptokoyn/site.webmanifest +57 -0
  190. package/src/client/public/cryptokoyn/sitemap +3 -3
  191. package/src/client/public/default/sitemap +3 -3
  192. package/src/client/public/itemledger/browserconfig.xml +2 -2
  193. package/src/client/public/itemledger/manifest.webmanifest +4 -4
  194. package/src/client/public/itemledger/microdata.json +71 -0
  195. package/src/client/public/itemledger/sitemap +3 -3
  196. package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
  197. package/src/client/public/test/sitemap +3 -3
  198. package/src/client/services/core/core.service.js +20 -8
  199. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +105 -0
  200. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  201. package/src/client/services/cyberia-entity/cyberia-entity.service.js +105 -0
  202. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  203. package/src/client/services/cyberia-instance/cyberia-instance.service.js +122 -0
  204. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +105 -0
  205. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  206. package/src/client/services/cyberia-map/cyberia-map.service.js +126 -0
  207. package/src/client/services/instance/instance.management.js +2 -2
  208. package/src/client/services/ipfs/ipfs.service.js +3 -23
  209. package/src/client/services/object-layer/object-layer.management.js +3 -3
  210. package/src/client/services/object-layer/object-layer.service.js +21 -0
  211. package/src/client/services/user/user.management.js +2 -2
  212. package/src/client/ssr/body/404.js +15 -11
  213. package/src/client/ssr/body/500.js +15 -11
  214. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  215. package/src/client/ssr/head/PwaItemledger.js +60 -0
  216. package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
  217. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  218. package/src/client/ssr/pages/Test.js +11 -10
  219. package/src/client.build.js +0 -3
  220. package/src/client.dev.js +0 -3
  221. package/src/db/DataBaseProvider.js +17 -2
  222. package/src/db/mariadb/MariaDB.js +14 -9
  223. package/src/db/mongo/MongooseDB.js +17 -1
  224. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +305 -0
  225. package/src/grpc/cyberia/README.md +326 -0
  226. package/src/grpc/cyberia/grpc-server.js +530 -0
  227. package/src/index.js +24 -1
  228. package/src/proxy.js +0 -3
  229. package/src/runtime/express/Dockerfile +4 -0
  230. package/src/runtime/express/Express.js +33 -10
  231. package/src/runtime/lampp/Dockerfile +13 -2
  232. package/src/runtime/lampp/Lampp.js +33 -17
  233. package/src/runtime/wp/Dockerfile +68 -0
  234. package/src/runtime/wp/Wp.js +639 -0
  235. package/src/server/auth.js +36 -15
  236. package/src/server/backup.js +39 -12
  237. package/src/server/besu-genesis-generator.js +1630 -0
  238. package/src/server/client-build-docs.js +133 -17
  239. package/src/server/client-build-live.js +9 -18
  240. package/src/server/client-build.js +229 -101
  241. package/src/server/client-dev-server.js +14 -13
  242. package/src/server/client-formatted.js +109 -57
  243. package/src/server/conf.js +391 -164
  244. package/src/server/cron.js +27 -24
  245. package/src/server/dns.js +29 -12
  246. package/src/server/downloader.js +0 -2
  247. package/src/server/ipfs-client.js +24 -1
  248. package/src/server/logger.js +27 -9
  249. package/src/server/object-layer.js +217 -103
  250. package/src/server/peer.js +8 -2
  251. package/src/server/process.js +1 -50
  252. package/src/server/proxy.js +4 -8
  253. package/src/server/runtime.js +30 -9
  254. package/src/server/semantic-layer-generator-floor.js +359 -0
  255. package/src/server/semantic-layer-generator-skin.js +1294 -0
  256. package/src/server/semantic-layer-generator.js +116 -555
  257. package/src/server/ssr.js +0 -3
  258. package/src/server/start.js +19 -12
  259. package/src/server/tls.js +0 -2
  260. package/src/server.js +0 -4
  261. package/src/ws/IoInterface.js +1 -10
  262. package/src/ws/IoServer.js +14 -33
  263. package/src/ws/core/channels/core.ws.chat.js +65 -20
  264. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  265. package/src/ws/core/channels/core.ws.stream.js +90 -31
  266. package/src/ws/core/core.ws.connection.js +12 -33
  267. package/src/ws/core/core.ws.emit.js +10 -26
  268. package/src/ws/core/core.ws.server.js +25 -58
  269. package/src/ws/default/channels/default.ws.main.js +53 -12
  270. package/src/ws/default/default.ws.connection.js +26 -13
  271. package/src/ws/default/default.ws.server.js +30 -12
  272. package/.env.development +0 -43
  273. package/.env.test +0 -43
  274. package/hardhat/contracts/CryptoKoyn.sol +0 -59
  275. package/hardhat/contracts/ItemLedger.sol +0 -73
  276. package/hardhat/contracts/Lock.sol +0 -34
  277. package/hardhat/hardhat.config.cjs +0 -45
  278. package/hardhat/ignition/modules/Lock.js +0 -18
  279. package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
  280. package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
  281. package/hardhat/scripts/deployItemledger.cjs +0 -25
  282. package/hardhat/test/Lock.js +0 -126
  283. package/hardhat/white-paper.md +0 -581
  284. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  285. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  286. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  287. package/src/client/components/default/ElementsDefault.js +0 -38
  288. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  289. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  290. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  291. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  292. package/src/ws/core/management/core.ws.chat.js +0 -8
  293. package/src/ws/core/management/core.ws.mailer.js +0 -16
  294. package/src/ws/core/management/core.ws.stream.js +0 -8
  295. package/src/ws/default/management/default.ws.main.js +0 -8
  296. package/white-paper.md +0 -581
@@ -0,0 +1,228 @@
1
+ import { Schema, model } from 'mongoose';
2
+ import { CYBERIA_INSTANCE_CONF_DEFAULTS as D } from './cyberia-instance-conf.defaults.js';
3
+
4
+ const ColorEntrySchema = new Schema(
5
+ {
6
+ key: { type: String, required: true },
7
+ r: { type: Number, default: 0 },
8
+ g: { type: Number, default: 0 },
9
+ b: { type: Number, default: 0 },
10
+ a: { type: Number, default: 255 },
11
+ },
12
+ { _id: false },
13
+ );
14
+
15
+ // ObjectLayer inventory slot: itemId + whether it starts active + initial quantity.
16
+ // Used by EntityDefaultSchema.defaultObjectLayers.
17
+ const ObjectLayerSlotSchema = new Schema(
18
+ {
19
+ itemId: { type: String, required: true },
20
+ active: { type: Boolean, default: false },
21
+ quantity: { type: Number, default: 1 },
22
+ },
23
+ { _id: false },
24
+ );
25
+
26
+ const EntityDefaultSchema = new Schema(
27
+ {
28
+ // Entity category string (matches entity_type_str / bot Behavior in game engine)
29
+ entityType: { type: String, required: true },
30
+ // Default ObjectLayer item IDs when the entity is alive and carries no assigned items.
31
+ liveItemIds: { type: [String], default: [] },
32
+ // Default ObjectLayer item IDs for the dead / ghost / respawning state.
33
+ // Empty array = use liveItemIds solid fill color.
34
+ deadItemIds: { type: [String], default: [] },
35
+ // Palette key for solid-color fallback when no OL items are assigned.
36
+ colorKey: { type: String, default: '' },
37
+ // Full default ObjectLayer inventory for this entity type.
38
+ // Each entry specifies itemId, whether it starts active, and its initial quantity.
39
+ // The coin slot must always have active:false — coins are non-activable.
40
+ // When non-empty this supersedes liveItemIds for inventory initialization.
41
+ defaultObjectLayers: { type: [ObjectLayerSlotSchema], default: [] },
42
+ },
43
+ { _id: false },
44
+ );
45
+
46
+ const SkillConfigEntrySchema = new Schema(
47
+ {
48
+ triggerItemId: { type: String, required: true },
49
+ logicEventIds: { type: [String], default: [] },
50
+ },
51
+ { _id: false },
52
+ );
53
+
54
+ // ── StatusIconEntrySchema ────────────────────────────────────────────────────
55
+ // Maps a u8 status ID to an overhead icon and a border colour used by the
56
+ // interaction bubble / interact overlay on the C/WASM client.
57
+ // See STATUS_ICONS in cyberia-instance-conf.defaults.js.
58
+ const StatusIconBorderColorSchema = new Schema(
59
+ {
60
+ r: { type: Number, default: 100 },
61
+ g: { type: Number, default: 100 },
62
+ b: { type: Number, default: 100 },
63
+ a: { type: Number, default: 200 },
64
+ },
65
+ { _id: false },
66
+ );
67
+
68
+ const StatusIconEntrySchema = new Schema(
69
+ {
70
+ id: { type: Number, required: true },
71
+ name: { type: String, default: '' },
72
+ iconId: { type: String, default: null },
73
+ bounce: { type: Boolean, default: false },
74
+ borderColor: { type: StatusIconBorderColorSchema },
75
+ description: { type: String, default: '' },
76
+ },
77
+ { _id: false },
78
+ );
79
+
80
+ // ── EconomyRulesSchema ───────────────────────────────────────────────────────
81
+ // Mirrors the EconomyRules proto message and the economyRules sub-document in
82
+ // cyberia-instance-conf.defaults.js. All fields default from those canonical
83
+ // values so a freshly created document is immediately playable.
84
+ // See OFF_CHAIN_ECONOMY.md for the full Fountain & Sink architecture.
85
+ const EconomyRulesSchema = new Schema(
86
+ {
87
+ // ── Fountains ───────────────────────────────────────────────────────────
88
+ botSpawnCoins: { type: Number, default: D.economyRules.botSpawnCoins },
89
+ playerSpawnCoins: { type: Number, default: D.economyRules.playerSpawnCoins },
90
+ // ── Kill Transfer ───────────────────────────────────────────────────────
91
+ coinKillPercentVsBot: { type: Number, default: D.economyRules.coinKillPercentVsBot },
92
+ coinKillPercentVsPlayer: { type: Number, default: D.economyRules.coinKillPercentVsPlayer },
93
+ coinKillMinAmount: { type: Number, default: D.economyRules.coinKillMinAmount },
94
+ // ── Sinks ───────────────────────────────────────────────────────────────
95
+ respawnCostPercent: { type: Number, default: D.economyRules.respawnCostPercent },
96
+ portalFee: { type: Number, default: D.economyRules.portalFee },
97
+ craftingFeePercent: { type: Number, default: D.economyRules.craftingFeePercent },
98
+ },
99
+ { _id: false },
100
+ );
101
+
102
+ // ── EquipmentRulesSchema ─────────────────────────────────────────────────────
103
+ // Governs which ObjectLayer item types can be simultaneously active on a
104
+ // character entity and enforces the one-active-per-type constraint.
105
+ // See EQUIPMENT_RULES_DEFAULTS in cyberia-instance-conf.defaults.js.
106
+ const EquipmentRulesSchema = new Schema(
107
+ {
108
+ // Item types that players are allowed to activate (equip).
109
+ // Types not in this list are non-activable (coins, floors, etc.).
110
+ activeItemTypes: { type: [String], default: D.equipmentRules.activeItemTypes },
111
+ // Enforce at most one active item per item type.
112
+ onePerType: { type: Boolean, default: D.equipmentRules.onePerType },
113
+ // Require at least one active skin when the player owns any skin.
114
+ requireSkin: { type: Boolean, default: D.equipmentRules.requireSkin },
115
+ },
116
+ { _id: false },
117
+ );
118
+
119
+ const SkillRulesSchema = new Schema(
120
+ {
121
+ projectileSpawnChance: { type: Number, default: D.skillRules.projectileSpawnChance },
122
+ projectileLifetimeMs: { type: Number, default: D.skillRules.projectileLifetimeMs },
123
+ projectileWidth: { type: Number, default: D.skillRules.projectileWidth },
124
+ projectileHeight: { type: Number, default: D.skillRules.projectileHeight },
125
+ projectileSpeedMultiplier: { type: Number, default: D.skillRules.projectileSpeedMultiplier },
126
+ doppelgangerSpawnChance: { type: Number, default: D.skillRules.doppelgangerSpawnChance },
127
+ doppelgangerLifetimeMs: { type: Number, default: D.skillRules.doppelgangerLifetimeMs },
128
+ doppelgangerSpawnRadius: { type: Number, default: D.skillRules.doppelgangerSpawnRadius },
129
+ doppelgangerInitialLifeFraction: { type: Number, default: D.skillRules.doppelgangerInitialLifeFraction },
130
+ },
131
+ { _id: false },
132
+ );
133
+
134
+ /**
135
+ * Game server configuration for a Cyberia instance.
136
+ * Separated from CyberiaInstance so the GUI never overwrites live server parameters
137
+ * when editing instance identity / map-graph fields.
138
+ *
139
+ * Linked from CyberiaInstance.conf (ObjectId ref).
140
+ * Looked up by instanceCode for CLI / gRPC use.
141
+ */
142
+ const CyberiaInstanceConfSchema = new Schema(
143
+ {
144
+ // Back-reference to the owning instance (indexed for fast lookup by code).
145
+ instanceCode: { type: String, required: true, unique: true, trim: true },
146
+
147
+ // ── Rendering / camera ──────────────────────────────────────────
148
+ cellSize: { type: Number, default: D.cellSize },
149
+ fps: { type: Number, default: D.fps },
150
+ interpolationMs: { type: Number, default: D.interpolationMs },
151
+ defaultObjWidth: { type: Number, default: D.defaultObjWidth },
152
+ defaultObjHeight: { type: Number, default: D.defaultObjHeight },
153
+ cameraSmoothing: { type: Number, default: D.cameraSmoothing },
154
+ cameraZoom: { type: Number, default: D.cameraZoom },
155
+ defaultWidthScreenFactor: { type: Number, default: D.defaultWidthScreenFactor },
156
+ defaultHeightScreenFactor: { type: Number, default: D.defaultHeightScreenFactor },
157
+ devUi: { type: Boolean, default: D.devUi },
158
+ // Empty array by default — colours must be configured per-instance.
159
+ // toInstanceConfig() fills in CYBERIA_INSTANCE_CONF_DEFAULTS.colors when the array is empty.
160
+ colors: { type: [ColorEntrySchema], default: [] },
161
+
162
+ // ── World / AOI ─────────────────────────────────────────────────
163
+ aoiRadius: { type: Number, default: D.aoiRadius },
164
+ portalHoldTimeMs: { type: Number, default: D.portalHoldTimeMs },
165
+ portalSpawnRadius: { type: Number, default: D.portalSpawnRadius },
166
+
167
+ // ── Entity base stats ────────────────────────────────────────────
168
+ entityBaseSpeed: { type: Number, default: D.entityBaseSpeed },
169
+ entityBaseMaxLife: { type: Number, default: D.entityBaseMaxLife },
170
+ entityBaseActionCooldownMs: { type: Number, default: D.entityBaseActionCooldownMs },
171
+ entityBaseMinActionCooldownMs: { type: Number, default: D.entityBaseMinActionCooldownMs },
172
+
173
+ // ── Bot defaults ─────────────────────────────────────────────────
174
+ botAggroRange: { type: Number, default: D.botAggroRange },
175
+
176
+ // ── Player defaults ──────────────────────────────────────────────
177
+ defaultPlayerWidth: { type: Number, default: D.defaultPlayerWidth },
178
+ defaultPlayerHeight: { type: Number, default: D.defaultPlayerHeight },
179
+ playerBaseLifeRegenMin: { type: Number, default: D.playerBaseLifeRegenMin },
180
+ playerBaseLifeRegenMax: { type: Number, default: D.playerBaseLifeRegenMax },
181
+ sumStatsLimit: { type: Number, default: D.sumStatsLimit },
182
+ maxActiveLayers: { type: Number, default: D.maxActiveLayers },
183
+ initialLifeFraction: { type: Number, default: D.initialLifeFraction },
184
+
185
+ // ── Combat / death ───────────────────────────────────────────────
186
+ respawnDurationMs: { type: Number, default: D.respawnDurationMs },
187
+ collisionLifeLoss: { type: Number, default: D.collisionLifeLoss },
188
+
189
+ // ── Economy ──────────────────────────────────────────────────────
190
+ // Fountain & Sink parameters. See EconomyRulesSchema and OFF_CHAIN_ECONOMY.md.
191
+ economyRules: { type: EconomyRulesSchema },
192
+
193
+ // ── Regen ────────────────────────────────────────────────────────
194
+ lifeRegenChance: { type: Number, default: D.lifeRegenChance },
195
+ maxChance: { type: Number, default: D.maxChance },
196
+
197
+ // ── Entity type rendering defaults ───────────────────────────────
198
+ // Replaces flat fields: userDefaultItemId, botDefaultItemId, ghostItemId,
199
+ // coinItemId, defaultFloorItemId, weaponDefaultItemId.
200
+ // Each entry: { entityType, liveItemIds, deadItemIds, colorKey }.
201
+ entityDefaults: { type: [EntityDefaultSchema], default: D.entityDefaults },
202
+
203
+ // ── Entity Status Indicators ────────────────────────────────────
204
+ // Overhead icon mapping + per-status border colour.
205
+ // See STATUS_ICONS in cyberia-instance-conf.defaults.js.
206
+ statusIcons: { type: [StatusIconEntrySchema], default: D.statusIcons },
207
+
208
+ // ── Skill system ─────────────────────────────────────────────────
209
+ // Each entry maps a trigger item to an ordered list of logic handler keys.
210
+ // Spawning entities (e.g. projectiles) is handled inside the logic handler itself.
211
+ skillConfig: { type: [SkillConfigEntrySchema], default: [] },
212
+
213
+ // Numeric tuning parameters for each skill archetype.
214
+ skillRules: { type: SkillRulesSchema },
215
+
216
+ // ── Equipment rules ──────────────────────────────────────────────
217
+ // Governs which item types can be simultaneously active and enforces
218
+ // the one-active-per-type constraint. See EQUIPMENT_RULES_DEFAULTS.
219
+ equipmentRules: { type: EquipmentRulesSchema },
220
+ },
221
+ { timestamps: true },
222
+ );
223
+
224
+ const CyberiaInstanceConfModel = model('CyberiaInstanceConf', CyberiaInstanceConfSchema);
225
+
226
+ const ProviderSchema = CyberiaInstanceConfSchema;
227
+
228
+ export { CyberiaInstanceConfSchema, CyberiaInstanceConfModel, ProviderSchema };
@@ -0,0 +1,27 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaInstanceConfController } from './cyberia-instance-conf.controller.js';
3
+ import express from 'express';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const CyberiaInstanceConfRouter = (options) => {
8
+ const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
+ router.post(`/:id`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
11
+ router.post(`/`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
12
+ router.get(
13
+ `/:id`,
14
+ // authMiddleware,
15
+ async (req, res) => await CyberiaInstanceConfController.get(req, res, options),
16
+ );
17
+ router.get(`/`, async (req, res) => await CyberiaInstanceConfController.get(req, res, options));
18
+ router.put(`/:id`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
19
+ router.put(`/`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
20
+ router.delete(`/:id`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
21
+ router.delete(`/`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
22
+ return router;
23
+ };
24
+
25
+ const ApiRouter = CyberiaInstanceConfRouter;
26
+
27
+ export { ApiRouter, CyberiaInstanceConfRouter };
@@ -0,0 +1,42 @@
1
+ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
2
+ import { loggerFactory } from '../../server/logger.js';
3
+ import { DataQuery } from '../../server/data-query.js';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const CyberiaInstanceConfService = {
8
+ post: async (req, res, options) => {
9
+ /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
10
+ const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
11
+ return await new CyberiaInstanceConf(req.body).save();
12
+ },
13
+ get: async (req, res, options) => {
14
+ /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
15
+ const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
16
+ if (req.params.id) return await CyberiaInstanceConf.findById(req.params.id);
17
+
18
+ // Parse query parameters using DataQuery helper
19
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
20
+
21
+ const [data, total] = await Promise.all([
22
+ CyberiaInstanceConf.find(query).sort(sort).limit(limit).skip(skip),
23
+ CyberiaInstanceConf.countDocuments(query),
24
+ ]);
25
+
26
+ const totalPages = Math.ceil(total / limit);
27
+ return { data, total, page, totalPages };
28
+ },
29
+ put: async (req, res, options) => {
30
+ /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
31
+ const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
32
+ return await CyberiaInstanceConf.findByIdAndUpdate(req.params.id, req.body);
33
+ },
34
+ delete: async (req, res, options) => {
35
+ /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
36
+ const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
37
+ if (req.params.id) return await CyberiaInstanceConf.findByIdAndDelete(req.params.id);
38
+ else return await CyberiaInstanceConf.deleteMany();
39
+ },
40
+ };
41
+
42
+ export { CyberiaInstanceConfService };
@@ -0,0 +1,79 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaMapService } from './cyberia-map.service.js';
3
+
4
+ const logger = loggerFactory(import.meta);
5
+
6
+ const CyberiaMapController = {
7
+ post: async (req, res, options) => {
8
+ try {
9
+ const result = await CyberiaMapService.post(req, res, options);
10
+ return res.status(200).json({
11
+ status: 'success',
12
+ data: result,
13
+ });
14
+ } catch (error) {
15
+ logger.error(error, error.stack);
16
+ return res.status(400).json({
17
+ status: 'error',
18
+ message: error.message,
19
+ });
20
+ }
21
+ },
22
+ get: async (req, res, options) => {
23
+ try {
24
+ const { page, limit } = req.query;
25
+ const result = await CyberiaMapService.get(
26
+ {
27
+ ...req,
28
+ path: req.path,
29
+ params: req.params,
30
+ query: { ...req.query, page: parseInt(page), limit: parseInt(limit) },
31
+ },
32
+ res,
33
+ options,
34
+ );
35
+ return res.status(200).json({
36
+ status: 'success',
37
+ data: result,
38
+ });
39
+ } catch (error) {
40
+ logger.error(error, error.stack);
41
+ return res.status(400).json({
42
+ status: 'error',
43
+ message: error.message,
44
+ });
45
+ }
46
+ },
47
+ put: async (req, res, options) => {
48
+ try {
49
+ const result = await CyberiaMapService.put(req, res, options);
50
+ return res.status(200).json({
51
+ status: 'success',
52
+ data: result,
53
+ });
54
+ } catch (error) {
55
+ logger.error(error, error.stack);
56
+ return res.status(400).json({
57
+ status: 'error',
58
+ message: error.message,
59
+ });
60
+ }
61
+ },
62
+ delete: async (req, res, options) => {
63
+ try {
64
+ const result = await CyberiaMapService.delete(req, res, options);
65
+ return res.status(200).json({
66
+ status: 'success',
67
+ data: result,
68
+ });
69
+ } catch (error) {
70
+ logger.error(error, error.stack);
71
+ return res.status(400).json({
72
+ status: 'error',
73
+ message: error.message,
74
+ });
75
+ }
76
+ },
77
+ };
78
+
79
+ export { CyberiaMapController };
@@ -0,0 +1,30 @@
1
+ import { Schema, model, Types } from 'mongoose';
2
+ import { CyberiaEntitySchema } from '../cyberia-entity/cyberia-entity.model.js';
3
+
4
+ // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
5
+
6
+ const CyberiaMapSchema = new Schema(
7
+ {
8
+ code: { type: String, default: '', unique: true },
9
+ name: { type: String, default: '' },
10
+ description: { type: String, default: '' },
11
+ entities: { type: [CyberiaEntitySchema], default: [] },
12
+ tags: { type: [String], default: [] },
13
+ creator: { type: Schema.Types.ObjectId, ref: 'User' },
14
+ status: { type: String, default: 'unlisted' },
15
+ thumbnail: { type: Schema.Types.ObjectId, ref: 'File' },
16
+ gridX: { type: Number, default: 16 },
17
+ gridY: { type: Number, default: 16 },
18
+ cellWidth: { type: Number, default: 32 },
19
+ cellHeight: { type: Number, default: 32 },
20
+ },
21
+ {
22
+ timestamps: true,
23
+ },
24
+ );
25
+
26
+ const CyberiaMapModel = model('CyberiaMap', CyberiaMapSchema);
27
+
28
+ const ProviderSchema = CyberiaMapSchema;
29
+
30
+ export { CyberiaMapSchema, CyberiaMapModel, ProviderSchema };
@@ -0,0 +1,40 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaMapController } from './cyberia-map.controller.js';
3
+ import { userGuard, adminGuard } from '../../server/auth.js';
4
+ import express from 'express';
5
+
6
+ const logger = loggerFactory(import.meta);
7
+
8
+ const CyberiaMapRouter = (options) => {
9
+ const router = express.Router();
10
+ const authMiddleware = options.authMiddleware;
11
+ router.post(
12
+ `/:id`,
13
+ authMiddleware,
14
+ userGuard,
15
+ async (req, res) => await CyberiaMapController.post(req, res, options),
16
+ );
17
+ router.post(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.post(req, res, options));
18
+ router.get(`/search-codes`, async (req, res) => await CyberiaMapController.get(req, res, options));
19
+ router.get(`/:id`, async (req, res) => await CyberiaMapController.get(req, res, options));
20
+ router.get(`/`, async (req, res) => await CyberiaMapController.get(req, res, options));
21
+ router.put(`/:id`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
22
+ router.put(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
23
+ router.delete(
24
+ `/:id`,
25
+ authMiddleware,
26
+ userGuard,
27
+ async (req, res) => await CyberiaMapController.delete(req, res, options),
28
+ );
29
+ router.delete(
30
+ `/`,
31
+ authMiddleware,
32
+ adminGuard,
33
+ async (req, res) => await CyberiaMapController.delete(req, res, options),
34
+ );
35
+ return router;
36
+ };
37
+
38
+ const ApiRouter = CyberiaMapRouter;
39
+
40
+ export { ApiRouter, CyberiaMapRouter };
@@ -0,0 +1,74 @@
1
+ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
2
+ import { loggerFactory } from '../../server/logger.js';
3
+ import { DataQuery } from '../../server/data-query.js';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const CyberiaMapService = {
8
+ post: async (req, res, options) => {
9
+ /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
10
+ const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
11
+ if (req.auth && req.auth.user) req.body.creator = req.auth.user._id;
12
+ return await new CyberiaMap(req.body).save();
13
+ },
14
+ get: async (req, res, options) => {
15
+ /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
16
+ const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
17
+ const populateCreator = { path: 'creator', model: 'User', select: '_id username' };
18
+
19
+ // GET /search-codes?q=<partial> - Fast partial match search on code
20
+ if (req.path?.startsWith('/search-codes')) {
21
+ const q = (req.query.q || '').trim();
22
+ if (!q) return { codes: [] };
23
+ const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24
+ const results = await CyberiaMap.find({ code: { $regex: escaped, $options: 'i' } }, { code: 1, _id: 0 })
25
+ .limit(20)
26
+ .lean();
27
+ const codes = [...new Set(results.map((r) => r.code).filter(Boolean))];
28
+ return { codes };
29
+ }
30
+
31
+ if (req.params.id) return await CyberiaMap.findById(req.params.id).populate(populateCreator);
32
+
33
+ // Parse query parameters using DataQuery helper
34
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
35
+
36
+ const [data, total] = await Promise.all([
37
+ CyberiaMap.find(query).sort(sort).limit(limit).skip(skip).populate(populateCreator),
38
+ CyberiaMap.countDocuments(query),
39
+ ]);
40
+
41
+ const totalPages = Math.ceil(total / limit);
42
+ return { data, total, page, totalPages };
43
+ },
44
+ put: async (req, res, options) => {
45
+ /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
46
+ const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
47
+ const map = await CyberiaMap.findById(req.params.id);
48
+ if (!map) throw new Error('map not found');
49
+ if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
50
+ throw new Error('insufficient permission');
51
+ if (req.body.thumbnail && map.thumbnail && String(req.body.thumbnail) !== String(map.thumbnail)) {
52
+ const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
53
+ await File.findByIdAndDelete(map.thumbnail);
54
+ }
55
+ return await CyberiaMap.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
56
+ },
57
+ delete: async (req, res, options) => {
58
+ /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
59
+ const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
60
+ if (req.params.id) {
61
+ const map = await CyberiaMap.findById(req.params.id);
62
+ if (!map) throw new Error('map not found');
63
+ if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
64
+ throw new Error('insufficient permission');
65
+ if (map.thumbnail) {
66
+ const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
67
+ await File.findByIdAndDelete(map.thumbnail);
68
+ }
69
+ return await CyberiaMap.findByIdAndDelete(req.params.id);
70
+ } else return await CyberiaMap.deleteMany();
71
+ },
72
+ };
73
+
74
+ export { CyberiaMapService };
@@ -497,7 +497,7 @@ const DocumentService = {
497
497
  req.body.isPublic = isPublic;
498
498
  req.body.tags = tags;
499
499
 
500
- return await Document.findByIdAndUpdate(req.params.id, req.body, { new: true });
500
+ return await Document.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
501
501
  }
502
502
  }
503
503
  },
@@ -19,7 +19,9 @@ const FileController = {
19
19
  },
20
20
  get: async (req, res, options) => {
21
21
  try {
22
- res.setHeader('Access-Control-Allow-Origin', '*');
22
+ if (req && req.headers && req.headers.origin) {
23
+ res.set('Access-Control-Allow-Origin', req.headers.origin);
24
+ } else res.setHeader('Access-Control-Allow-Origin', '*');
23
25
  res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
24
26
  const result = await FileService.get(req, res, options);
25
27
  if (result instanceof Buffer) {
@@ -1,10 +1,28 @@
1
1
  [
2
+ {
3
+ "api": "atlas-sprite-sheet",
4
+ "model": {
5
+ "fileId": true
6
+ }
7
+ },
2
8
  {
3
9
  "api": "company",
4
10
  "model": {
5
11
  "logo": true
6
12
  }
7
13
  },
14
+ {
15
+ "api": "cyberia-instance",
16
+ "model": {
17
+ "thumbnail": true
18
+ }
19
+ },
20
+ {
21
+ "api": "cyberia-map",
22
+ "model": {
23
+ "thumbnail": true
24
+ }
25
+ },
8
26
  {
9
27
  "api": "document",
10
28
  "model": {
@@ -387,12 +387,35 @@ const FileService = {
387
387
  if (doc.isPublic) return true;
388
388
 
389
389
  // Otherwise, user must be authenticated and own the document
390
+ // Try bearer token first
390
391
  const token = getBearerToken(req);
391
- if (!token) false;
392
- const payload = jwtVerify(token, options);
393
- const user = await User.findOne({ _id: payload._id }).lean();
394
- if (!user) return false;
395
- return String(doc.userId) === String(user._id);
392
+ if (token) {
393
+ try {
394
+ const payload = jwtVerify(token, options);
395
+ const user = await User.findOne({ _id: payload._id }).lean();
396
+ if (user && String(doc.userId) === String(user._id)) return true;
397
+ } catch (bearerErr) {
398
+ logger.warn('Bearer token verification failed, trying cookie session fallback:', bearerErr.message);
399
+ }
400
+ }
401
+
402
+ // Fallback: check cookie-based session (refreshToken cookie)
403
+ const refreshToken = req.cookies?.refreshToken;
404
+ if (refreshToken) {
405
+ try {
406
+ const user = await User.findOne({ 'activeSessions.tokenHash': refreshToken }).lean();
407
+ if (user) {
408
+ const session = user.activeSessions.find((s) => s.tokenHash === refreshToken);
409
+ if (session && (!session.expiresAt || session.expiresAt >= new Date())) {
410
+ return String(doc.userId) === String(user._id);
411
+ }
412
+ }
413
+ } catch (cookieErr) {
414
+ logger.warn('Cookie session verification failed:', cookieErr.message);
415
+ }
416
+ }
417
+
418
+ return false;
396
419
  } catch (err) {
397
420
  console.log(err);
398
421
  logger.error('Authorization check failed:', err);
@@ -69,34 +69,13 @@ const IpfsController = {
69
69
  });
70
70
  }
71
71
  },
72
- pin: async (req, res, options) => {
72
+ verify: async (req, res, options) => {
73
73
  try {
74
- const result = await IpfsService.pin(req, res, options);
75
- return res.status(200).json({
76
- status: 'success',
77
- data: result,
78
- });
74
+ const result = await IpfsService.verify(req, res, options);
75
+ return res.status(200).json({ status: 'success', data: result });
79
76
  } catch (error) {
80
77
  logger.error(error, error.stack);
81
- return res.status(400).json({
82
- status: 'error',
83
- message: error.message,
84
- });
85
- }
86
- },
87
- unpin: async (req, res, options) => {
88
- try {
89
- const result = await IpfsService.unpin(req, res, options);
90
- return res.status(200).json({
91
- status: 'success',
92
- data: result,
93
- });
94
- } catch (error) {
95
- logger.error(error, error.stack);
96
- return res.status(400).json({
97
- status: 'error',
98
- message: error.message,
99
- });
78
+ return res.status(400).json({ status: 'error', message: error.message });
100
79
  }
101
80
  },
102
81
  };