@sync-in/server 1.7.0 → 1.8.1

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 (275) hide show
  1. package/CHANGELOG.md +173 -58
  2. package/environment/environment.dist.yaml +6 -3
  3. package/migrations/0003_giant_luckman.sql +6 -0
  4. package/migrations/meta/0003_snapshot.json +2463 -0
  5. package/migrations/meta/_journal.json +7 -0
  6. package/package.json +19 -17
  7. package/server/app.bootstrap.js +5 -2
  8. package/server/app.bootstrap.js.map +1 -1
  9. package/server/app.constants.js +0 -4
  10. package/server/app.constants.js.map +1 -1
  11. package/server/app.service.js +7 -6
  12. package/server/app.service.js.map +1 -1
  13. package/server/applications/files/constants/only-office.js +12 -0
  14. package/server/applications/files/constants/only-office.js.map +1 -1
  15. package/server/applications/files/files.config.js +5 -0
  16. package/server/applications/files/files.config.js.map +1 -1
  17. package/server/applications/files/files.controller.js +12 -4
  18. package/server/applications/files/files.controller.js.map +1 -1
  19. package/server/applications/files/files.controller.spec.js +18 -4
  20. package/server/applications/files/files.controller.spec.js.map +1 -1
  21. package/server/applications/files/services/files-content-manager.service.js +6 -6
  22. package/server/applications/files/services/files-content-manager.service.js.map +1 -1
  23. package/server/applications/files/services/files-manager.service.js +4 -4
  24. package/server/applications/files/services/files-manager.service.js.map +1 -1
  25. package/server/applications/files/services/files-methods.service.js +4 -7
  26. package/server/applications/files/services/files-methods.service.js.map +1 -1
  27. package/server/applications/files/services/files-only-office-manager.service.js +2 -2
  28. package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
  29. package/server/applications/files/services/files-parser.service.js +6 -3
  30. package/server/applications/files/services/files-parser.service.js.map +1 -1
  31. package/server/applications/files/services/files-scheduler.service.js +51 -3
  32. package/server/applications/files/services/files-scheduler.service.js.map +1 -1
  33. package/server/applications/files/services/files-search-manager.service.js +4 -0
  34. package/server/applications/files/services/files-search-manager.service.js.map +1 -1
  35. package/server/applications/files/utils/doc-textify/adapters/pdf.js +6 -8
  36. package/server/applications/files/utils/doc-textify/adapters/pdf.js.map +1 -1
  37. package/server/applications/notifications/i18n/de.js +56 -0
  38. package/server/applications/notifications/i18n/de.js.map +1 -0
  39. package/server/applications/notifications/i18n/es.js +52 -0
  40. package/server/applications/notifications/i18n/es.js.map +1 -0
  41. package/server/applications/notifications/i18n/hi.js +52 -0
  42. package/server/applications/notifications/i18n/hi.js.map +1 -0
  43. package/server/applications/notifications/i18n/index.js +73 -8
  44. package/server/applications/notifications/i18n/index.js.map +1 -1
  45. package/server/applications/notifications/i18n/it.js +52 -0
  46. package/server/applications/notifications/i18n/it.js.map +1 -0
  47. package/server/applications/notifications/i18n/ja.js +52 -0
  48. package/server/applications/notifications/i18n/ja.js.map +1 -0
  49. package/server/applications/notifications/i18n/ko.js +52 -0
  50. package/server/applications/notifications/i18n/ko.js.map +1 -0
  51. package/server/applications/notifications/i18n/pl.js +52 -0
  52. package/server/applications/notifications/i18n/pl.js.map +1 -0
  53. package/server/applications/notifications/i18n/pt.js +52 -0
  54. package/server/applications/notifications/i18n/pt.js.map +1 -0
  55. package/server/applications/notifications/i18n/pt_br.js +52 -0
  56. package/server/applications/notifications/i18n/pt_br.js.map +1 -0
  57. package/server/applications/notifications/i18n/ru.js +52 -0
  58. package/server/applications/notifications/i18n/ru.js.map +1 -0
  59. package/server/applications/notifications/i18n/tr.js +52 -0
  60. package/server/applications/notifications/i18n/tr.js.map +1 -0
  61. package/server/applications/notifications/i18n/zh.js +52 -0
  62. package/server/applications/notifications/i18n/zh.js.map +1 -0
  63. package/server/applications/notifications/mails/models.js +6 -7
  64. package/server/applications/notifications/mails/models.js.map +1 -1
  65. package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
  66. package/server/applications/shares/dto/create-or-update-share.dto.js +11 -0
  67. package/server/applications/shares/dto/create-or-update-share.dto.js.map +1 -1
  68. package/server/applications/shares/interfaces/share-props.interface.js.map +1 -1
  69. package/server/applications/shares/schemas/share.interface.js.map +1 -1
  70. package/server/applications/shares/schemas/shares.schema.js +9 -0
  71. package/server/applications/shares/schemas/shares.schema.js.map +1 -1
  72. package/server/applications/shares/services/shares-manager.service.js +46 -17
  73. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  74. package/server/applications/shares/services/shares-queries.service.js +24 -5
  75. package/server/applications/shares/services/shares-queries.service.js.map +1 -1
  76. package/server/applications/spaces/constants/cache.js +4 -0
  77. package/server/applications/spaces/constants/cache.js.map +1 -1
  78. package/server/applications/spaces/dto/create-or-update-space.dto.js +5 -0
  79. package/server/applications/spaces/dto/create-or-update-space.dto.js.map +1 -1
  80. package/server/applications/spaces/guards/space.guard.js +3 -3
  81. package/server/applications/spaces/guards/space.guard.js.map +1 -1
  82. package/server/applications/spaces/models/space-props.model.js.map +1 -1
  83. package/server/applications/spaces/models/space.model.js.map +1 -1
  84. package/server/applications/spaces/schemas/space.interface.js.map +1 -1
  85. package/server/applications/spaces/schemas/spaces.schema.js +1 -0
  86. package/server/applications/spaces/schemas/spaces.schema.js.map +1 -1
  87. package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
  88. package/server/applications/spaces/services/spaces-manager.service.js +34 -31
  89. package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
  90. package/server/applications/spaces/services/spaces-queries.service.js +23 -7
  91. package/server/applications/spaces/services/spaces-queries.service.js.map +1 -1
  92. package/server/applications/spaces/services/spaces-scheduler.service.js +21 -20
  93. package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
  94. package/server/applications/spaces/spaces.controller.js +4 -2
  95. package/server/applications/spaces/spaces.controller.js.map +1 -1
  96. package/server/applications/spaces/utils/paths.js +14 -16
  97. package/server/applications/spaces/utils/paths.js.map +1 -1
  98. package/server/applications/sync/services/sync-manager.service.js +4 -3
  99. package/server/applications/sync/services/sync-manager.service.js.map +1 -1
  100. package/server/applications/sync/services/sync-paths-manager.service.js +1 -1
  101. package/server/applications/sync/services/sync-paths-manager.service.js.map +1 -1
  102. package/server/applications/sync/services/sync-paths-manager.service.spec.js +1 -1
  103. package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
  104. package/server/applications/sync/sync.controller.js +2 -1
  105. package/server/applications/sync/sync.controller.js.map +1 -1
  106. package/server/applications/users/constants/routes.js +5 -0
  107. package/server/applications/users/constants/routes.js.map +1 -1
  108. package/server/applications/users/constants/user.js +0 -16
  109. package/server/applications/users/constants/user.js.map +1 -1
  110. package/server/applications/users/dto/user-properties.dto.js +10 -0
  111. package/server/applications/users/dto/user-properties.dto.js.map +1 -1
  112. package/server/applications/users/models/user.model.js.map +1 -1
  113. package/server/applications/users/schemas/user.interface.js.map +1 -1
  114. package/server/applications/users/schemas/users.schema.js +3 -2
  115. package/server/applications/users/schemas/users.schema.js.map +1 -1
  116. package/server/applications/users/services/admin-users-manager.service.js +1 -0
  117. package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
  118. package/server/applications/users/services/admin-users-manager.service.spec.js +2 -1
  119. package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
  120. package/server/applications/users/services/users-manager.service.js +7 -2
  121. package/server/applications/users/services/users-manager.service.js.map +1 -1
  122. package/server/applications/users/services/users-manager.service.spec.js +1 -0
  123. package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
  124. package/server/applications/users/services/users-queries.service.js +18 -4
  125. package/server/applications/users/services/users-queries.service.js.map +1 -1
  126. package/server/applications/users/users.controller.js +15 -0
  127. package/server/applications/users/users.controller.js.map +1 -1
  128. package/server/applications/users/users.gateway.js +6 -0
  129. package/server/applications/users/users.gateway.js.map +1 -1
  130. package/server/applications/users/utils/test.js +2 -2
  131. package/server/applications/users/utils/test.js.map +1 -1
  132. package/server/applications/webdav/constants/routes.js +2 -2
  133. package/server/applications/webdav/constants/routes.js.map +1 -1
  134. package/server/applications/webdav/constants/webdav.js +2 -2
  135. package/server/applications/webdav/constants/webdav.js.map +1 -1
  136. package/server/applications/webdav/filters/webdav.filter.js +2 -2
  137. package/server/applications/webdav/filters/webdav.filter.js.map +1 -1
  138. package/server/applications/webdav/filters/webdav.filter.spec.js +2 -2
  139. package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -1
  140. package/server/applications/webdav/services/webdav-methods.service.js +3 -2
  141. package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
  142. package/server/applications/webdav/utils/webdav.js +1 -2
  143. package/server/applications/webdav/utils/webdav.js.map +1 -1
  144. package/server/authentication/auth.config.js +2 -2
  145. package/server/authentication/auth.config.js.map +1 -1
  146. package/server/authentication/guards/auth-basic.strategy.js +2 -2
  147. package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
  148. package/server/common/i18n.js +52 -0
  149. package/server/common/i18n.js.map +1 -0
  150. package/server/common/image.js +63 -43
  151. package/server/common/image.js.map +1 -1
  152. package/server/common/interfaces.js.map +1 -1
  153. package/server/common/shared.js +5 -2
  154. package/server/common/shared.js.map +1 -1
  155. package/server/configuration/config.validation.js +3 -3
  156. package/server/configuration/config.validation.js.map +1 -1
  157. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +8 -6
  158. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
  159. package/server/infrastructure/cache/adapters/redis-cache.adapter.js +22 -17
  160. package/server/infrastructure/cache/adapters/redis-cache.adapter.js.map +1 -1
  161. package/server/infrastructure/cache/cache.e2e-spec.js +1 -0
  162. package/server/infrastructure/cache/cache.e2e-spec.js.map +1 -1
  163. package/server/infrastructure/cache/cache.module.js +1 -14
  164. package/server/infrastructure/cache/cache.module.js.map +1 -1
  165. package/server/infrastructure/cache/services/cache.service.js.map +1 -1
  166. package/server/infrastructure/database/database.module.js +20 -1
  167. package/server/infrastructure/database/database.module.js.map +1 -1
  168. package/server/infrastructure/database/utils.js +48 -0
  169. package/server/infrastructure/database/utils.js.map +1 -1
  170. package/server/infrastructure/scheduler/scheduler.module.js +1 -1
  171. package/server/infrastructure/scheduler/scheduler.module.js.map +1 -1
  172. package/server/infrastructure/websocket/adapters/cluster.adapter.js +1 -3
  173. package/server/infrastructure/websocket/adapters/cluster.adapter.js.map +1 -1
  174. package/static/3rdpartylicenses.txt +137 -163
  175. package/static/chunk-2KLC4T2Z.js +1 -0
  176. package/static/chunk-2VMSXRCB.js +12 -0
  177. package/static/chunk-3GMLWAFZ.js +1 -0
  178. package/static/chunk-3OHSRRKH.js +4 -0
  179. package/static/chunk-3R4WKOHQ.js +1 -0
  180. package/static/{chunk-7ITZXYYJ.js → chunk-3R74L4UU.js} +1 -1
  181. package/static/chunk-3XVM35O2.js +1 -0
  182. package/static/chunk-3YVRP3VM.js +2 -0
  183. package/static/chunk-5NMSIIQB.js +1 -0
  184. package/static/chunk-5UKZLU5H.js +1 -0
  185. package/static/chunk-AF24EYXU.js +1 -0
  186. package/static/chunk-AKQVEHO6.js +2 -0
  187. package/static/chunk-BCVX464U.js +2 -0
  188. package/static/chunk-BQV4FRM6.js +1 -0
  189. package/static/{chunk-EVIE5F2U.js → chunk-CETH7UYS.js} +1 -1
  190. package/static/chunk-CHJ64RJM.js +1 -0
  191. package/static/chunk-DIT6W7VM.js +562 -0
  192. package/static/chunk-DKSEQTMX.js +1 -0
  193. package/static/chunk-DM4NXKEP.js +1 -0
  194. package/static/chunk-DPUVSXRB.js +1 -0
  195. package/static/chunk-DSWEWLXJ.js +1 -0
  196. package/static/chunk-FJE6BOFL.js +1 -0
  197. package/static/chunk-FZ3JPGYZ.js +1 -0
  198. package/static/chunk-IQSKQXC3.js +1 -0
  199. package/static/chunk-ITUFI2BJ.js +1 -0
  200. package/static/chunk-JPT5WEAT.js +1 -0
  201. package/static/chunk-LCTZJ537.js +1 -0
  202. package/static/chunk-LK2UCQJ6.js +1 -0
  203. package/static/chunk-LNTUR3GU.js +1 -0
  204. package/static/chunk-LP5TBXEN.js +7 -0
  205. package/static/{chunk-IPAC4VAF.js → chunk-LVSNIS5P.js} +1 -1
  206. package/static/{chunk-SIPE37PA.js → chunk-MTVSJTIW.js} +1 -1
  207. package/static/chunk-N3U6637P.js +1 -0
  208. package/static/chunk-NNV4OXSB.js +1 -0
  209. package/static/chunk-O6FYXVHI.js +1 -0
  210. package/static/chunk-OOGP4WSH.js +2 -0
  211. package/static/chunk-PB4AIT7O.js +1 -0
  212. package/static/chunk-PCWDQPOM.js +2 -0
  213. package/static/chunk-PNR6M34W.js +1 -0
  214. package/static/chunk-PVDHBQRM.js +1 -0
  215. package/static/chunk-Q5KM7LTX.js +1 -0
  216. package/static/chunk-QHC6ZPQ4.js +1 -0
  217. package/static/chunk-QMRBZHE4.js +1 -0
  218. package/static/chunk-QO6BTONN.js +1 -0
  219. package/static/chunk-QSJRY3TF.js +1 -0
  220. package/static/chunk-QUUIRSYT.js +1 -0
  221. package/static/chunk-RFH46UW3.js +1 -0
  222. package/static/{chunk-PTGDOWV3.js → chunk-RSXHRKM5.js} +1 -1
  223. package/static/chunk-RV3VZJPZ.js +1 -0
  224. package/static/{chunk-QNJFQVYI.js → chunk-S7HNXVRB.js} +1 -1
  225. package/static/chunk-SBZ572Q4.js +2 -0
  226. package/static/chunk-SJR5R3Y4.js +1 -0
  227. package/static/chunk-SLHTEGRU.js +1 -0
  228. package/static/{chunk-SH5EVL4E.js → chunk-SSFF27P2.js} +1 -1
  229. package/static/chunk-UNCPXHHT.js +1 -0
  230. package/static/chunk-URHTCJ7G.js +1 -0
  231. package/static/chunk-V3LHHZYN.js +1 -0
  232. package/static/{chunk-DJYJ66UF.js → chunk-VJTXJ43D.js} +1 -1
  233. package/static/chunk-VQQKMY2C.js +1 -0
  234. package/static/{chunk-IQOALFYU.js → chunk-WSSU2HXE.js} +1 -1
  235. package/static/chunk-XDZGW64M.js +3 -0
  236. package/static/chunk-XTRDKGKG.js +1 -0
  237. package/static/chunk-YLWTEC3X.js +1 -0
  238. package/static/chunk-Z5J5F5SX.js +1 -0
  239. package/static/chunk-ZIJQRARU.js +1 -0
  240. package/static/index.html +2 -2
  241. package/static/main-4H5BJY3J.js +9 -0
  242. package/static/scripts-WRDOQIU5.js +24 -0
  243. package/static/{styles-A5VYX3CE.css → styles-2C2UNCNB.css} +1 -1
  244. package/server/applications/spaces/interfaces/space-quota.interface.js +0 -10
  245. package/server/applications/spaces/interfaces/space-quota.interface.js.map +0 -1
  246. package/static/chunk-22EANI6R.js +0 -1
  247. package/static/chunk-3GFGJYMK.js +0 -1
  248. package/static/chunk-4YGJGZZZ.js +0 -1
  249. package/static/chunk-5K7HEX3C.js +0 -27
  250. package/static/chunk-5KLMS6A4.js +0 -1
  251. package/static/chunk-ATP3BFHV.js +0 -562
  252. package/static/chunk-BB4G55KE.js +0 -1
  253. package/static/chunk-EWKSX76T.js +0 -1
  254. package/static/chunk-FHLACA7V.js +0 -1
  255. package/static/chunk-GCATNU55.js +0 -1
  256. package/static/chunk-GYODPCIE.js +0 -1
  257. package/static/chunk-HZTFYLM5.js +0 -1
  258. package/static/chunk-JSUKJT6Z.js +0 -1
  259. package/static/chunk-JXZCNFW7.js +0 -1
  260. package/static/chunk-LTGFCQR7.js +0 -1
  261. package/static/chunk-LV3PYKWO.js +0 -1
  262. package/static/chunk-N2WFNW6M.js +0 -7
  263. package/static/chunk-ORMRCEGT.js +0 -1
  264. package/static/chunk-OUTBJSMW.js +0 -1
  265. package/static/chunk-RS2PX32L.js +0 -1
  266. package/static/chunk-RSSWH3S2.js +0 -1
  267. package/static/chunk-RTRJ3KFH.js +0 -1
  268. package/static/chunk-TKTCBDOG.js +0 -1
  269. package/static/chunk-V6K2N46L.js +0 -1
  270. package/static/chunk-XLCCZSQL.js +0 -4
  271. package/static/chunk-YPEH66GG.js +0 -1
  272. package/static/chunk-YPOIUQ57.js +0 -1
  273. package/static/chunk-ZKCFO2OA.js +0 -4
  274. package/static/main-MZ7HWZXO.js +0 -9
  275. package/static/scripts-VZVAP2P4.js +0 -30
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/models/space-props.model.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { uniquePermissions } from '../../../common/functions'\nimport { MEMBER_TYPE } from '../../users/constants/member'\nimport { Member } from '../../users/interfaces/member.interface'\nimport { SPACE_ALL_OPERATIONS, SPACE_ROLE } from '../constants/spaces'\nimport { Space } from '../schemas/space.interface'\nimport { SpaceRootProps } from './space-root-props.model'\n\nexport class SpaceProps implements Space {\n id: number\n alias: string\n name: string\n enabled: boolean\n description: string\n storageQuota: number\n storageUsage: number\n modifiedAt: Date\n disabledAt: Date\n createdAt: Date\n\n // Extra properties\n members: Member[] = []\n roots?: SpaceRootProps[] = []\n permissions: string\n role?: number\n counts?: { users: number; groups: number; links: number; roots: number; shares: number }\n\n constructor(props: Partial<SpaceProps>, userId?: number) {\n if (props?.role === SPACE_ROLE.IS_MANAGER) {\n props.permissions = SPACE_ALL_OPERATIONS\n } else if (props.permissions) {\n props.permissions = uniquePermissions(props.permissions)\n }\n\n Object.assign(this, props)\n\n if (userId) {\n this.setCounts(userId)\n }\n }\n\n setCounts(userId: number) {\n this.counts = { users: 0, groups: 0, links: 0, roots: 0, shares: 0 }\n for (const m of this.members) {\n if (m.type === MEMBER_TYPE.USER || m.type === MEMBER_TYPE.GUEST) {\n if (m.linkId) {\n this.counts.links++\n } else {\n this.counts.users++\n }\n } else {\n this.counts.groups++\n }\n }\n for (const r of this.roots) {\n if (r.owner?.id === userId) {\n this.counts.roots++\n }\n }\n }\n}\n"],"names":["SpaceProps","setCounts","userId","counts","users","groups","links","roots","shares","m","members","type","MEMBER_TYPE","USER","GUEST","linkId","r","owner","id","props","role","SPACE_ROLE","IS_MANAGER","permissions","SPACE_ALL_OPERATIONS","uniquePermissions","Object","assign"],"mappings":"AAAA;;;;CAIC;;;;+BASYA;;;eAAAA;;;2BAPqB;wBACN;wBAEqB;AAI1C,IAAA,AAAMA,aAAN,MAAMA;IAiCXC,UAAUC,MAAc,EAAE;QACxB,IAAI,CAACC,MAAM,GAAG;YAAEC,OAAO;YAAGC,QAAQ;YAAGC,OAAO;YAAGC,OAAO;YAAGC,QAAQ;QAAE;QACnE,KAAK,MAAMC,KAAK,IAAI,CAACC,OAAO,CAAE;YAC5B,IAAID,EAAEE,IAAI,KAAKC,mBAAW,CAACC,IAAI,IAAIJ,EAAEE,IAAI,KAAKC,mBAAW,CAACE,KAAK,EAAE;gBAC/D,IAAIL,EAAEM,MAAM,EAAE;oBACZ,IAAI,CAACZ,MAAM,CAACG,KAAK;gBACnB,OAAO;oBACL,IAAI,CAACH,MAAM,CAACC,KAAK;gBACnB;YACF,OAAO;gBACL,IAAI,CAACD,MAAM,CAACE,MAAM;YACpB;QACF;QACA,KAAK,MAAMW,KAAK,IAAI,CAACT,KAAK,CAAE;YAC1B,IAAIS,EAAEC,KAAK,EAAEC,OAAOhB,QAAQ;gBAC1B,IAAI,CAACC,MAAM,CAACI,KAAK;YACnB;QACF;IACF;IAhCA,YAAYY,KAA0B,EAAEjB,MAAe,CAAE;QAPzD,mBAAmB;aACnBQ,UAAoB,EAAE;aACtBH,QAA2B,EAAE;QAM3B,IAAIY,OAAOC,SAASC,kBAAU,CAACC,UAAU,EAAE;YACzCH,MAAMI,WAAW,GAAGC,4BAAoB;QAC1C,OAAO,IAAIL,MAAMI,WAAW,EAAE;YAC5BJ,MAAMI,WAAW,GAAGE,IAAAA,4BAAiB,EAACN,MAAMI,WAAW;QACzD;QAEAG,OAAOC,MAAM,CAAC,IAAI,EAAER;QAEpB,IAAIjB,QAAQ;YACV,IAAI,CAACD,SAAS,CAACC;QACjB;IACF;AAqBF"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/models/space-props.model.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { uniquePermissions } from '../../../common/functions'\nimport { MEMBER_TYPE } from '../../users/constants/member'\nimport { Member } from '../../users/interfaces/member.interface'\nimport { SPACE_ALL_OPERATIONS, SPACE_ROLE } from '../constants/spaces'\nimport { Space } from '../schemas/space.interface'\nimport { SpaceRootProps } from './space-root-props.model'\n\nexport class SpaceProps implements Space {\n id: number\n alias: string\n name: string\n enabled: boolean\n description: string\n storageQuota: number\n storageUsage: number\n storageIndexing: boolean\n modifiedAt: Date\n disabledAt: Date\n createdAt: Date\n\n // Extra properties\n members: Member[] = []\n roots?: SpaceRootProps[] = []\n permissions: string\n role?: number\n counts?: { users: number; groups: number; links: number; roots: number; shares: number }\n\n constructor(props: Partial<SpaceProps>, userId?: number) {\n if (props?.role === SPACE_ROLE.IS_MANAGER) {\n props.permissions = SPACE_ALL_OPERATIONS\n } else if (props.permissions) {\n props.permissions = uniquePermissions(props.permissions)\n }\n\n Object.assign(this, props)\n\n if (userId) {\n this.setCounts(userId)\n }\n }\n\n setCounts(userId: number) {\n this.counts = { users: 0, groups: 0, links: 0, roots: 0, shares: 0 }\n for (const m of this.members) {\n if (m.type === MEMBER_TYPE.USER || m.type === MEMBER_TYPE.GUEST) {\n if (m.linkId) {\n this.counts.links++\n } else {\n this.counts.users++\n }\n } else {\n this.counts.groups++\n }\n }\n for (const r of this.roots) {\n if (r.owner?.id === userId) {\n this.counts.roots++\n }\n }\n }\n}\n"],"names":["SpaceProps","setCounts","userId","counts","users","groups","links","roots","shares","m","members","type","MEMBER_TYPE","USER","GUEST","linkId","r","owner","id","props","role","SPACE_ROLE","IS_MANAGER","permissions","SPACE_ALL_OPERATIONS","uniquePermissions","Object","assign"],"mappings":"AAAA;;;;CAIC;;;;+BASYA;;;eAAAA;;;2BAPqB;wBACN;wBAEqB;AAI1C,IAAA,AAAMA,aAAN,MAAMA;IAkCXC,UAAUC,MAAc,EAAE;QACxB,IAAI,CAACC,MAAM,GAAG;YAAEC,OAAO;YAAGC,QAAQ;YAAGC,OAAO;YAAGC,OAAO;YAAGC,QAAQ;QAAE;QACnE,KAAK,MAAMC,KAAK,IAAI,CAACC,OAAO,CAAE;YAC5B,IAAID,EAAEE,IAAI,KAAKC,mBAAW,CAACC,IAAI,IAAIJ,EAAEE,IAAI,KAAKC,mBAAW,CAACE,KAAK,EAAE;gBAC/D,IAAIL,EAAEM,MAAM,EAAE;oBACZ,IAAI,CAACZ,MAAM,CAACG,KAAK;gBACnB,OAAO;oBACL,IAAI,CAACH,MAAM,CAACC,KAAK;gBACnB;YACF,OAAO;gBACL,IAAI,CAACD,MAAM,CAACE,MAAM;YACpB;QACF;QACA,KAAK,MAAMW,KAAK,IAAI,CAACT,KAAK,CAAE;YAC1B,IAAIS,EAAEC,KAAK,EAAEC,OAAOhB,QAAQ;gBAC1B,IAAI,CAACC,MAAM,CAACI,KAAK;YACnB;QACF;IACF;IAhCA,YAAYY,KAA0B,EAAEjB,MAAe,CAAE;QAPzD,mBAAmB;aACnBQ,UAAoB,EAAE;aACtBH,QAA2B,EAAE;QAM3B,IAAIY,OAAOC,SAASC,kBAAU,CAACC,UAAU,EAAE;YACzCH,MAAMI,WAAW,GAAGC,4BAAoB;QAC1C,OAAO,IAAIL,MAAMI,WAAW,EAAE;YAC5BJ,MAAMI,WAAW,GAAGE,IAAAA,4BAAiB,EAACN,MAAMI,WAAW;QACzD;QAEAG,OAAOC,MAAM,CAAC,IAAI,EAAER;QAEpB,IAAIjB,QAAQ;YACV,IAAI,CAACD,SAAS,CAACC;QACjB;IACF;AAqBF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/models/space.model.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { configuration } from '../../../configuration/config.environment'\nimport { SPACE_REPOSITORY } from '../constants/spaces'\nimport { SpaceRoot } from '../schemas/space-root.interface'\nimport { Space } from '../schemas/space.interface'\n\nexport class SpaceModel implements Space {\n id: number\n alias: string\n enabled: boolean\n name: string\n description: string\n storageQuota: number\n storageUsage: number\n modifiedAt: Date\n disabledAt: Date\n createdAt: Date\n\n // outside db schema\n root: SpaceRoot[] = []\n private _homePath: string\n private _filesPath: string\n private _trashPath: string\n\n constructor(props: any) {\n Object.assign(this, props)\n }\n\n get homePath(): string {\n return (this._homePath ||= path.join(configuration.applications.files.spacesPath, this.alias))\n }\n\n get filesPath(): string {\n return (this._filesPath ||= path.join(this.homePath, SPACE_REPOSITORY.FILES))\n }\n\n get trashPath(): string {\n return (this._trashPath ||= path.join(this.homePath, SPACE_REPOSITORY.TRASH))\n }\n\n static async makePaths(spaceAlias: string) {\n for (const p of [SpaceModel.getFilesPath(spaceAlias), SpaceModel.getTrashPath(spaceAlias)]) {\n await fs.mkdir(p, { recursive: true })\n }\n }\n\n static getHomePath(spaceAlias: string) {\n return path.join(configuration.applications.files.spacesPath, spaceAlias)\n }\n\n static getFilesPath(spaceAlias: string) {\n return path.join(SpaceModel.getHomePath(spaceAlias), SPACE_REPOSITORY.FILES)\n }\n\n static getTrashPath(spaceAlias: string) {\n return path.join(SpaceModel.getHomePath(spaceAlias), SPACE_REPOSITORY.TRASH)\n }\n\n static getRepositoryPath(spaceAlias: string, inTrash = false) {\n if (inTrash) return SpaceModel.getTrashPath(spaceAlias)\n return SpaceModel.getFilesPath(spaceAlias)\n }\n}\n"],"names":["SpaceModel","homePath","_homePath","path","join","configuration","applications","files","spacesPath","alias","filesPath","_filesPath","SPACE_REPOSITORY","FILES","trashPath","_trashPath","TRASH","makePaths","spaceAlias","p","getFilesPath","getTrashPath","fs","mkdir","recursive","getHomePath","getRepositoryPath","inTrash","props","root","Object","assign"],"mappings":"AAAA;;;;CAIC;;;;+BASYA;;;eAAAA;;;iEAPE;iEACE;mCACa;wBACG;;;;;;AAI1B,IAAA,AAAMA,aAAN,MAAMA;IAsBX,IAAIC,WAAmB;QACrB,OAAQ,IAAI,CAACC,SAAS,KAAKC,iBAAI,CAACC,IAAI,CAACC,gCAAa,CAACC,YAAY,CAACC,KAAK,CAACC,UAAU,EAAE,IAAI,CAACC,KAAK;IAC9F;IAEA,IAAIC,YAAoB;QACtB,OAAQ,IAAI,CAACC,UAAU,KAAKR,iBAAI,CAACC,IAAI,CAAC,IAAI,CAACH,QAAQ,EAAEW,wBAAgB,CAACC,KAAK;IAC7E;IAEA,IAAIC,YAAoB;QACtB,OAAQ,IAAI,CAACC,UAAU,KAAKZ,iBAAI,CAACC,IAAI,CAAC,IAAI,CAACH,QAAQ,EAAEW,wBAAgB,CAACI,KAAK;IAC7E;IAEA,aAAaC,UAAUC,UAAkB,EAAE;QACzC,KAAK,MAAMC,KAAK;YAACnB,WAAWoB,YAAY,CAACF;YAAalB,WAAWqB,YAAY,CAACH;SAAY,CAAE;YAC1F,MAAMI,iBAAE,CAACC,KAAK,CAACJ,GAAG;gBAAEK,WAAW;YAAK;QACtC;IACF;IAEA,OAAOC,YAAYP,UAAkB,EAAE;QACrC,OAAOf,iBAAI,CAACC,IAAI,CAACC,gCAAa,CAACC,YAAY,CAACC,KAAK,CAACC,UAAU,EAAEU;IAChE;IAEA,OAAOE,aAAaF,UAAkB,EAAE;QACtC,OAAOf,iBAAI,CAACC,IAAI,CAACJ,WAAWyB,WAAW,CAACP,aAAaN,wBAAgB,CAACC,KAAK;IAC7E;IAEA,OAAOQ,aAAaH,UAAkB,EAAE;QACtC,OAAOf,iBAAI,CAACC,IAAI,CAACJ,WAAWyB,WAAW,CAACP,aAAaN,wBAAgB,CAACI,KAAK;IAC7E;IAEA,OAAOU,kBAAkBR,UAAkB,EAAES,UAAU,KAAK,EAAE;QAC5D,IAAIA,SAAS,OAAO3B,WAAWqB,YAAY,CAACH;QAC5C,OAAOlB,WAAWoB,YAAY,CAACF;IACjC;IArCA,YAAYU,KAAU,CAAE;QANxB,oBAAoB;aACpBC,OAAoB,EAAE;QAMpBC,OAAOC,MAAM,CAAC,IAAI,EAAEH;IACtB;AAoCF"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/models/space.model.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { configuration } from '../../../configuration/config.environment'\nimport { SPACE_REPOSITORY } from '../constants/spaces'\nimport { SpaceRoot } from '../schemas/space-root.interface'\nimport { Space } from '../schemas/space.interface'\n\nexport class SpaceModel implements Space {\n id: number\n alias: string\n enabled: boolean\n name: string\n description: string\n storageQuota: number\n storageUsage: number\n storageIndexing: boolean\n modifiedAt: Date\n disabledAt: Date\n createdAt: Date\n\n // outside db schema\n root: SpaceRoot[] = []\n private _homePath: string\n private _filesPath: string\n private _trashPath: string\n\n constructor(props: any) {\n Object.assign(this, props)\n }\n\n get homePath(): string {\n return (this._homePath ||= path.join(configuration.applications.files.spacesPath, this.alias))\n }\n\n get filesPath(): string {\n return (this._filesPath ||= path.join(this.homePath, SPACE_REPOSITORY.FILES))\n }\n\n get trashPath(): string {\n return (this._trashPath ||= path.join(this.homePath, SPACE_REPOSITORY.TRASH))\n }\n\n static async makePaths(spaceAlias: string) {\n for (const p of [SpaceModel.getFilesPath(spaceAlias), SpaceModel.getTrashPath(spaceAlias)]) {\n await fs.mkdir(p, { recursive: true })\n }\n }\n\n static getHomePath(spaceAlias: string) {\n return path.join(configuration.applications.files.spacesPath, spaceAlias)\n }\n\n static getFilesPath(spaceAlias: string) {\n return path.join(SpaceModel.getHomePath(spaceAlias), SPACE_REPOSITORY.FILES)\n }\n\n static getTrashPath(spaceAlias: string) {\n return path.join(SpaceModel.getHomePath(spaceAlias), SPACE_REPOSITORY.TRASH)\n }\n\n static getRepositoryPath(spaceAlias: string, inTrash = false) {\n if (inTrash) return SpaceModel.getTrashPath(spaceAlias)\n return SpaceModel.getFilesPath(spaceAlias)\n }\n}\n"],"names":["SpaceModel","homePath","_homePath","path","join","configuration","applications","files","spacesPath","alias","filesPath","_filesPath","SPACE_REPOSITORY","FILES","trashPath","_trashPath","TRASH","makePaths","spaceAlias","p","getFilesPath","getTrashPath","fs","mkdir","recursive","getHomePath","getRepositoryPath","inTrash","props","root","Object","assign"],"mappings":"AAAA;;;;CAIC;;;;+BASYA;;;eAAAA;;;iEAPE;iEACE;mCACa;wBACG;;;;;;AAI1B,IAAA,AAAMA,aAAN,MAAMA;IAuBX,IAAIC,WAAmB;QACrB,OAAQ,IAAI,CAACC,SAAS,KAAKC,iBAAI,CAACC,IAAI,CAACC,gCAAa,CAACC,YAAY,CAACC,KAAK,CAACC,UAAU,EAAE,IAAI,CAACC,KAAK;IAC9F;IAEA,IAAIC,YAAoB;QACtB,OAAQ,IAAI,CAACC,UAAU,KAAKR,iBAAI,CAACC,IAAI,CAAC,IAAI,CAACH,QAAQ,EAAEW,wBAAgB,CAACC,KAAK;IAC7E;IAEA,IAAIC,YAAoB;QACtB,OAAQ,IAAI,CAACC,UAAU,KAAKZ,iBAAI,CAACC,IAAI,CAAC,IAAI,CAACH,QAAQ,EAAEW,wBAAgB,CAACI,KAAK;IAC7E;IAEA,aAAaC,UAAUC,UAAkB,EAAE;QACzC,KAAK,MAAMC,KAAK;YAACnB,WAAWoB,YAAY,CAACF;YAAalB,WAAWqB,YAAY,CAACH;SAAY,CAAE;YAC1F,MAAMI,iBAAE,CAACC,KAAK,CAACJ,GAAG;gBAAEK,WAAW;YAAK;QACtC;IACF;IAEA,OAAOC,YAAYP,UAAkB,EAAE;QACrC,OAAOf,iBAAI,CAACC,IAAI,CAACC,gCAAa,CAACC,YAAY,CAACC,KAAK,CAACC,UAAU,EAAEU;IAChE;IAEA,OAAOE,aAAaF,UAAkB,EAAE;QACtC,OAAOf,iBAAI,CAACC,IAAI,CAACJ,WAAWyB,WAAW,CAACP,aAAaN,wBAAgB,CAACC,KAAK;IAC7E;IAEA,OAAOQ,aAAaH,UAAkB,EAAE;QACtC,OAAOf,iBAAI,CAACC,IAAI,CAACJ,WAAWyB,WAAW,CAACP,aAAaN,wBAAgB,CAACI,KAAK;IAC7E;IAEA,OAAOU,kBAAkBR,UAAkB,EAAES,UAAU,KAAK,EAAE;QAC5D,IAAIA,SAAS,OAAO3B,WAAWqB,YAAY,CAACH;QAC5C,OAAOlB,WAAWoB,YAAY,CAACF;IACjC;IArCA,YAAYU,KAAU,CAAE;QANxB,oBAAoB;aACpBC,OAAoB,EAAE;QAMpBC,OAAOC,MAAM,CAAC,IAAI,EAAEH;IACtB;AAoCF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/schemas/space.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport type { spaces } from './spaces.schema'\n\ntype SpaceSchema = typeof spaces.$inferSelect\n\nexport class Space implements SpaceSchema {\n id: number\n alias: string\n name: string\n enabled: boolean\n description: string\n storageUsage: number\n storageQuota: number\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n}\n"],"names":["Space"],"mappings":"AAAA;;;;CAIC;;;;+BAMYA;;;eAAAA;;;AAAN,IAAA,AAAMA,QAAN,MAAMA;AAWb"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/schemas/space.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport type { spaces } from './spaces.schema'\n\ntype SpaceSchema = typeof spaces.$inferSelect\n\nexport class Space implements SpaceSchema {\n id: number\n alias: string\n name: string\n enabled: boolean\n description: string\n storageUsage: number\n storageQuota: number\n storageIndexing: boolean\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n}\n"],"names":["Space"],"mappings":"AAAA;;;;CAIC;;;;+BAMYA;;;eAAAA;;;AAAN,IAAA,AAAMA,QAAN,MAAMA;AAYb"}
@@ -46,6 +46,7 @@ const spaces = (0, _mysqlcore.mysqlTable)('spaces', {
46
46
  mode: 'number',
47
47
  unsigned: true
48
48
  }),
49
+ storageIndexing: (0, _mysqlcore.boolean)('storageIndexing').default(true).notNull(),
49
50
  createdAt: (0, _mysqlcore.datetime)('createdAt', {
50
51
  mode: 'date'
51
52
  }).default((0, _drizzleorm.sql)`CURRENT_TIMESTAMP`).notNull(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/schemas/spaces.schema.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { SQL, sql } from 'drizzle-orm'\nimport { bigint, boolean, datetime, mysqlTable, uniqueIndex, varchar } from 'drizzle-orm/mysql-core'\nimport { SPACE_PERMS_SEP } from '../constants/spaces'\n\n/*\n alias: used to navigate over api & webdav, must be unique\n name: set by user and showed on web\n storageQuota:\n 0 : no storage\n null : unlimited\n other: limited to value\n*/\n\nexport const spaces = mysqlTable(\n 'spaces',\n {\n id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),\n alias: varchar('alias', { length: 255 }).notNull(),\n name: varchar('name', { length: 255 }).notNull(),\n description: varchar('description', { length: 255 }),\n enabled: boolean('enabled').default(true).notNull(),\n storageUsage: bigint('storageUsage', { mode: 'number', unsigned: true }).default(0).notNull(),\n storageQuota: bigint('storageQuota', { mode: 'number', unsigned: true }),\n createdAt: datetime('createdAt', { mode: 'date' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n modifiedAt: datetime('modifiedAt', { mode: 'date' }).default(sql`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`),\n disabledAt: datetime('disabledAt', { mode: 'date' })\n },\n (table) => [uniqueIndex('alias_idx').on(table.alias)]\n)\n\nexport const spaceGroupConcatPermissions = (column: any, separator = SPACE_PERMS_SEP): SQL<string> =>\n sql`IFNULL(GROUP_CONCAT(DISTINCT(IF(${column} = '', null, ${column})) SEPARATOR ${sql.raw(`'${separator}'`)}), '')`\n"],"names":["spaceGroupConcatPermissions","spaces","mysqlTable","id","bigint","mode","unsigned","autoincrement","primaryKey","alias","varchar","length","notNull","name","description","enabled","boolean","default","storageUsage","storageQuota","createdAt","datetime","sql","modifiedAt","disabledAt","table","uniqueIndex","on","column","separator","SPACE_PERMS_SEP","raw"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAkCYA;eAAAA;;QAnBAC;eAAAA;;;4BAbY;2BACmD;wBAC5C;AAWzB,MAAMA,SAASC,IAAAA,qBAAU,EAC9B,UACA;IACEC,IAAIC,IAAAA,iBAAM,EAAC,MAAM;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGC,aAAa,GAAGC,UAAU;IAC/EC,OAAOC,IAAAA,kBAAO,EAAC,SAAS;QAAEC,QAAQ;IAAI,GAAGC,OAAO;IAChDC,MAAMH,IAAAA,kBAAO,EAAC,QAAQ;QAAEC,QAAQ;IAAI,GAAGC,OAAO;IAC9CE,aAAaJ,IAAAA,kBAAO,EAAC,eAAe;QAAEC,QAAQ;IAAI;IAClDI,SAASC,IAAAA,kBAAO,EAAC,WAAWC,OAAO,CAAC,MAAML,OAAO;IACjDM,cAAcd,IAAAA,iBAAM,EAAC,gBAAgB;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGW,OAAO,CAAC,GAAGL,OAAO;IAC3FO,cAAcf,IAAAA,iBAAM,EAAC,gBAAgB;QAAEC,MAAM;QAAUC,UAAU;IAAK;IACtEc,WAAWC,IAAAA,mBAAQ,EAAC,aAAa;QAAEhB,MAAM;IAAO,GAC7CY,OAAO,CAACK,IAAAA,eAAG,CAAA,CAAC,iBAAiB,CAAC,EAC9BV,OAAO;IACVW,YAAYF,IAAAA,mBAAQ,EAAC,cAAc;QAAEhB,MAAM;IAAO,GAAGY,OAAO,CAACK,IAAAA,eAAG,CAAA,CAAC,6CAA6C,CAAC;IAC/GE,YAAYH,IAAAA,mBAAQ,EAAC,cAAc;QAAEhB,MAAM;IAAO;AACpD,GACA,CAACoB,QAAU;QAACC,IAAAA,sBAAW,EAAC,aAAaC,EAAE,CAACF,MAAMhB,KAAK;KAAE;AAGhD,MAAMT,8BAA8B,CAAC4B,QAAaC,YAAYC,uBAAe,GAClFR,IAAAA,eAAG,CAAA,CAAC,gCAAgC,EAAEM,OAAO,aAAa,EAAEA,OAAO,aAAa,EAAEN,eAAG,CAACS,GAAG,CAAC,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/schemas/spaces.schema.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { SQL, sql } from 'drizzle-orm'\nimport { bigint, boolean, datetime, mysqlTable, uniqueIndex, varchar } from 'drizzle-orm/mysql-core'\nimport { SPACE_PERMS_SEP } from '../constants/spaces'\n\n/*\n alias: used to navigate over api & webdav, must be unique\n name: set by user and showed on web\n storageQuota:\n 0 : no storage\n null : unlimited\n other: limited to value\n*/\n\nexport const spaces = mysqlTable(\n 'spaces',\n {\n id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),\n alias: varchar('alias', { length: 255 }).notNull(),\n name: varchar('name', { length: 255 }).notNull(),\n description: varchar('description', { length: 255 }),\n enabled: boolean('enabled').default(true).notNull(),\n storageUsage: bigint('storageUsage', { mode: 'number', unsigned: true }).default(0).notNull(),\n storageQuota: bigint('storageQuota', { mode: 'number', unsigned: true }),\n storageIndexing: boolean('storageIndexing').default(true).notNull(),\n createdAt: datetime('createdAt', { mode: 'date' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n modifiedAt: datetime('modifiedAt', { mode: 'date' }).default(sql`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`),\n disabledAt: datetime('disabledAt', { mode: 'date' })\n },\n (table) => [uniqueIndex('alias_idx').on(table.alias)]\n)\n\nexport const spaceGroupConcatPermissions = (column: any, separator = SPACE_PERMS_SEP): SQL<string> =>\n sql`IFNULL(GROUP_CONCAT(DISTINCT(IF(${column} = '', null, ${column})) SEPARATOR ${sql.raw(`'${separator}'`)}), '')`\n"],"names":["spaceGroupConcatPermissions","spaces","mysqlTable","id","bigint","mode","unsigned","autoincrement","primaryKey","alias","varchar","length","notNull","name","description","enabled","boolean","default","storageUsage","storageQuota","storageIndexing","createdAt","datetime","sql","modifiedAt","disabledAt","table","uniqueIndex","on","column","separator","SPACE_PERMS_SEP","raw"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAmCYA;eAAAA;;QApBAC;eAAAA;;;4BAbY;2BACmD;wBAC5C;AAWzB,MAAMA,SAASC,IAAAA,qBAAU,EAC9B,UACA;IACEC,IAAIC,IAAAA,iBAAM,EAAC,MAAM;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGC,aAAa,GAAGC,UAAU;IAC/EC,OAAOC,IAAAA,kBAAO,EAAC,SAAS;QAAEC,QAAQ;IAAI,GAAGC,OAAO;IAChDC,MAAMH,IAAAA,kBAAO,EAAC,QAAQ;QAAEC,QAAQ;IAAI,GAAGC,OAAO;IAC9CE,aAAaJ,IAAAA,kBAAO,EAAC,eAAe;QAAEC,QAAQ;IAAI;IAClDI,SAASC,IAAAA,kBAAO,EAAC,WAAWC,OAAO,CAAC,MAAML,OAAO;IACjDM,cAAcd,IAAAA,iBAAM,EAAC,gBAAgB;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGW,OAAO,CAAC,GAAGL,OAAO;IAC3FO,cAAcf,IAAAA,iBAAM,EAAC,gBAAgB;QAAEC,MAAM;QAAUC,UAAU;IAAK;IACtEc,iBAAiBJ,IAAAA,kBAAO,EAAC,mBAAmBC,OAAO,CAAC,MAAML,OAAO;IACjES,WAAWC,IAAAA,mBAAQ,EAAC,aAAa;QAAEjB,MAAM;IAAO,GAC7CY,OAAO,CAACM,IAAAA,eAAG,CAAA,CAAC,iBAAiB,CAAC,EAC9BX,OAAO;IACVY,YAAYF,IAAAA,mBAAQ,EAAC,cAAc;QAAEjB,MAAM;IAAO,GAAGY,OAAO,CAACM,IAAAA,eAAG,CAAA,CAAC,6CAA6C,CAAC;IAC/GE,YAAYH,IAAAA,mBAAQ,EAAC,cAAc;QAAEjB,MAAM;IAAO;AACpD,GACA,CAACqB,QAAU;QAACC,IAAAA,sBAAW,EAAC,aAAaC,EAAE,CAACF,MAAMjB,KAAK;KAAE;AAGhD,MAAMT,8BAA8B,CAAC6B,QAAaC,YAAYC,uBAAe,GAClFR,IAAAA,eAAG,CAAA,CAAC,gCAAgC,EAAEM,OAAO,aAAa,EAAEA,OAAO,aAAa,EAAEN,eAAG,CAACS,GAAG,CAAC,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/services/spaces-browser.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, Injectable, Logger } from '@nestjs/common'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { configuration } from '../../../configuration/config.environment'\nimport { FileLock } from '../../files/interfaces/file-lock.interface'\nimport { FileProps } from '../../files/interfaces/file-props.interface'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { FilesRecents } from '../../files/services/files-recents.service'\nimport { dirName, fileName, getProps } from '../../files/utils/files'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { USER_PERMISSION } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { LOCK_SCOPE } from '../../webdav/constants/webdav'\nimport { SpaceFiles } from '../interfaces/space-files.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { realPathFromRootFile, IsRealPathIsDirAndExists } from '../utils/paths'\nimport { SpacesManager } from './spaces-manager.service'\nimport { SpacesQueries } from './spaces-queries.service'\n\n@Injectable()\nexport class SpacesBrowser {\n private readonly logger = new Logger(SpacesBrowser.name)\n\n constructor(\n private readonly spacesManager: SpacesManager,\n private readonly spacesQueries: SpacesQueries,\n private readonly sharesQueries: SharesQueries,\n private readonly filesQueries: FilesQueries,\n private readonly filesLockManager: FilesLockManager,\n private readonly filesRecents: FilesRecents\n ) {}\n\n async browse(\n user: UserModel,\n space: SpaceEnv,\n options: {\n withLocks?: boolean\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n } = {}\n ): Promise<SpaceFiles> {\n // check sync permission\n options.withSyncs = options.withSyncs && user.havePermission(USER_PERMISSION.DESKTOP_APP) && user.havePermission(USER_PERMISSION.DESKTOP_APP_SYNC)\n const spaceFiles: SpaceFiles = { files: [], hasRoots: false, permissions: space.browsePermissions() }\n const [fsFiles, dbFiles, rootFiles] = await Promise.all([\n this.parseFS(space),\n this.parseDB(user.id, space, options),\n this.parseRootFiles(user, space, {\n withShares: options.withSpacesAndShares,\n withHasComments: options.withHasComments,\n withSyncs: options.withSyncs\n })\n ])\n this.updateDBFiles(user, space, dbFiles, fsFiles, options)\n if (space.inSharesList) {\n // the share space includes shares as root files\n spaceFiles.files = [...rootFiles, ...fsFiles]\n spaceFiles.hasRoots = true\n } else {\n await this.mergeSpaceRootFiles(space, rootFiles, fsFiles, spaceFiles)\n }\n if (options.withLocks && !space.inTrashRepository) {\n // locks were removed when files were moved to the trash, no need to parse locks\n await this.enrichWithLocks(space, spaceFiles.files)\n }\n // update recents files\n this.filesRecents.updateRecents(user, space, spaceFiles.files).catch((e: Error) => this.logger.error(`${this.browse.name} - ${e}`))\n return spaceFiles\n }\n\n private async parseRootFiles(\n user: UserModel,\n space: SpaceEnv,\n options: {\n withShares?: boolean\n withHasComments?: boolean\n withSyncs?: boolean\n }\n ): Promise<FileProps[]> {\n if (space.inFilesRepository && space.id && !space.root.alias) {\n // list roots in the space\n return Promise.all((await this.spacesQueries.spaceRootFiles(user.id, space.id, options)).map((f) => this.updateRootFile(f, options)))\n } else if (space.inSharesList) {\n // list shares as roots\n return Promise.all((await this.sharesQueries.shareRootFiles(user, options)).map((f) => this.updateRootFile(f, options)))\n }\n return []\n }\n\n private async parseDB(\n userId: number,\n space: SpaceEnv,\n options: {\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n }\n ): Promise<FileProps[]> {\n if (space.inSharesList) return []\n const dbOptions = {\n withSpaces: options.withSpacesAndShares && space.inPersonalSpace,\n withShares: options.withSpacesAndShares,\n withSyncs: options.withSyncs,\n withHasComments: options.withHasComments,\n ignoreChildShares: !space.inSharesRepository\n }\n return this.filesQueries.browseFiles(userId, space.dbFile, dbOptions)\n }\n\n private async parseFS(space: SpaceEnv): Promise<FileProps[]> {\n if (space.inSharesList) return []\n const fsFiles: FileProps[] = []\n try {\n await IsRealPathIsDirAndExists(space.realPath)\n } catch (e) {\n this.logger.warn(`${this.parseFS.name} - ${space.realPath} : ${e.message}`)\n throw new HttpException(e.message, e.httpCode)\n }\n for await (const f of this.parsePath(space)) {\n fsFiles.push(f)\n }\n return fsFiles\n }\n\n private async *parsePath(space: SpaceEnv): AsyncGenerator<FileProps> {\n try {\n for (const element of await fs.readdir(space.realPath, { withFileTypes: true })) {\n const isDir = element.isDirectory()\n if (!isDir && !element.isFile()) {\n this.logger.log(`${this.parsePath.name} - ignore special file : ${element.name}`)\n continue\n }\n if (!configuration.applications.files.showHiddenFiles && element.name[0] === '.') {\n this.logger.verbose(`${this.parsePath.name} - ignore filtered file : ${element.name}`)\n continue\n }\n const realPath = path.join(space.realPath, element.name)\n const filePath = path.join(space.relativeUrl, element.name)\n try {\n yield await getProps(realPath, filePath, isDir)\n } catch (e) {\n this.logger.warn(`${this.parsePath.name} - unable get stats from ${realPath} : ${e}`)\n }\n }\n } catch (e) {\n this.logger.error(`${this.parsePath.name} - unable to parse ${space.realPath} : ${e}`)\n }\n }\n\n private async updateRootFile(f: FileProps, options: { withShares?: boolean; withHasComments?: boolean; withSyncs?: boolean }): Promise<FileProps> {\n // get realpath\n const realPath = realPathFromRootFile(f)\n f.path = f.root.name\n try {\n const fileProps: FileProps = await getProps(realPath, f.path)\n if (options.withShares) {\n fileProps.shares = f.shares\n }\n if (options.withHasComments) {\n fileProps.hasComments = f.hasComments\n }\n if (options.withSyncs) {\n fileProps.syncs = f.syncs\n }\n if (f.id) {\n // f.id is null for external roots\n // todo: check if a db file referenced under external roots have an id and correctly parsed here\n this.filesQueries.compareAndUpdateFileProps(f, fileProps).catch((e: Error) => this.logger.error(`${this.updateRootFile.name} - ${e}`))\n fileProps.id = f.id\n }\n fileProps.root = {\n id: f.root.id,\n alias: f.root.alias,\n description: f.root.description,\n enabled: typeof f.root.enabled === 'undefined' ? true : f.root.enabled,\n permissions: f.root.permissions,\n owner: f.root.owner\n }\n return fileProps\n } catch (e) {\n this.logger.error(`${this.updateRootFile.name} - ${JSON.stringify(f)} - ${e}`)\n return { ...f, name: fileName(f.path), path: dirName(f.path), ...{ root: { ...f.root, enabled: false } } }\n }\n }\n\n private updateDBFiles(\n user: UserModel,\n space: SpaceEnv,\n dbFiles: FileProps[],\n fsFiles: FileProps[],\n options: {\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n }\n ) {\n for (const dbFile of dbFiles) {\n const fsFile = fsFiles.find((f: FileProps) => dbFile.name === f.name)\n if (fsFile) {\n /* important: inherits from the file id in database */\n fsFile.id = dbFile.id\n if (options.withSpacesAndShares) {\n fsFile.spaces = dbFile.spaces\n fsFile.shares = dbFile.shares\n }\n if (options.withSyncs) {\n fsFile.syncs = dbFile.syncs\n }\n if (options.withHasComments) {\n fsFile.hasComments = dbFile.hasComments\n }\n this.filesQueries.compareAndUpdateFileProps(dbFile, fsFile).catch((e: Error) => this.logger.error(`${this.updateDBFiles.name} - ${e}`))\n } else {\n this.logger.warn(`${this.updateDBFiles.name} - missing ${dbFile.path}/${dbFile.name} (${dbFile.id}) from fs, delete it from db`)\n if (options.withSpacesAndShares) {\n if (dbFile.spaces) {\n for (const space of dbFile.spaces) {\n this.logger.warn(\n `${this.updateDBFiles.name} - ${dbFile.path}/${dbFile.name} (${dbFile.id}) will be removed from space : *${space.alias}* (${space.id})`\n )\n }\n }\n if (dbFile.shares) {\n for (const share of dbFile.shares) {\n this.logger.warn(\n `${this.updateDBFiles.name} - ${dbFile.path}/${dbFile.name} (${dbFile.id}) will be removed from share : *${share.alias}* (${share.id})`\n )\n }\n }\n }\n this.deleteDBFile(user, space, dbFile).catch((e: Error) => this.logger.error(`${this.updateDBFiles.name} - ${e}`))\n }\n }\n }\n\n private async deleteDBFile(user: UserModel, space: SpaceEnv, dbFile: FileProps) {\n const spaceEnv = await this.spacesManager.spaceEnv(user, path.join(space.url, dbFile.name).split('/'))\n this.filesQueries.deleteFiles(spaceEnv.dbFile, dbFile.isDir, true).catch((e: Error) => this.logger.error(`${this.deleteDBFile.name} - ${e}`))\n }\n\n private async mergeSpaceRootFiles(space: SpaceEnv, rootFiles: FileProps[], fsFiles: FileProps[], spaceFiles: SpaceFiles) {\n // merges root files in space files taking care of alias and name (file names must be unique)\n if (!rootFiles.length) {\n spaceFiles.files = fsFiles\n return\n }\n spaceFiles.hasRoots = true\n for (const f of rootFiles) {\n // check root alias (must be unique in the space)\n const newAlias: string = await this.spacesManager.uniqueRootAlias(\n space.id,\n f.root.alias,\n fsFiles.map((f) => f.name),\n true\n )\n if (newAlias) {\n this.logger.log(`${this.mergeSpaceRootFiles.name} - update space root alias (${f.root.id}) : ${f.root.alias} -> ${newAlias}`)\n // update in db\n this.spacesQueries\n .updateRoot({ alias: newAlias }, { id: f.root.id })\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // cleanup cache\n this.spacesQueries\n .clearCachePermissions(space.alias, [f.root.alias, newAlias])\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // assign\n f.root.alias = newAlias\n }\n // check root name (must be unique in the space)\n // f.name is equal to root name\n const newName: string = this.spacesManager.uniqueRootName(\n f.name,\n fsFiles.map((f) => f.name)\n )\n if (newName) {\n this.logger.log(`${this.mergeSpaceRootFiles.name} - update space root name (${f.root.id}) : ${f.name} -> ${newName}`)\n // update in db\n this.spacesQueries\n .updateRoot({ name: newName }, { id: f.root.id })\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // assign\n f.name = newName\n }\n }\n spaceFiles.files = [...fsFiles, ...rootFiles]\n }\n\n private async enrichWithLocks(space: SpaceEnv, files: FileProps[]) {\n if (space.inSharesList) {\n return\n }\n const locks: Record<string, FileLock> = await this.filesLockManager.browseParentChildLocks(space.dbFile, false)\n if (!Object.keys(locks).length) return\n for (const f of files.filter((f) => (f.root && f.root.alias in locks) || (!f.root && f.name in locks))) {\n const lock: FileLock = f.root ? locks[f.root.alias] : locks[f.name]\n f.lock = {\n owner: lock?.davLock?.owner || `${lock.owner.fullName} (${lock.owner.email})`,\n ownerLogin: lock.owner.login,\n isExclusive: lock?.davLock?.lockscope ? lock?.davLock?.lockscope === LOCK_SCOPE.EXCLUSIVE : true\n }\n }\n }\n}\n"],"names":["SpacesBrowser","browse","user","space","options","withSyncs","havePermission","USER_PERMISSION","DESKTOP_APP","DESKTOP_APP_SYNC","spaceFiles","files","hasRoots","permissions","browsePermissions","fsFiles","dbFiles","rootFiles","Promise","all","parseFS","parseDB","id","parseRootFiles","withShares","withSpacesAndShares","withHasComments","updateDBFiles","inSharesList","mergeSpaceRootFiles","withLocks","inTrashRepository","enrichWithLocks","filesRecents","updateRecents","catch","e","logger","error","name","inFilesRepository","root","alias","spacesQueries","spaceRootFiles","map","f","updateRootFile","sharesQueries","shareRootFiles","userId","dbOptions","withSpaces","inPersonalSpace","ignoreChildShares","inSharesRepository","filesQueries","browseFiles","dbFile","IsRealPathIsDirAndExists","realPath","warn","message","HttpException","httpCode","parsePath","push","element","fs","readdir","withFileTypes","isDir","isDirectory","isFile","log","configuration","applications","showHiddenFiles","verbose","path","join","filePath","relativeUrl","getProps","realPathFromRootFile","fileProps","shares","hasComments","syncs","compareAndUpdateFileProps","description","enabled","owner","JSON","stringify","fileName","dirName","fsFile","find","spaces","share","deleteDBFile","spaceEnv","spacesManager","url","split","deleteFiles","length","newAlias","uniqueRootAlias","updateRoot","clearCachePermissions","newName","uniqueRootName","locks","filesLockManager","browseParentChildLocks","Object","keys","filter","lock","davLock","fullName","email","ownerLogin","login","isExclusive","lockscope","LOCK_SCOPE","EXCLUSIVE","Logger"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/services/spaces-browser.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, Injectable, Logger } from '@nestjs/common'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { configuration } from '../../../configuration/config.environment'\nimport { FileLock } from '../../files/interfaces/file-lock.interface'\nimport { FileProps } from '../../files/interfaces/file-props.interface'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { FilesRecents } from '../../files/services/files-recents.service'\nimport { dirName, fileName, getProps } from '../../files/utils/files'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { USER_PERMISSION } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { LOCK_SCOPE } from '../../webdav/constants/webdav'\nimport { SpaceFiles } from '../interfaces/space-files.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { IsRealPathIsDirAndExists, realPathFromRootFile } from '../utils/paths'\nimport { SpacesManager } from './spaces-manager.service'\nimport { SpacesQueries } from './spaces-queries.service'\n\n@Injectable()\nexport class SpacesBrowser {\n private readonly logger = new Logger(SpacesBrowser.name)\n\n constructor(\n private readonly spacesManager: SpacesManager,\n private readonly spacesQueries: SpacesQueries,\n private readonly sharesQueries: SharesQueries,\n private readonly filesQueries: FilesQueries,\n private readonly filesLockManager: FilesLockManager,\n private readonly filesRecents: FilesRecents\n ) {}\n\n async browse(\n user: UserModel,\n space: SpaceEnv,\n options: {\n withLocks?: boolean\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n } = {}\n ): Promise<SpaceFiles> {\n // check sync permission\n options.withSyncs = options.withSyncs && user.havePermission(USER_PERMISSION.DESKTOP_APP) && user.havePermission(USER_PERMISSION.DESKTOP_APP_SYNC)\n const spaceFiles: SpaceFiles = { files: [], hasRoots: false, permissions: space.browsePermissions() }\n const [fsFiles, dbFiles, rootFiles] = await Promise.all([\n this.parseFS(space),\n this.parseDB(user.id, space, options),\n this.parseRootFiles(user, space, {\n withShares: options.withSpacesAndShares,\n withHasComments: options.withHasComments,\n withSyncs: options.withSyncs\n })\n ])\n this.updateDBFiles(user, space, dbFiles, fsFiles, options)\n if (space.inSharesList) {\n // the share space includes shares as root files\n spaceFiles.files = [...rootFiles, ...fsFiles]\n spaceFiles.hasRoots = true\n } else {\n await this.mergeSpaceRootFiles(space, rootFiles, fsFiles, spaceFiles)\n }\n if (options.withLocks && !space.inTrashRepository) {\n // locks were removed when files were moved to the trash, no need to parse locks\n await this.enrichWithLocks(space, spaceFiles.files)\n }\n // update recents files\n this.filesRecents.updateRecents(user, space, spaceFiles.files).catch((e: Error) => this.logger.error(`${this.browse.name} - ${e}`))\n return spaceFiles\n }\n\n private async parseRootFiles(\n user: UserModel,\n space: SpaceEnv,\n options: {\n withShares?: boolean\n withHasComments?: boolean\n withSyncs?: boolean\n }\n ): Promise<FileProps[]> {\n if (space.inFilesRepository && space.id && !space.root.alias) {\n // list roots in the space\n return Promise.all((await this.spacesQueries.spaceRootFiles(user.id, space.id, options)).map((f) => this.updateRootFile(f, options)))\n } else if (space.inSharesList) {\n // list shares as roots\n return Promise.all((await this.sharesQueries.shareRootFiles(user, options)).map((f) => this.updateRootFile(f, options)))\n }\n return []\n }\n\n private async parseDB(\n userId: number,\n space: SpaceEnv,\n options: {\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n }\n ): Promise<FileProps[]> {\n if (space.inSharesList) return []\n const dbOptions = {\n withSpaces: options.withSpacesAndShares && space.inPersonalSpace,\n withShares: options.withSpacesAndShares,\n withSyncs: options.withSyncs,\n withHasComments: options.withHasComments,\n ignoreChildShares: !space.inSharesRepository\n }\n return this.filesQueries.browseFiles(userId, space.dbFile, dbOptions)\n }\n\n private async parseFS(space: SpaceEnv): Promise<FileProps[]> {\n if (space.inSharesList) return []\n const fsFiles: FileProps[] = []\n try {\n await IsRealPathIsDirAndExists(space.realPath)\n } catch (e) {\n this.logger.warn(`${this.parseFS.name} - ${space.realPath} : ${e.message}`)\n throw new HttpException(e.message, e.httpCode)\n }\n for await (const f of this.parsePath(space)) {\n fsFiles.push(f)\n }\n return fsFiles\n }\n\n private async *parsePath(space: SpaceEnv): AsyncGenerator<FileProps> {\n try {\n for (const element of await fs.readdir(space.realPath, { withFileTypes: true })) {\n const isDir = element.isDirectory()\n if (!isDir && !element.isFile()) {\n this.logger.log(`${this.parsePath.name} - ignore special file : ${element.name}`)\n continue\n }\n if (!configuration.applications.files.showHiddenFiles && element.name[0] === '.') {\n this.logger.verbose(`${this.parsePath.name} - ignore filtered file : ${element.name}`)\n continue\n }\n const realPath = path.join(space.realPath, element.name)\n const filePath = path.join(space.relativeUrl, element.name)\n try {\n yield await getProps(realPath, filePath, isDir)\n } catch (e) {\n this.logger.warn(`${this.parsePath.name} - unable get stats from ${realPath} : ${e}`)\n }\n }\n } catch (e) {\n this.logger.error(`${this.parsePath.name} - unable to parse ${space.realPath} : ${e}`)\n }\n }\n\n private async updateRootFile(f: FileProps, options: { withShares?: boolean; withHasComments?: boolean; withSyncs?: boolean }): Promise<FileProps> {\n // get realpath\n const realPath = realPathFromRootFile(f)\n f.path = f.root.name\n try {\n const fileProps: FileProps = await getProps(realPath, f.path)\n if (options.withShares) {\n fileProps.shares = f.shares\n }\n if (options.withHasComments) {\n fileProps.hasComments = f.hasComments\n }\n if (options.withSyncs) {\n fileProps.syncs = f.syncs\n }\n if (f.id) {\n // f.id is null for external roots\n // todo: check if a db file referenced under external roots have an id and correctly parsed here\n this.filesQueries.compareAndUpdateFileProps(f, fileProps).catch((e: Error) => this.logger.error(`${this.updateRootFile.name} - ${e}`))\n fileProps.id = f.id\n }\n fileProps.root = {\n id: f.root.id,\n alias: f.root.alias,\n description: f.root.description,\n enabled: typeof f.root.enabled === 'undefined' ? true : f.root.enabled,\n permissions: f.root.permissions,\n owner: f.root.owner\n }\n return fileProps\n } catch (e) {\n this.logger.error(`${this.updateRootFile.name} - ${JSON.stringify(f)} - ${e}`)\n return { ...f, name: fileName(f.path), path: dirName(f.path), ...{ root: { ...f.root, enabled: false } } }\n }\n }\n\n private updateDBFiles(\n user: UserModel,\n space: SpaceEnv,\n dbFiles: FileProps[],\n fsFiles: FileProps[],\n options: {\n withSpacesAndShares?: boolean\n withSyncs?: boolean\n withHasComments?: boolean\n }\n ) {\n for (const dbFile of dbFiles) {\n const fsFile = fsFiles.find((f: FileProps) => dbFile.name === f.name)\n if (fsFile) {\n /* important: inherits from the file id in database */\n fsFile.id = dbFile.id\n if (options.withSpacesAndShares) {\n fsFile.spaces = dbFile.spaces\n fsFile.shares = dbFile.shares\n }\n if (options.withSyncs) {\n fsFile.syncs = dbFile.syncs\n }\n if (options.withHasComments) {\n fsFile.hasComments = dbFile.hasComments\n }\n this.filesQueries.compareAndUpdateFileProps(dbFile, fsFile).catch((e: Error) => this.logger.error(`${this.updateDBFiles.name} - ${e}`))\n } else {\n this.logger.warn(`${this.updateDBFiles.name} - missing ${dbFile.path}/${dbFile.name} (${dbFile.id}) from fs, delete it from db`)\n if (options.withSpacesAndShares) {\n if (dbFile.spaces) {\n for (const space of dbFile.spaces) {\n this.logger.warn(\n `${this.updateDBFiles.name} - ${dbFile.path}/${dbFile.name} (${dbFile.id}) will be removed from space : *${space.alias}* (${space.id})`\n )\n }\n }\n if (dbFile.shares) {\n for (const share of dbFile.shares) {\n this.logger.warn(\n `${this.updateDBFiles.name} - ${dbFile.path}/${dbFile.name} (${dbFile.id}) will be removed from share : *${share.alias}* (${share.id})`\n )\n }\n }\n }\n this.deleteDBFile(user, space, dbFile).catch((e: Error) => this.logger.error(`${this.updateDBFiles.name} - ${e}`))\n }\n }\n }\n\n private async deleteDBFile(user: UserModel, space: SpaceEnv, dbFile: FileProps) {\n const spaceEnv = await this.spacesManager.spaceEnv(user, path.join(space.url, dbFile.name).split('/'))\n this.filesQueries.deleteFiles(spaceEnv.dbFile, dbFile.isDir, true).catch((e: Error) => this.logger.error(`${this.deleteDBFile.name} - ${e}`))\n }\n\n private async mergeSpaceRootFiles(space: SpaceEnv, rootFiles: FileProps[], fsFiles: FileProps[], spaceFiles: SpaceFiles) {\n // merges root files in space files taking care of alias and name (file names must be unique)\n if (!rootFiles.length) {\n spaceFiles.files = fsFiles\n return\n }\n spaceFiles.hasRoots = true\n for (const f of rootFiles) {\n // check root alias (must be unique in the space)\n const newAlias: string = await this.spacesManager.uniqueRootAlias(\n space.id,\n f.root.alias,\n fsFiles.map((f) => f.name),\n true\n )\n if (newAlias) {\n this.logger.log(`${this.mergeSpaceRootFiles.name} - update space root alias (${f.root.id}) : ${f.root.alias} -> ${newAlias}`)\n // update in db\n this.spacesQueries\n .updateRoot({ alias: newAlias }, { id: f.root.id })\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // cleanup cache\n this.spacesQueries\n .clearCachePermissions(space.alias, [f.root.alias, newAlias])\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // assign\n f.root.alias = newAlias\n }\n // check root name (must be unique in the space)\n // f.name is equal to root name\n const newName: string = this.spacesManager.uniqueRootName(\n f.name,\n fsFiles.map((f) => f.name)\n )\n if (newName) {\n this.logger.log(`${this.mergeSpaceRootFiles.name} - update space root name (${f.root.id}) : ${f.name} -> ${newName}`)\n // update in db\n this.spacesQueries\n .updateRoot({ name: newName }, { id: f.root.id })\n .catch((e: Error) => this.logger.error(`${this.mergeSpaceRootFiles.name} - ${e}`))\n // assign\n f.name = newName\n }\n }\n spaceFiles.files = [...fsFiles, ...rootFiles]\n }\n\n private async enrichWithLocks(space: SpaceEnv, files: FileProps[]) {\n if (space.inSharesList) {\n return\n }\n const locks: Record<string, FileLock> = await this.filesLockManager.browseParentChildLocks(space.dbFile, false)\n if (!Object.keys(locks).length) return\n for (const f of files.filter((f) => (f.root && f.root.alias in locks) || (!f.root && f.name in locks))) {\n const lock: FileLock = f.root ? locks[f.root.alias] : locks[f.name]\n f.lock = {\n owner: lock?.davLock?.owner || `${lock.owner.fullName} (${lock.owner.email})`,\n ownerLogin: lock.owner.login,\n isExclusive: lock?.davLock?.lockscope ? lock?.davLock?.lockscope === LOCK_SCOPE.EXCLUSIVE : true\n }\n }\n }\n}\n"],"names":["SpacesBrowser","browse","user","space","options","withSyncs","havePermission","USER_PERMISSION","DESKTOP_APP","DESKTOP_APP_SYNC","spaceFiles","files","hasRoots","permissions","browsePermissions","fsFiles","dbFiles","rootFiles","Promise","all","parseFS","parseDB","id","parseRootFiles","withShares","withSpacesAndShares","withHasComments","updateDBFiles","inSharesList","mergeSpaceRootFiles","withLocks","inTrashRepository","enrichWithLocks","filesRecents","updateRecents","catch","e","logger","error","name","inFilesRepository","root","alias","spacesQueries","spaceRootFiles","map","f","updateRootFile","sharesQueries","shareRootFiles","userId","dbOptions","withSpaces","inPersonalSpace","ignoreChildShares","inSharesRepository","filesQueries","browseFiles","dbFile","IsRealPathIsDirAndExists","realPath","warn","message","HttpException","httpCode","parsePath","push","element","fs","readdir","withFileTypes","isDir","isDirectory","isFile","log","configuration","applications","showHiddenFiles","verbose","path","join","filePath","relativeUrl","getProps","realPathFromRootFile","fileProps","shares","hasComments","syncs","compareAndUpdateFileProps","description","enabled","owner","JSON","stringify","fileName","dirName","fsFile","find","spaces","share","deleteDBFile","spaceEnv","spacesManager","url","split","deleteFiles","length","newAlias","uniqueRootAlias","updateRoot","clearCachePermissions","newName","uniqueRootName","locks","filesLockManager","browseParentChildLocks","Object","keys","filter","lock","davLock","fullName","email","ownerLogin","login","isExclusive","lockscope","LOCK_SCOPE","EXCLUSIVE","Logger"],"mappings":"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"}
@@ -20,7 +20,6 @@ const _constants = require("../../../common/constants");
20
20
  const _functions = require("../../../common/functions");
21
21
  const _shared = require("../../../common/shared");
22
22
  const _configenvironment = require("../../../configuration/config.environment");
23
- const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
24
23
  const _contextmanagerservice = require("../../../infrastructure/context/services/context-manager.service");
25
24
  const _fileerror = require("../../files/models/file-error");
26
25
  const _files = require("../../files/utils/files");
@@ -191,6 +190,7 @@ let SpacesManager = class SpacesManager {
191
190
  description: createOrUpdateSpaceDto.description,
192
191
  enabled: createOrUpdateSpaceDto.enabled,
193
192
  storageQuota: createOrUpdateSpaceDto.storageQuota,
193
+ storageIndexing: createOrUpdateSpaceDto.storageIndexing,
194
194
  disabledAt: createOrUpdateSpaceDto.enabled ? null : new Date()
195
195
  });
196
196
  try {
@@ -211,16 +211,18 @@ let SpacesManager = class SpacesManager {
211
211
  }
212
212
  async updateSpace(user, spaceId, createOrUpdateSpaceDto) {
213
213
  /* only managers of the space can update it */ const space = await this.userCanAccessSpace(user.id, spaceId, true);
214
- // check & update space info
214
+ // check and update space info
215
215
  const spaceDiffProps = {
216
216
  modifiedAt: new Date()
217
217
  };
218
- for (const prop of [
218
+ const props = [
219
219
  'name',
220
220
  'description',
221
221
  'enabled',
222
- 'storageQuota'
223
- ]){
222
+ 'storageQuota',
223
+ 'storageIndexing'
224
+ ];
225
+ for (const prop of props){
224
226
  if (createOrUpdateSpaceDto[prop] !== space[prop]) {
225
227
  spaceDiffProps[prop] = createOrUpdateSpaceDto[prop];
226
228
  if (prop === 'name') {
@@ -330,12 +332,13 @@ let SpacesManager = class SpacesManager {
330
332
  return null;
331
333
  }
332
334
  async updatePersonalSpacesQuota(forUser) {
333
- for (const user of (await this.usersQueries.selectUsers([
335
+ const props = [
334
336
  'id',
335
337
  'login',
336
338
  'storageUsage',
337
339
  'storageQuota'
338
- ], [
340
+ ];
341
+ for (const user of (await this.usersQueries.selectUsers(props, [
339
342
  (0, _drizzleorm.lte)(_usersschema.users.role, _user.USER_ROLE.USER),
340
343
  ...forUser ? [
341
344
  (0, _drizzleorm.eq)(_usersschema.users.id, forUser.id)
@@ -354,7 +357,7 @@ let SpacesManager = class SpacesManager {
354
357
  storageUsage: size,
355
358
  storageQuota: user.storageQuota
356
359
  };
357
- this.cache.set(`${_cache.CACHE_QUOTA_USER_PREFIX}-${user.id}`, spaceQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updatePersonalSpacesQuota.name} - ${e}`));
360
+ this.spacesQueries.cache.set(`${_cache.CACHE_QUOTA_USER_PREFIX}-${user.id}`, spaceQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updatePersonalSpacesQuota.name} - ${e}`));
358
361
  if (user.storageUsage !== spaceQuota.storageUsage) {
359
362
  this.logger.log(`${this.updatePersonalSpacesQuota.name} - user *${user.login}* (${user.id}) : storage usage updated : ${spaceQuota.storageUsage}`);
360
363
  await this.usersQueries.updateUserOrGuest(user.id, {
@@ -364,30 +367,28 @@ let SpacesManager = class SpacesManager {
364
367
  }
365
368
  }
366
369
  async updateSpacesQuota(spaceId) {
367
- for (const space of (await this.spacesQueries.selectSpaces([
368
- 'id',
369
- 'alias',
370
- 'storageUsage',
371
- 'storageQuota'
372
- ], [
373
- ...spaceId ? [
374
- (0, _drizzleorm.eq)(_spacesschema.spaces.id, spaceId)
375
- ] : []
376
- ]))){
370
+ for (const space of (await this.spacesQueries.spacesQuotaPaths(spaceId))){
377
371
  const spacePath = _spacemodel.SpaceModel.getHomePath(space.alias);
378
372
  if (!await (0, _files.isPathExists)(spacePath)) {
379
373
  this.logger.warn(`${this.updateSpacesQuota.name} - *${space.alias}* home path does not exist`);
380
374
  continue;
381
375
  }
382
- const [size, errors] = await (0, _files.dirSize)(spacePath);
383
- for (const [path, error] of Object.entries(errors)){
384
- this.logger.warn(`${this.updateSpacesQuota.name} - unable to get size for *${space.alias}* on ${path} : ${error}`);
376
+ let size = 0;
377
+ for (const rPath of [
378
+ spacePath,
379
+ ...space.externalPaths.filter(Boolean)
380
+ ]){
381
+ const [rPathSize, errors] = await (0, _files.dirSize)(rPath);
382
+ size += rPathSize;
383
+ for (const [path, error] of Object.entries(errors)){
384
+ this.logger.warn(`${this.updateSpacesQuota.name} - unable to get size for *${space.alias}* on ${path} : ${error}`);
385
+ }
385
386
  }
386
387
  const spaceQuota = {
387
388
  storageUsage: size,
388
389
  storageQuota: space.storageQuota
389
390
  };
390
- this.cache.set(`${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.id}`, spaceQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updateSpacesQuota.name} - ${e}`));
391
+ this.spacesQueries.cache.set(`${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.id}`, spaceQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updateSpacesQuota.name} - ${e}`));
391
392
  if (space.storageUsage !== spaceQuota.storageUsage) {
392
393
  this.logger.log(`${this.updateSpacesQuota.name} - space *${space.alias}* (${space.id}) : storage usage updated : ${spaceQuota.storageUsage}`);
393
394
  await this.spacesQueries.updateSpace(space.id, {
@@ -397,12 +398,13 @@ let SpacesManager = class SpacesManager {
397
398
  }
398
399
  }
399
400
  async deleteExpiredSpaces() {
400
- /* Removes spaces that have been disabled for more than 30 days */ for (const space of (await this.spacesQueries.selectSpaces([
401
+ /* Removes spaces that have been disabled for more than 30 days */ const props = [
401
402
  'id',
402
403
  'name',
403
404
  'alias',
404
405
  'disabledAt'
405
- ], [
406
+ ];
407
+ for (const space of (await this.spacesQueries.selectSpaces(props, [
406
408
  (0, _drizzleorm.eq)(_spacesschema.spaces.enabled, false),
407
409
  (0, _drizzleorm.isNotNull)(_spacesschema.spaces.disabledAt)
408
410
  ]))){
@@ -625,7 +627,7 @@ let SpacesManager = class SpacesManager {
625
627
  }
626
628
  await this.spacesQueries.deleteSpace(space.id, deleteNow);
627
629
  if (deleteNow) {
628
- this.cache.del(`${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.id}`).catch((e)=>this.logger.error(`${this.deleteOrDisableSpace.name} - ${e}`));
630
+ this.spacesQueries.cache.del(`${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.id}`).catch((e)=>this.logger.error(`${this.deleteOrDisableSpace.name} - ${e}`));
629
631
  await this.deleteSpaceLocation(space.alias);
630
632
  }
631
633
  }
@@ -701,7 +703,7 @@ let SpacesManager = class SpacesManager {
701
703
  return true;
702
704
  }
703
705
  async setQuotaExceeded(user, space) {
704
- /* extract quota from spaces|shares|roots */ if (space.inSharesList || space.inSharesRepository && space.root?.externalPath) {
706
+ /* extract quota from spaces|shares|roots */ if (space.inSharesList) {
705
707
  return;
706
708
  }
707
709
  const cacheQuotaKey = (0, _paths.quotaKeyFromSpace)(user.id, space);
@@ -709,15 +711,18 @@ let SpacesManager = class SpacesManager {
709
711
  this.logger.verbose(`${this.setQuotaExceeded.name} - quota was ignored for space : *${space.alias}* (${space.id})`);
710
712
  return;
711
713
  }
712
- let quota = await this.cache.get(cacheQuotaKey);
714
+ let quota = await this.spacesQueries.cache.get(cacheQuotaKey);
713
715
  if (!quota) {
714
716
  // the quota scheduler has not started yet or the cache has been cleared
715
717
  if (space.inPersonalSpace) {
716
718
  await this.updatePersonalSpacesQuota(user);
719
+ } else if (space.inSharesRepository) {
720
+ // Shares with external paths
721
+ await this.sharesManager.updateSharesExternalPathQuota(space.id);
717
722
  } else {
718
723
  await this.updateSpacesQuota(space.id);
719
724
  }
720
- quota = await this.cache.get(cacheQuotaKey);
725
+ quota = await this.spacesQueries.cache.get(cacheQuotaKey);
721
726
  }
722
727
  if (quota) {
723
728
  space.storageUsage = quota.storageUsage;
@@ -792,9 +797,8 @@ let SpacesManager = class SpacesManager {
792
797
  }
793
798
  }
794
799
  }
795
- constructor(contextManager, cache, spacesQueries, usersQueries, sharesManager, notificationsManager){
800
+ constructor(contextManager, spacesQueries, usersQueries, sharesManager, notificationsManager){
796
801
  this.contextManager = contextManager;
797
- this.cache = cache;
798
802
  this.spacesQueries = spacesQueries;
799
803
  this.usersQueries = usersQueries;
800
804
  this.sharesManager = sharesManager;
@@ -807,7 +811,6 @@ SpacesManager = _ts_decorate([
807
811
  _ts_metadata("design:type", Function),
808
812
  _ts_metadata("design:paramtypes", [
809
813
  typeof _contextmanagerservice.ContextManager === "undefined" ? Object : _contextmanagerservice.ContextManager,
810
- typeof _cacheservice.Cache === "undefined" ? Object : _cacheservice.Cache,
811
814
  typeof _spacesqueriesservice.SpacesQueries === "undefined" ? Object : _spacesqueriesservice.SpacesQueries,
812
815
  typeof _usersqueriesservice.UsersQueries === "undefined" ? Object : _usersqueriesservice.UsersQueries,
813
816
  typeof _sharesmanagerservice.SharesManager === "undefined" ? Object : _sharesmanagerservice.SharesManager,