@sync-in/server 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/CHANGELOG.md +164 -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 +16 -15
  7. package/server/app.bootstrap.js +1 -0
  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/services/files-content-manager.service.js +6 -6
  18. package/server/applications/files/services/files-content-manager.service.js.map +1 -1
  19. package/server/applications/files/services/files-manager.service.js +4 -4
  20. package/server/applications/files/services/files-manager.service.js.map +1 -1
  21. package/server/applications/files/services/files-methods.service.js +5 -3
  22. package/server/applications/files/services/files-methods.service.js.map +1 -1
  23. package/server/applications/files/services/files-only-office-manager.service.js +2 -2
  24. package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
  25. package/server/applications/files/services/files-parser.service.js +6 -3
  26. package/server/applications/files/services/files-parser.service.js.map +1 -1
  27. package/server/applications/files/services/files-scheduler.service.js +51 -3
  28. package/server/applications/files/services/files-scheduler.service.js.map +1 -1
  29. package/server/applications/files/services/files-search-manager.service.js +4 -0
  30. package/server/applications/files/services/files-search-manager.service.js.map +1 -1
  31. package/server/applications/files/utils/doc-textify/adapters/pdf.js +10 -1
  32. package/server/applications/files/utils/doc-textify/adapters/pdf.js.map +1 -1
  33. package/server/applications/notifications/i18n/de.js +56 -0
  34. package/server/applications/notifications/i18n/de.js.map +1 -0
  35. package/server/applications/notifications/i18n/es.js +52 -0
  36. package/server/applications/notifications/i18n/es.js.map +1 -0
  37. package/server/applications/notifications/i18n/hi.js +52 -0
  38. package/server/applications/notifications/i18n/hi.js.map +1 -0
  39. package/server/applications/notifications/i18n/index.js +73 -8
  40. package/server/applications/notifications/i18n/index.js.map +1 -1
  41. package/server/applications/notifications/i18n/it.js +52 -0
  42. package/server/applications/notifications/i18n/it.js.map +1 -0
  43. package/server/applications/notifications/i18n/ja.js +52 -0
  44. package/server/applications/notifications/i18n/ja.js.map +1 -0
  45. package/server/applications/notifications/i18n/ko.js +52 -0
  46. package/server/applications/notifications/i18n/ko.js.map +1 -0
  47. package/server/applications/notifications/i18n/pl.js +52 -0
  48. package/server/applications/notifications/i18n/pl.js.map +1 -0
  49. package/server/applications/notifications/i18n/pt.js +52 -0
  50. package/server/applications/notifications/i18n/pt.js.map +1 -0
  51. package/server/applications/notifications/i18n/pt_br.js +52 -0
  52. package/server/applications/notifications/i18n/pt_br.js.map +1 -0
  53. package/server/applications/notifications/i18n/ru.js +52 -0
  54. package/server/applications/notifications/i18n/ru.js.map +1 -0
  55. package/server/applications/notifications/i18n/tr.js +52 -0
  56. package/server/applications/notifications/i18n/tr.js.map +1 -0
  57. package/server/applications/notifications/i18n/zh.js +52 -0
  58. package/server/applications/notifications/i18n/zh.js.map +1 -0
  59. package/server/applications/notifications/mails/models.js +6 -7
  60. package/server/applications/notifications/mails/models.js.map +1 -1
  61. package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
  62. package/server/applications/shares/dto/create-or-update-share.dto.js +11 -0
  63. package/server/applications/shares/dto/create-or-update-share.dto.js.map +1 -1
  64. package/server/applications/shares/interfaces/share-props.interface.js.map +1 -1
  65. package/server/applications/shares/schemas/share.interface.js.map +1 -1
  66. package/server/applications/shares/schemas/shares.schema.js +9 -0
  67. package/server/applications/shares/schemas/shares.schema.js.map +1 -1
  68. package/server/applications/shares/services/shares-manager.service.js +46 -17
  69. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  70. package/server/applications/shares/services/shares-queries.service.js +24 -5
  71. package/server/applications/shares/services/shares-queries.service.js.map +1 -1
  72. package/server/applications/spaces/constants/cache.js +4 -0
  73. package/server/applications/spaces/constants/cache.js.map +1 -1
  74. package/server/applications/spaces/dto/create-or-update-space.dto.js +5 -0
  75. package/server/applications/spaces/dto/create-or-update-space.dto.js.map +1 -1
  76. package/server/applications/spaces/guards/space.guard.js +3 -3
  77. package/server/applications/spaces/guards/space.guard.js.map +1 -1
  78. package/server/applications/spaces/models/space-props.model.js.map +1 -1
  79. package/server/applications/spaces/models/space.model.js.map +1 -1
  80. package/server/applications/spaces/schemas/space.interface.js.map +1 -1
  81. package/server/applications/spaces/schemas/spaces.schema.js +1 -0
  82. package/server/applications/spaces/schemas/spaces.schema.js.map +1 -1
  83. package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
  84. package/server/applications/spaces/services/spaces-manager.service.js +34 -31
  85. package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
  86. package/server/applications/spaces/services/spaces-queries.service.js +23 -7
  87. package/server/applications/spaces/services/spaces-queries.service.js.map +1 -1
  88. package/server/applications/spaces/services/spaces-scheduler.service.js +21 -20
  89. package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
  90. package/server/applications/spaces/spaces.controller.js +4 -2
  91. package/server/applications/spaces/spaces.controller.js.map +1 -1
  92. package/server/applications/spaces/utils/paths.js +14 -16
  93. package/server/applications/spaces/utils/paths.js.map +1 -1
  94. package/server/applications/sync/services/sync-manager.service.js +4 -3
  95. package/server/applications/sync/services/sync-manager.service.js.map +1 -1
  96. package/server/applications/sync/services/sync-paths-manager.service.js +1 -1
  97. package/server/applications/sync/services/sync-paths-manager.service.js.map +1 -1
  98. package/server/applications/sync/services/sync-paths-manager.service.spec.js +1 -1
  99. package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
  100. package/server/applications/sync/sync.controller.js +2 -1
  101. package/server/applications/sync/sync.controller.js.map +1 -1
  102. package/server/applications/users/constants/routes.js +5 -0
  103. package/server/applications/users/constants/routes.js.map +1 -1
  104. package/server/applications/users/constants/user.js +0 -16
  105. package/server/applications/users/constants/user.js.map +1 -1
  106. package/server/applications/users/dto/user-properties.dto.js +10 -0
  107. package/server/applications/users/dto/user-properties.dto.js.map +1 -1
  108. package/server/applications/users/models/user.model.js.map +1 -1
  109. package/server/applications/users/schemas/user.interface.js.map +1 -1
  110. package/server/applications/users/schemas/users.schema.js +3 -2
  111. package/server/applications/users/schemas/users.schema.js.map +1 -1
  112. package/server/applications/users/services/admin-users-manager.service.js +1 -0
  113. package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
  114. package/server/applications/users/services/admin-users-manager.service.spec.js +2 -1
  115. package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
  116. package/server/applications/users/services/users-manager.service.js +8 -2
  117. package/server/applications/users/services/users-manager.service.js.map +1 -1
  118. package/server/applications/users/services/users-manager.service.spec.js +1 -0
  119. package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
  120. package/server/applications/users/services/users-queries.service.js +18 -4
  121. package/server/applications/users/services/users-queries.service.js.map +1 -1
  122. package/server/applications/users/users.controller.js +15 -0
  123. package/server/applications/users/users.controller.js.map +1 -1
  124. package/server/applications/users/utils/test.js +2 -2
  125. package/server/applications/users/utils/test.js.map +1 -1
  126. package/server/applications/webdav/constants/routes.js +2 -2
  127. package/server/applications/webdav/constants/routes.js.map +1 -1
  128. package/server/applications/webdav/constants/webdav.js +2 -2
  129. package/server/applications/webdav/constants/webdav.js.map +1 -1
  130. package/server/applications/webdav/filters/webdav.filter.js +2 -2
  131. package/server/applications/webdav/filters/webdav.filter.js.map +1 -1
  132. package/server/applications/webdav/filters/webdav.filter.spec.js +2 -2
  133. package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -1
  134. package/server/applications/webdav/services/webdav-methods.service.js +3 -2
  135. package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
  136. package/server/applications/webdav/utils/webdav.js +1 -2
  137. package/server/applications/webdav/utils/webdav.js.map +1 -1
  138. package/server/authentication/auth.config.js +2 -2
  139. package/server/authentication/auth.config.js.map +1 -1
  140. package/server/authentication/guards/auth-basic.strategy.js +2 -2
  141. package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
  142. package/server/common/i18n.js +52 -0
  143. package/server/common/i18n.js.map +1 -0
  144. package/server/common/image.js +49 -33
  145. package/server/common/image.js.map +1 -1
  146. package/server/common/interfaces.js.map +1 -1
  147. package/server/common/shared.js +5 -2
  148. package/server/common/shared.js.map +1 -1
  149. package/server/configuration/config.validation.js +3 -3
  150. package/server/configuration/config.validation.js.map +1 -1
  151. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +8 -6
  152. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
  153. package/server/infrastructure/cache/adapters/redis-cache.adapter.js +22 -17
  154. package/server/infrastructure/cache/adapters/redis-cache.adapter.js.map +1 -1
  155. package/server/infrastructure/cache/cache.e2e-spec.js +1 -0
  156. package/server/infrastructure/cache/cache.e2e-spec.js.map +1 -1
  157. package/server/infrastructure/cache/cache.module.js +1 -14
  158. package/server/infrastructure/cache/cache.module.js.map +1 -1
  159. package/server/infrastructure/cache/services/cache.service.js.map +1 -1
  160. package/server/infrastructure/database/database.module.js +20 -1
  161. package/server/infrastructure/database/database.module.js.map +1 -1
  162. package/server/infrastructure/database/utils.js +48 -0
  163. package/server/infrastructure/database/utils.js.map +1 -1
  164. package/server/infrastructure/scheduler/scheduler.module.js +1 -1
  165. package/server/infrastructure/scheduler/scheduler.module.js.map +1 -1
  166. package/server/infrastructure/websocket/adapters/cluster.adapter.js +1 -3
  167. package/server/infrastructure/websocket/adapters/cluster.adapter.js.map +1 -1
  168. package/static/3rdpartylicenses.txt +137 -137
  169. package/static/chunk-2KLC4T2Z.js +1 -0
  170. package/static/chunk-373XVRXW.js +1 -0
  171. package/static/chunk-3GMLWAFZ.js +1 -0
  172. package/static/chunk-3XVM35O2.js +1 -0
  173. package/static/chunk-3YVRP3VM.js +2 -0
  174. package/static/chunk-5NMSIIQB.js +1 -0
  175. package/static/chunk-AF24EYXU.js +1 -0
  176. package/static/chunk-AKQVEHO6.js +2 -0
  177. package/static/{chunk-PTGDOWV3.js → chunk-AY2SZ3G6.js} +1 -1
  178. package/static/chunk-BCVX464U.js +2 -0
  179. package/static/{chunk-IPAC4VAF.js → chunk-BIKLW4YS.js} +1 -1
  180. package/static/chunk-C36MW4ME.js +562 -0
  181. package/static/chunk-CHJ64RJM.js +1 -0
  182. package/static/chunk-DKSEQTMX.js +1 -0
  183. package/static/chunk-DM4NXKEP.js +1 -0
  184. package/static/chunk-DPUVSXRB.js +1 -0
  185. package/static/chunk-DSWEWLXJ.js +1 -0
  186. package/static/chunk-FJE6BOFL.js +1 -0
  187. package/static/chunk-FZ3JPGYZ.js +1 -0
  188. package/static/chunk-GUGNR5TF.js +3 -0
  189. package/static/chunk-H6NE33VX.js +1 -0
  190. package/static/{chunk-DJYJ66UF.js → chunk-HAS5ZOTR.js} +1 -1
  191. package/static/chunk-HNQRZALS.js +1 -0
  192. package/static/chunk-JPT5WEAT.js +1 -0
  193. package/static/{chunk-QNJFQVYI.js → chunk-JSWCNGXJ.js} +1 -1
  194. package/static/chunk-KFJIQIGR.js +1 -0
  195. package/static/chunk-LNTUR3GU.js +1 -0
  196. package/static/chunk-LVM4QB22.js +1 -0
  197. package/static/chunk-M3XVNQZQ.js +1 -0
  198. package/static/{chunk-EVIE5F2U.js → chunk-MFLIJH6T.js} +1 -1
  199. package/static/{chunk-IQOALFYU.js → chunk-MSUHTBB2.js} +1 -1
  200. package/static/chunk-N3U6637P.js +1 -0
  201. package/static/chunk-NNV4OXSB.js +1 -0
  202. package/static/chunk-NO2LTNW3.js +1 -0
  203. package/static/chunk-OOGP4WSH.js +2 -0
  204. package/static/chunk-PB4AIT7O.js +1 -0
  205. package/static/chunk-PCWDQPOM.js +2 -0
  206. package/static/chunk-PGZZP5W3.js +1 -0
  207. package/static/chunk-PVDHBQRM.js +1 -0
  208. package/static/chunk-Q5KM7LTX.js +1 -0
  209. package/static/chunk-QHC6ZPQ4.js +1 -0
  210. package/static/chunk-QO6BTONN.js +1 -0
  211. package/static/chunk-QZU2S5CV.js +1 -0
  212. package/static/chunk-SBZ572Q4.js +2 -0
  213. package/static/chunk-SHIVUDP3.js +1 -0
  214. package/static/chunk-SLHTEGRU.js +1 -0
  215. package/static/{chunk-SH5EVL4E.js → chunk-SSFF27P2.js} +1 -1
  216. package/static/chunk-TPYBFZS5.js +1 -0
  217. package/static/chunk-UEQCWMXD.js +1 -0
  218. package/static/chunk-UG5DMXYO.js +1 -0
  219. package/static/chunk-UJPPR4MX.js +1 -0
  220. package/static/chunk-UNCPXHHT.js +1 -0
  221. package/static/chunk-URHTCJ7G.js +1 -0
  222. package/static/chunk-V3AT2BKP.js +1 -0
  223. package/static/chunk-VKK5BSLX.js +1 -0
  224. package/static/{chunk-SIPE37PA.js → chunk-VM4YX6Q7.js} +1 -1
  225. package/static/chunk-WJW7CT6G.js +27 -0
  226. package/static/{chunk-7ITZXYYJ.js → chunk-WLMNXRBS.js} +1 -1
  227. package/static/chunk-X5XGK6T7.js +4 -0
  228. package/static/chunk-YEKR5OPO.js +1 -0
  229. package/static/chunk-YW57T2PF.js +1 -0
  230. package/static/chunk-Z5J5F5SX.js +1 -0
  231. package/static/chunk-ZIJQRARU.js +1 -0
  232. package/static/chunk-ZPF2DSQV.js +1 -0
  233. package/static/chunk-ZTCRGJ6Y.js +7 -0
  234. package/static/index.html +2 -2
  235. package/static/main-VOL6OMJ5.js +9 -0
  236. package/static/scripts-WRDOQIU5.js +24 -0
  237. package/static/{styles-A5VYX3CE.css → styles-2C2UNCNB.css} +1 -1
  238. package/server/applications/spaces/interfaces/space-quota.interface.js +0 -10
  239. package/server/applications/spaces/interfaces/space-quota.interface.js.map +0 -1
  240. package/static/chunk-22EANI6R.js +0 -1
  241. package/static/chunk-3GFGJYMK.js +0 -1
  242. package/static/chunk-4YGJGZZZ.js +0 -1
  243. package/static/chunk-5K7HEX3C.js +0 -27
  244. package/static/chunk-5KLMS6A4.js +0 -1
  245. package/static/chunk-ATP3BFHV.js +0 -562
  246. package/static/chunk-BB4G55KE.js +0 -1
  247. package/static/chunk-EWKSX76T.js +0 -1
  248. package/static/chunk-FHLACA7V.js +0 -1
  249. package/static/chunk-GCATNU55.js +0 -1
  250. package/static/chunk-GYODPCIE.js +0 -1
  251. package/static/chunk-HZTFYLM5.js +0 -1
  252. package/static/chunk-JSUKJT6Z.js +0 -1
  253. package/static/chunk-JXZCNFW7.js +0 -1
  254. package/static/chunk-LTGFCQR7.js +0 -1
  255. package/static/chunk-LV3PYKWO.js +0 -1
  256. package/static/chunk-N2WFNW6M.js +0 -7
  257. package/static/chunk-ORMRCEGT.js +0 -1
  258. package/static/chunk-OUTBJSMW.js +0 -1
  259. package/static/chunk-RS2PX32L.js +0 -1
  260. package/static/chunk-RSSWH3S2.js +0 -1
  261. package/static/chunk-RTRJ3KFH.js +0 -1
  262. package/static/chunk-TKTCBDOG.js +0 -1
  263. package/static/chunk-V6K2N46L.js +0 -1
  264. package/static/chunk-XLCCZSQL.js +0 -4
  265. package/static/chunk-YPEH66GG.js +0 -1
  266. package/static/chunk-YPOIUQ57.js +0 -1
  267. package/static/chunk-ZKCFO2OA.js +0 -4
  268. package/static/main-MZ7HWZXO.js +0 -9
  269. package/static/scripts-VZVAP2P4.js +0 -30
@@ -0,0 +1,52 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ Object.defineProperty(exports, "tr", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return tr;
13
+ }
14
+ });
15
+ const tr = {
16
+ 'If you no longer wish to receive notifications, change your preferences directly from your user space': 'Artık bildirim almak istemiyorsanız, kullanıcı alanınızdan doğrudan tercihlerinizi değiştirin.',
17
+ 'Access it from': 'Buradan erişin',
18
+ Comment: 'Yorum',
19
+ commented: 'yorum yaptı',
20
+ 'You receive this notification if you are the owner of the file or if you have also commented on this file': 'Dosyanın sahibiyseniz veya bu dosyaya yorum yaptıysanız bu bildirimi alırsınız.',
21
+ Space: 'Alan',
22
+ 'from the space': 'alandan',
23
+ 'to the space': 'alana',
24
+ 'Access your spaces from': 'Alanlarınıza buradan erişin',
25
+ 'Access this space from': 'Bu alana buradan erişin',
26
+ 'You now have access to the space': 'Artık bu alana erişiminiz var',
27
+ 'You no longer have access to the space': 'Artık bu alana erişiminiz yok',
28
+ 'This space has been permanently deleted': 'Bu alan kalıcı olarak silindi',
29
+ anchored: 'sabitledi',
30
+ unanchored: 'sabitlemeyi kaldırdı',
31
+ Share: 'Paylaşım',
32
+ 'shared with you': 'sizinle paylaştı',
33
+ 'no longer share with you': 'artık sizinle paylaşmıyor',
34
+ 'You now have access to the share': 'Artık paylaşıma erişiminiz var',
35
+ 'You no longer have access to the share': 'Artık paylaşıma erişiminiz yok',
36
+ 'You are no longer a member of the parent share, your child share has been deleted': 'Üst paylaşıma artık üye olmadığınız için alt paylaşımınız silindi',
37
+ 'Access your shares from': 'Paylaşımlarınıza buradan erişin',
38
+ 'Access password': 'Erişim parolası',
39
+ Sync: 'Eşitleme',
40
+ 'Access your syncs from': 'Eşitlemelerinize buradan erişin',
41
+ 'You are no longer synchronizing': 'Artık eşitleme yapmıyorsunuz',
42
+ 'Security notification': 'Güvenlik bildirimi',
43
+ 'Your account has been locked after several unsuccessful authentication attempts': 'Birkaç başarısız kimlik doğrulama girişiminden sonra hesabınız kilitlendi',
44
+ 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.': 'Bu güvenlik bildirimi, Sync-in hesabınızla ilgilidir. Analiz yapılması ve hesabınızın kilidinin açılması için lütfen bir yöneticiyle iletişime geçin.',
45
+ 'Two-factor authentication (2FA) on your account has been disabled': 'Hesabınızda iki faktörlü kimlik doğrulama (2FA) devre dışı bırakıldı',
46
+ 'Two-factor authentication (2FA) on your account has been enabled': 'Hesabınızda iki faktörlü kimlik doğrulama (2FA) etkinleştirildi',
47
+ 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.': 'Sync-in hesabınızın güvenliği değiştiği için bu bildirimi aldınız. Bunun bir hata olduğunu düşünüyorsanız güvenlik ayarlarınızı gözden geçirin veya yöneticinizle iletişime geçin.',
48
+ 'Address IP': 'IP adresi',
49
+ Browser: 'Tarayıcı'
50
+ };
51
+
52
+ //# sourceMappingURL=tr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../backend/src/applications/notifications/i18n/tr.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\nexport const tr = {\n 'If you no longer wish to receive notifications, change your preferences directly from your user space':\n 'Artık bildirim almak istemiyorsanız, kullanıcı alanınızdan doğrudan tercihlerinizi değiştirin.',\n 'Access it from': 'Buradan erişin',\n Comment: 'Yorum',\n commented: 'yorum yaptı',\n 'You receive this notification if you are the owner of the file or if you have also commented on this file':\n 'Dosyanın sahibiyseniz veya bu dosyaya yorum yaptıysanız bu bildirimi alırsınız.',\n Space: 'Alan',\n 'from the space': 'alandan',\n 'to the space': 'alana',\n 'Access your spaces from': 'Alanlarınıza buradan erişin',\n 'Access this space from': 'Bu alana buradan erişin',\n 'You now have access to the space': 'Artık bu alana erişiminiz var',\n 'You no longer have access to the space': 'Artık bu alana erişiminiz yok',\n 'This space has been permanently deleted': 'Bu alan kalıcı olarak silindi',\n anchored: 'sabitledi',\n unanchored: 'sabitlemeyi kaldırdı',\n Share: 'Paylaşım',\n 'shared with you': 'sizinle paylaştı',\n 'no longer share with you': 'artık sizinle paylaşmıyor',\n 'You now have access to the share': 'Artık paylaşıma erişiminiz var',\n 'You no longer have access to the share': 'Artık paylaşıma erişiminiz yok',\n 'You are no longer a member of the parent share, your child share has been deleted':\n 'Üst paylaşıma artık üye olmadığınız için alt paylaşımınız silindi',\n 'Access your shares from': 'Paylaşımlarınıza buradan erişin',\n 'Access password': 'Erişim parolası',\n Sync: 'Eşitleme',\n 'Access your syncs from': 'Eşitlemelerinize buradan erişin',\n 'You are no longer synchronizing': 'Artık eşitleme yapmıyorsunuz',\n 'Security notification': 'Güvenlik bildirimi',\n 'Your account has been locked after several unsuccessful authentication attempts':\n 'Birkaç başarısız kimlik doğrulama girişiminden sonra hesabınız kilitlendi',\n 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.':\n 'Bu güvenlik bildirimi, Sync-in hesabınızla ilgilidir. Analiz yapılması ve hesabınızın kilidinin açılması için lütfen bir yöneticiyle iletişime geçin.',\n 'Two-factor authentication (2FA) on your account has been disabled': 'Hesabınızda iki faktörlü kimlik doğrulama (2FA) devre dışı bırakıldı',\n 'Two-factor authentication (2FA) on your account has been enabled': 'Hesabınızda iki faktörlü kimlik doğrulama (2FA) etkinleştirildi',\n 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.':\n 'Sync-in hesabınızın güvenliği değiştiği için bu bildirimi aldınız. Bunun bir hata olduğunu düşünüyorsanız güvenlik ayarlarınızı gözden geçirin veya yöneticinizle iletişime geçin.',\n 'Address IP': 'IP adresi',\n Browser: 'Tarayıcı'\n} as const\n"],"names":["tr","Comment","commented","Space","anchored","unanchored","Share","Sync","Browser"],"mappings":"AAAA;;;;CAIC;;;;+BAEYA;;;eAAAA;;;AAAN,MAAMA,KAAK;IAChB,yGACE;IACF,kBAAkB;IAClBC,SAAS;IACTC,WAAW;IACX,6GACE;IACFC,OAAO;IACP,kBAAkB;IAClB,gBAAgB;IAChB,2BAA2B;IAC3B,0BAA0B;IAC1B,oCAAoC;IACpC,0CAA0C;IAC1C,2CAA2C;IAC3CC,UAAU;IACVC,YAAY;IACZC,OAAO;IACP,mBAAmB;IACnB,4BAA4B;IAC5B,oCAAoC;IACpC,0CAA0C;IAC1C,qFACE;IACF,2BAA2B;IAC3B,mBAAmB;IACnBC,MAAM;IACN,0BAA0B;IAC1B,mCAAmC;IACnC,yBAAyB;IACzB,mFACE;IACF,8IACE;IACF,qEAAqE;IACrE,oEAAoE;IACpE,iMACE;IACF,cAAc;IACdC,SAAS;AACX"}
@@ -0,0 +1,52 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ Object.defineProperty(exports, "zh", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return zh;
13
+ }
14
+ });
15
+ const zh = {
16
+ 'If you no longer wish to receive notifications, change your preferences directly from your user space': '如果您不再希望接收通知,请在您的用户空间中直接更改偏好设置',
17
+ 'Access it from': '通过以下入口访问',
18
+ Comment: '评论',
19
+ commented: '评论了',
20
+ 'You receive this notification if you are the owner of the file or if you have also commented on this file': '如果您是该文件的所有者或也对该文件进行了评论,您会收到此通知',
21
+ Space: '空间',
22
+ 'from the space': '来自该空间',
23
+ 'to the space': '到该空间',
24
+ 'Access your spaces from': '从以下位置访问您的空间',
25
+ 'Access this space from': '从以下位置访问此空间',
26
+ 'You now have access to the space': '您现在可以访问该空间',
27
+ 'You no longer have access to the space': '您已不再能够访问该空间',
28
+ 'This space has been permanently deleted': '该空间已被永久删除',
29
+ anchored: '已固定',
30
+ unanchored: '已取消固定',
31
+ Share: '共享',
32
+ 'shared with you': '与您共享了',
33
+ 'no longer share with you': '不再与您共享',
34
+ 'You now have access to the share': '您现在可以访问该共享',
35
+ 'You no longer have access to the share': '您已不再能够访问该共享',
36
+ 'You are no longer a member of the parent share, your child share has been deleted': '您已不再是父级共享的成员,您的子共享已被删除',
37
+ 'Access your shares from': '从以下位置访问您的共享',
38
+ 'Access password': '访问密码',
39
+ Sync: '同步',
40
+ 'Access your syncs from': '从以下位置访问您的同步',
41
+ 'You are no longer synchronizing': '您已停止同步',
42
+ 'Security notification': '安全通知',
43
+ 'Your account has been locked after several unsuccessful authentication attempts': '在多次身份验证失败后,您的账户已被锁定',
44
+ 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.': '此安全通知与您的 Sync-in 账户相关。请联系管理员进行分析并解锁您的账户。',
45
+ 'Two-factor authentication (2FA) on your account has been disabled': '您账户的双重身份验证 (2FA) 已被禁用',
46
+ 'Two-factor authentication (2FA) on your account has been enabled': '您账户的双重身份验证 (2FA) 已被启用',
47
+ 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.': '您收到此通知是因为您的 Sync-in 账户安全性发生了变化。如认为这是错误,请检查您的安全设置或联系管理员。',
48
+ 'Address IP': 'IP 地址',
49
+ Browser: '浏览器'
50
+ };
51
+
52
+ //# sourceMappingURL=zh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../backend/src/applications/notifications/i18n/zh.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\nexport const zh = {\n 'If you no longer wish to receive notifications, change your preferences directly from your user space':\n '如果您不再希望接收通知,请在您的用户空间中直接更改偏好设置',\n 'Access it from': '通过以下入口访问',\n Comment: '评论',\n commented: '评论了',\n 'You receive this notification if you are the owner of the file or if you have also commented on this file':\n '如果您是该文件的所有者或也对该文件进行了评论,您会收到此通知',\n Space: '空间',\n 'from the space': '来自该空间',\n 'to the space': '到该空间',\n 'Access your spaces from': '从以下位置访问您的空间',\n 'Access this space from': '从以下位置访问此空间',\n 'You now have access to the space': '您现在可以访问该空间',\n 'You no longer have access to the space': '您已不再能够访问该空间',\n 'This space has been permanently deleted': '该空间已被永久删除',\n anchored: '已固定',\n unanchored: '已取消固定',\n Share: '共享',\n 'shared with you': '与您共享了',\n 'no longer share with you': '不再与您共享',\n 'You now have access to the share': '您现在可以访问该共享',\n 'You no longer have access to the share': '您已不再能够访问该共享',\n 'You are no longer a member of the parent share, your child share has been deleted': '您已不再是父级共享的成员,您的子共享已被删除',\n 'Access your shares from': '从以下位置访问您的共享',\n 'Access password': '访问密码',\n Sync: '同步',\n 'Access your syncs from': '从以下位置访问您的同步',\n 'You are no longer synchronizing': '您已停止同步',\n 'Security notification': '安全通知',\n 'Your account has been locked after several unsuccessful authentication attempts': '在多次身份验证失败后,您的账户已被锁定',\n 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.':\n '此安全通知与您的 Sync-in 账户相关。请联系管理员进行分析并解锁您的账户。',\n 'Two-factor authentication (2FA) on your account has been disabled': '您账户的双重身份验证 (2FA) 已被禁用',\n 'Two-factor authentication (2FA) on your account has been enabled': '您账户的双重身份验证 (2FA) 已被启用',\n 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.':\n '您收到此通知是因为您的 Sync-in 账户安全性发生了变化。如认为这是错误,请检查您的安全设置或联系管理员。',\n 'Address IP': 'IP 地址',\n Browser: '浏览器'\n} as const\n"],"names":["zh","Comment","commented","Space","anchored","unanchored","Share","Sync","Browser"],"mappings":"AAAA;;;;CAIC;;;;+BAEYA;;;eAAAA;;;AAAN,MAAMA,KAAK;IAChB,yGACE;IACF,kBAAkB;IAClBC,SAAS;IACTC,WAAW;IACX,6GACE;IACFC,OAAO;IACP,kBAAkB;IAClB,gBAAgB;IAChB,2BAA2B;IAC3B,0BAA0B;IAC1B,oCAAoC;IACpC,0CAA0C;IAC1C,2CAA2C;IAC3CC,UAAU;IACVC,YAAY;IACZC,OAAO;IACP,mBAAmB;IACnB,4BAA4B;IAC5B,oCAAoC;IACpC,0CAA0C;IAC1C,qFAAqF;IACrF,2BAA2B;IAC3B,mBAAmB;IACnBC,MAAM;IACN,0BAA0B;IAC1B,mCAAmC;IACnC,yBAAyB;IACzB,mFAAmF;IACnF,8IACE;IACF,qEAAqE;IACrE,oEAAoE;IACpE,iMACE;IACF,cAAc;IACdC,SAAS;AACX"}
@@ -38,7 +38,6 @@ _export(exports, {
38
38
  return syncMail;
39
39
  }
40
40
  });
41
- const _appconstants = require("../../../app.constants");
42
41
  const _constants = require("../../../common/constants");
43
42
  const _shared = require("../../../common/shared");
44
43
  const _files = require("../../files/utils/files");
@@ -54,7 +53,7 @@ function commentMail(language, notification, options) {
54
53
  event: notification.event
55
54
  });
56
55
  const content = `${(0, _templates.mailAuthor)(options.author)}${(0, _templates.mailEventOnElement)(tr.event, notification.element)}${(0, _templates.mailItalicContent)(options.content)}`;
57
- const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromSpaceFile)(options.currentUrl, notification)}">${_appconstants.SERVER_NAME}</a><br>${tr.footer}<br>${tr.defaultFooter}`;
56
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromSpaceFile)(options.currentUrl, notification)}">${_shared.SERVER_NAME}</a><br>${tr.footer}<br>${tr.defaultFooter}`;
58
57
  return [
59
58
  `${tr.title}: ${(0, _shared.capitalizeString)(notification.element)}`,
60
59
  (0, _templates.mailTemplate)(content, footer)
@@ -69,7 +68,7 @@ function spaceMail(language, notification, options) {
69
68
  });
70
69
  const spaceUrl = (0, _urls.urlFromSpace)(options.currentUrl, options.action === _constants.ACTION.ADD ? notification.element : undefined);
71
70
  const content = `${(0, _templates.mailEventOnElement)(tr.event, notification.element)}`;
72
- const footer = `<br>${tr.urlText}&nbsp;<a href="${spaceUrl}">${_appconstants.SERVER_NAME}</a><br>${tr.defaultFooter}`;
71
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${spaceUrl}">${_shared.SERVER_NAME}</a><br>${tr.defaultFooter}`;
73
72
  return [
74
73
  `${tr.title}: ${(0, _shared.capitalizeString)(notification.element)}`,
75
74
  (0, _templates.mailTemplate)(content, footer)
@@ -86,7 +85,7 @@ function spaceRootMail(language, notification, options) {
86
85
  const spaceName = (0, _files.fileName)(notification.url);
87
86
  const spaceRootUrl = options.action === _constants.ACTION.ADD ? (0, _urls.urlFromSpaceFile)(options.currentUrl, notification) : (0, _urls.urlFromSpace)(options.currentUrl, spaceName);
88
87
  const content = `${(0, _templates.mailAuthor)(options.author)}${(0, _templates.mailEventOnElement)(tr.event, notification.element)}&nbsp;${tr.originEvent}&nbsp;<b>${spaceName}</b>`;
89
- const footer = `<br>${tr.urlText}&nbsp;<a href="${spaceRootUrl}">${_appconstants.SERVER_NAME}</a><br>${tr.defaultFooter}`;
88
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${spaceRootUrl}">${_shared.SERVER_NAME}</a><br>${tr.defaultFooter}`;
90
89
  return [
91
90
  `${tr.title}: ${(0, _shared.capitalizeString)(spaceName)}`,
92
91
  (0, _templates.mailTemplate)(content, footer)
@@ -100,7 +99,7 @@ function shareMail(language, notification, options) {
100
99
  event: notification.event
101
100
  });
102
101
  const content = `${options.author ? (0, _templates.mailAuthor)(options.author) : ''}${(0, _templates.mailEventOnElement)(tr.event, notification.element)}`;
103
- const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromSpaceFile)(options.currentUrl, notification)}">${_appconstants.SERVER_NAME}</a><br>${tr.defaultFooter}`;
102
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromSpaceFile)(options.currentUrl, notification)}">${_shared.SERVER_NAME}</a><br>${tr.defaultFooter}`;
104
103
  return [
105
104
  `${tr.title}: ${(0, _shared.capitalizeString)(notification.element)}`,
106
105
  (0, _templates.mailTemplate)(content, footer)
@@ -117,7 +116,7 @@ function linkMail(language, notification, options) {
117
116
  if (options.linkPassword) {
118
117
  content += `<br><br>${tr.passwordText}:&nbsp;<div style="border:1px solid #000; padding:8px; display:inline-block;">${options.linkPassword}</div>`;
119
118
  }
120
- const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromLink)(options.currentUrl, options.linkUUID)}">${_appconstants.SERVER_NAME}</a>`;
119
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${(0, _urls.urlFromLink)(options.currentUrl, options.linkUUID)}">${_shared.SERVER_NAME}</a>`;
121
120
  return [
122
121
  `${tr.title}: ${(0, _shared.capitalizeString)(notification.element)}`,
123
122
  (0, _templates.mailTemplate)(content, footer)
@@ -132,7 +131,7 @@ function syncMail(language, notification, options) {
132
131
  });
133
132
  const syncUrl = (0, _urls.urlFromSync)(options.currentUrl);
134
133
  const content = `${(0, _templates.mailEventOnElement)(tr.event, notification.element)}`;
135
- const footer = `<br>${tr.urlText}&nbsp;<a href="${syncUrl}">${_appconstants.SERVER_NAME}</a><br>${tr.defaultFooter}`;
134
+ const footer = `<br>${tr.urlText}&nbsp;<a href="${syncUrl}">${_shared.SERVER_NAME}</a><br>${tr.defaultFooter}`;
136
135
  return [
137
136
  `${tr.title}: ${(0, _shared.capitalizeString)(notification.element)}`,
138
137
  (0, _templates.mailTemplate)(content, footer)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/notifications/mails/models.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 { SERVER_NAME } from '../../../app.constants'\nimport { ACTION } from '../../../common/constants'\nimport { capitalizeString } from '../../../common/shared'\nimport { fileName } from '../../files/utils/files'\nimport { UserModel } from '../../users/models/user.model'\nimport { translateObject } from '../i18n'\nimport { NotificationContent } from '../interfaces/notification-properties.interface'\nimport { defaultFooter, mailAuthor, mailEventOnElement, mailItalicContent, mailTemplate } from './templates'\nimport { urlFromLink, urlFromSpace, urlFromSpaceFile, urlFromSync } from './urls'\n\nexport function commentMail(\n language: string,\n notification: NotificationContent,\n options: {\n content: string\n currentUrl: string\n author: UserModel\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Comment',\n defaultFooter: defaultFooter,\n footer: 'You receive this notification if you are the owner of the file or if you have also commented on this file',\n urlText: 'Access it from',\n event: notification.event\n })\n\n const content = `${mailAuthor(options.author)}${mailEventOnElement(tr.event, notification.element)}${mailItalicContent(options.content)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromSpaceFile(options.currentUrl, notification)}\">${SERVER_NAME}</a><br>${tr.footer}<br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function spaceMail(\n language: string,\n notification: NotificationContent,\n options: {\n currentUrl: string\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Space',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your spaces from',\n event: notification.event\n })\n\n const spaceUrl = urlFromSpace(options.currentUrl, options.action === ACTION.ADD ? notification.element : undefined)\n\n const content = `${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${spaceUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function spaceRootMail(\n language: string,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Space',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access this space from',\n event: notification.event,\n originEvent: options.action === ACTION.ADD ? 'to the space' : 'from the space'\n })\n\n const spaceName = fileName(notification.url)\n const spaceRootUrl =\n options.action === ACTION.ADD ? urlFromSpaceFile(options.currentUrl, notification) : urlFromSpace(options.currentUrl, spaceName)\n\n const content = `${mailAuthor(options.author)}${mailEventOnElement(tr.event, notification.element)}&nbsp;${tr.originEvent}&nbsp;<b>${spaceName}</b>`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${spaceRootUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(spaceName)}`, mailTemplate(content, footer)]\n}\n\nexport function shareMail(\n language: string,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Share',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your shares from',\n event: notification.event\n })\n\n const content = `${options.author ? mailAuthor(options.author) : ''}${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromSpaceFile(options.currentUrl, notification)}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function linkMail(\n language: string,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n linkUUID: string\n linkPassword: string\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: options.action === ACTION.ADD ? 'Share' : 'Space',\n passwordText: 'Access password',\n urlText: 'Access it from',\n event: notification.event\n })\n\n let content = `${options.author ? mailAuthor(options.author) : ''}${mailEventOnElement(tr.event, notification.element)}`\n\n if (options.linkPassword) {\n content += `<br><br>${tr.passwordText}:&nbsp;<div style=\"border:1px solid #000; padding:8px; display:inline-block;\">${options.linkPassword}</div>`\n }\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromLink(options.currentUrl, options.linkUUID)}\">${SERVER_NAME}</a>`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function syncMail(\n language: string,\n notification: NotificationContent,\n options: {\n currentUrl: string\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Sync',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your syncs from',\n event: notification.event\n })\n\n const syncUrl = urlFromSync(options.currentUrl)\n\n const content = `${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${syncUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function auth2FaMail(language: string, notification: NotificationContent): [string, string] {\n const tr = translateObject(language, {\n title: 'Security notification',\n footer:\n 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.',\n event: notification.event,\n addressIp: 'Address IP',\n browser: 'Browser'\n })\n\n const content = `${tr.event}<br><br>${tr.addressIp}:&nbsp;${notification.url}<br>${tr.browser}:&nbsp;${notification.element}`\n\n const footer = `<br>${tr.footer}<br>`\n\n return [tr.title, mailTemplate(content, footer)]\n}\n\nexport function authLocked(language: string, notification: NotificationContent): [string, string] {\n const tr = translateObject(language, {\n title: 'Security notification',\n footer:\n 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.',\n event: notification.event,\n addressIp: 'Address IP'\n })\n\n const content = `${tr.event}<br><br>${tr.addressIp}:&nbsp;${notification.url}<br>`\n\n const footer = `<br>${tr.footer}<br>`\n\n return [tr.title, mailTemplate(content, footer)]\n}\n"],"names":["auth2FaMail","authLocked","commentMail","linkMail","shareMail","spaceMail","spaceRootMail","syncMail","language","notification","options","tr","translateObject","title","defaultFooter","footer","urlText","event","content","mailAuthor","author","mailEventOnElement","element","mailItalicContent","urlFromSpaceFile","currentUrl","SERVER_NAME","capitalizeString","mailTemplate","action","ACTION","ADD","spaceUrl","urlFromSpace","undefined","originEvent","spaceName","fileName","url","spaceRootUrl","passwordText","linkPassword","urlFromLink","linkUUID","syncUrl","urlFromSync","addressIp","browser"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/notifications/mails/models.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 { ACTION } from '../../../common/constants'\nimport { i18nLocale } from '../../../common/i18n'\nimport { capitalizeString, SERVER_NAME } from '../../../common/shared'\nimport { fileName } from '../../files/utils/files'\nimport { UserModel } from '../../users/models/user.model'\nimport { translateObject } from '../i18n'\nimport { NotificationContent } from '../interfaces/notification-properties.interface'\nimport { defaultFooter, mailAuthor, mailEventOnElement, mailItalicContent, mailTemplate } from './templates'\nimport { urlFromLink, urlFromSpace, urlFromSpaceFile, urlFromSync } from './urls'\n\nexport function commentMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n content: string\n currentUrl: string\n author: UserModel\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Comment',\n defaultFooter: defaultFooter,\n footer: 'You receive this notification if you are the owner of the file or if you have also commented on this file',\n urlText: 'Access it from',\n event: notification.event\n })\n\n const content = `${mailAuthor(options.author)}${mailEventOnElement(tr.event, notification.element)}${mailItalicContent(options.content)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromSpaceFile(options.currentUrl, notification)}\">${SERVER_NAME}</a><br>${tr.footer}<br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function spaceMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n currentUrl: string\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Space',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your spaces from',\n event: notification.event\n })\n\n const spaceUrl = urlFromSpace(options.currentUrl, options.action === ACTION.ADD ? notification.element : undefined)\n\n const content = `${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${spaceUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function spaceRootMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Space',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access this space from',\n event: notification.event,\n originEvent: options.action === ACTION.ADD ? 'to the space' : 'from the space'\n })\n\n const spaceName = fileName(notification.url)\n const spaceRootUrl =\n options.action === ACTION.ADD ? urlFromSpaceFile(options.currentUrl, notification) : urlFromSpace(options.currentUrl, spaceName)\n\n const content = `${mailAuthor(options.author)}${mailEventOnElement(tr.event, notification.element)}&nbsp;${tr.originEvent}&nbsp;<b>${spaceName}</b>`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${spaceRootUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(spaceName)}`, mailTemplate(content, footer)]\n}\n\nexport function shareMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Share',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your shares from',\n event: notification.event\n })\n\n const content = `${options.author ? mailAuthor(options.author) : ''}${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromSpaceFile(options.currentUrl, notification)}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function linkMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n currentUrl: string\n author: UserModel\n action: ACTION\n linkUUID: string\n linkPassword: string\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: options.action === ACTION.ADD ? 'Share' : 'Space',\n passwordText: 'Access password',\n urlText: 'Access it from',\n event: notification.event\n })\n\n let content = `${options.author ? mailAuthor(options.author) : ''}${mailEventOnElement(tr.event, notification.element)}`\n\n if (options.linkPassword) {\n content += `<br><br>${tr.passwordText}:&nbsp;<div style=\"border:1px solid #000; padding:8px; display:inline-block;\">${options.linkPassword}</div>`\n }\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${urlFromLink(options.currentUrl, options.linkUUID)}\">${SERVER_NAME}</a>`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function syncMail(\n language: i18nLocale,\n notification: NotificationContent,\n options: {\n currentUrl: string\n action: ACTION\n }\n): [string, string] {\n const tr = translateObject(language, {\n title: 'Sync',\n defaultFooter: defaultFooter,\n urlText: options.action === ACTION.ADD ? 'Access it from' : 'Access your syncs from',\n event: notification.event\n })\n\n const syncUrl = urlFromSync(options.currentUrl)\n\n const content = `${mailEventOnElement(tr.event, notification.element)}`\n\n const footer = `<br>${tr.urlText}&nbsp;<a href=\"${syncUrl}\">${SERVER_NAME}</a><br>${tr.defaultFooter}`\n\n return [`${tr.title}: ${capitalizeString(notification.element)}`, mailTemplate(content, footer)]\n}\n\nexport function auth2FaMail(language: i18nLocale, notification: NotificationContent): [string, string] {\n const tr = translateObject(language, {\n title: 'Security notification',\n footer:\n 'You received this notification because the security of your Sync-in account has changed. If you think this was a mistake, please review your security settings or contact your administrator.',\n event: notification.event,\n addressIp: 'Address IP',\n browser: 'Browser'\n })\n\n const content = `${tr.event}<br><br>${tr.addressIp}:&nbsp;${notification.url}<br>${tr.browser}:&nbsp;${notification.element}`\n\n const footer = `<br>${tr.footer}<br>`\n\n return [tr.title, mailTemplate(content, footer)]\n}\n\nexport function authLocked(language: i18nLocale, notification: NotificationContent): [string, string] {\n const tr = translateObject(language, {\n title: 'Security notification',\n footer:\n 'This security notification concerns your Sync-in account. Please contact an administrator to perform the analysis and unlock your account.',\n event: notification.event,\n addressIp: 'Address IP'\n })\n\n const content = `${tr.event}<br><br>${tr.addressIp}:&nbsp;${notification.url}<br>`\n\n const footer = `<br>${tr.footer}<br>`\n\n return [tr.title, mailTemplate(content, footer)]\n}\n"],"names":["auth2FaMail","authLocked","commentMail","linkMail","shareMail","spaceMail","spaceRootMail","syncMail","language","notification","options","tr","translateObject","title","defaultFooter","footer","urlText","event","content","mailAuthor","author","mailEventOnElement","element","mailItalicContent","urlFromSpaceFile","currentUrl","SERVER_NAME","capitalizeString","mailTemplate","action","ACTION","ADD","spaceUrl","urlFromSpace","undefined","originEvent","spaceName","fileName","url","spaceRootUrl","passwordText","linkPassword","urlFromLink","linkUUID","syncUrl","urlFromSync","addressIp","browser"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/notifications/services/notifications-manager.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 { Injectable, Logger } from '@nestjs/common'\nimport { MailProps } from '../../../infrastructure/mailer/interfaces/mail.interface'\nimport { Mailer } from '../../../infrastructure/mailer/mailer.service'\nimport { USER_NOTIFICATION } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { NOTIFICATION_APP } from '../constants/notifications'\nimport { NOTIFICATIONS_WS } from '../constants/websocket'\nimport type { NotificationContent, NotificationFromUser, NotificationOptions } from '../interfaces/notification-properties.interface'\nimport type { UserMailNotification } from '../interfaces/user-mail-notification'\nimport { auth2FaMail, authLocked, commentMail, linkMail, shareMail, spaceMail, spaceRootMail, syncMail } from '../mails/models'\nimport { WebSocketNotifications } from '../notifications.gateway'\nimport { NotificationsQueries } from './notifications-queries.service'\n\n@Injectable()\nexport class NotificationsManager {\n private readonly logger = new Logger(NotificationsManager.name)\n\n constructor(\n private readonly mailer: Mailer,\n private readonly notificationsQueries: NotificationsQueries,\n private readonly webSocketNotifications: WebSocketNotifications\n ) {}\n\n list(user: UserModel, onlyUnread: boolean = false): Promise<NotificationFromUser[]> {\n return this.notificationsQueries.list(user.id, onlyUnread)\n }\n\n async create(toUsers: UserMailNotification[] | number[], content: NotificationContent, options?: NotificationOptions): Promise<void> {\n // store it in db\n const isArrayOfUsers: boolean = typeof toUsers[0] === 'object'\n const toUserIds = isArrayOfUsers ? (toUsers as UserMailNotification[]).map((m) => m.id) : (toUsers as number[])\n this.storeNotification(toUserIds, content, options?.author?.id).catch((e: Error) => this.logger.error(`${this.create.name} - ${e}`))\n\n // send websocket notification\n this.webSocketNotifications.sendMessageToUsers(toUserIds, NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check')\n\n // send emails\n if (this.mailer.available) {\n const usersNotifiedByEmail: UserMailNotification[] = isArrayOfUsers\n ? (toUsers as UserMailNotification[]).filter((u) => u.notification === USER_NOTIFICATION.APPLICATION_EMAIL)\n : await this.notificationsQueries.usersNotifiedByEmail(toUsers as number[])\n if (!usersNotifiedByEmail.length) {\n return\n }\n this.sendEmailNotification(usersNotifiedByEmail, content, options).catch((e: Error) => this.logger.error(`${this.create.name} - ${e}`))\n }\n }\n\n wasRead(user: UserModel, notificationId?: number): void {\n this.notificationsQueries.wasRead(user.id, notificationId).catch((e: Error) => this.logger.error(`${this.wasRead.name} - ${e}`))\n }\n\n async delete(user: UserModel, notificationId?: number): Promise<void> {\n return this.notificationsQueries.delete(user.id, notificationId)\n }\n\n async sendEmailNotification(toUsers: UserMailNotification[], content: NotificationContent, options?: NotificationOptions): Promise<void> {\n if (!this.mailer.available) {\n return\n }\n if (options?.author) {\n options.author.avatarBase64 = await getAvatarBase64(options.author.login)\n }\n this.mailer\n .sendMails(\n await Promise.all(\n toUsers.map(async (m) => {\n const [title, html] = this.genMail(m.language, content, options)\n return {\n to: m.email,\n subject: title,\n html: html\n } satisfies MailProps\n })\n )\n )\n .catch((e: Error) => this.logger.error(`${this.sendEmailNotification.name} - ${e}`))\n }\n\n private async storeNotification(toUserIds: number[], content: NotificationContent, authorId?: number): Promise<void> {\n // store it in db\n try {\n await this.notificationsQueries.create(authorId || null, toUserIds, content)\n } catch (e) {\n this.logger.error(`${this.create.name} - ${e}`)\n }\n }\n\n private genMail(language: string, content: NotificationContent, options?: NotificationOptions): [string, string] {\n switch (content.app) {\n case NOTIFICATION_APP.COMMENTS:\n return commentMail(language, content, { content: options.content, currentUrl: options.currentUrl, author: options.author })\n case NOTIFICATION_APP.SPACES:\n return spaceMail(language, content, { currentUrl: options.currentUrl, action: options.action })\n case NOTIFICATION_APP.SPACE_ROOTS:\n return spaceRootMail(language, content, { currentUrl: options.currentUrl, author: options.author, action: options.action })\n case NOTIFICATION_APP.SHARES:\n return shareMail(language, content, { currentUrl: options.currentUrl, author: options.author, action: options.action })\n case NOTIFICATION_APP.LINKS:\n return linkMail(language, content, {\n currentUrl: options.currentUrl,\n author: options.author,\n linkUUID: options.linkUUID,\n linkPassword: options.linkPassword,\n action: options.action\n })\n case NOTIFICATION_APP.SYNC:\n return syncMail(language, content, { currentUrl: options.currentUrl, action: options.action })\n case NOTIFICATION_APP.AUTH_2FA:\n return auth2FaMail(language, content)\n case NOTIFICATION_APP.AUTH_LOCKED:\n return authLocked(language, content)\n default:\n this.logger.error(`${this.genMail.name} - case not handled : ${content.app}`)\n }\n }\n}\n"],"names":["NotificationsManager","list","user","onlyUnread","notificationsQueries","id","create","toUsers","content","options","isArrayOfUsers","toUserIds","map","m","storeNotification","author","catch","e","logger","error","name","webSocketNotifications","sendMessageToUsers","NOTIFICATIONS_WS","EVENTS","NOTIFICATION","mailer","available","usersNotifiedByEmail","filter","u","notification","USER_NOTIFICATION","APPLICATION_EMAIL","length","sendEmailNotification","wasRead","notificationId","delete","avatarBase64","getAvatarBase64","login","sendMails","Promise","all","title","html","genMail","language","to","email","subject","authorId","app","NOTIFICATION_APP","COMMENTS","commentMail","currentUrl","SPACES","spaceMail","action","SPACE_ROOTS","spaceRootMail","SHARES","shareMail","LINKS","linkMail","linkUUID","linkPassword","SYNC","syncMail","AUTH_2FA","auth2FaMail","AUTH_LOCKED","authLocked","Logger"],"mappings":"AAAA;;;;CAIC;;;;+BAiBYA;;;eAAAA;;;wBAfsB;+BAEZ;sBACW;wBAEF;+BACC;2BACA;wBAG6E;sCACvE;6CACF;;;;;;;;;;AAG9B,IAAA,AAAMA,uBAAN,MAAMA;IASXC,KAAKC,IAAe,EAAEC,aAAsB,KAAK,EAAmC;QAClF,OAAO,IAAI,CAACC,oBAAoB,CAACH,IAAI,CAACC,KAAKG,EAAE,EAAEF;IACjD;IAEA,MAAMG,OAAOC,OAA0C,EAAEC,OAA4B,EAAEC,OAA6B,EAAiB;QACnI,iBAAiB;QACjB,MAAMC,iBAA0B,OAAOH,OAAO,CAAC,EAAE,KAAK;QACtD,MAAMI,YAAYD,iBAAiB,AAACH,QAAmCK,GAAG,CAAC,CAACC,IAAMA,EAAER,EAAE,IAAKE;QAC3F,IAAI,CAACO,iBAAiB,CAACH,WAAWH,SAASC,SAASM,QAAQV,IAAIW,KAAK,CAAC,CAACC,IAAa,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACb,MAAM,CAACc,IAAI,CAAC,GAAG,EAAEH,GAAG;QAElI,8BAA8B;QAC9B,IAAI,CAACI,sBAAsB,CAACC,kBAAkB,CAACX,WAAWY,2BAAgB,CAACC,MAAM,CAACC,YAAY,EAAE;QAEhG,cAAc;QACd,IAAI,IAAI,CAACC,MAAM,CAACC,SAAS,EAAE;YACzB,MAAMC,uBAA+ClB,iBACjD,AAACH,QAAmCsB,MAAM,CAAC,CAACC,IAAMA,EAAEC,YAAY,KAAKC,uBAAiB,CAACC,iBAAiB,IACxG,MAAM,IAAI,CAAC7B,oBAAoB,CAACwB,oBAAoB,CAACrB;YACzD,IAAI,CAACqB,qBAAqBM,MAAM,EAAE;gBAChC;YACF;YACA,IAAI,CAACC,qBAAqB,CAACP,sBAAsBpB,SAASC,SAASO,KAAK,CAAC,CAACC,IAAa,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACb,MAAM,CAACc,IAAI,CAAC,GAAG,EAAEH,GAAG;QACvI;IACF;IAEAmB,QAAQlC,IAAe,EAAEmC,cAAuB,EAAQ;QACtD,IAAI,CAACjC,oBAAoB,CAACgC,OAAO,CAAClC,KAAKG,EAAE,EAAEgC,gBAAgBrB,KAAK,CAAC,CAACC,IAAa,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACiB,OAAO,CAAChB,IAAI,CAAC,GAAG,EAAEH,GAAG;IAChI;IAEA,MAAMqB,OAAOpC,IAAe,EAAEmC,cAAuB,EAAiB;QACpE,OAAO,IAAI,CAACjC,oBAAoB,CAACkC,MAAM,CAACpC,KAAKG,EAAE,EAAEgC;IACnD;IAEA,MAAMF,sBAAsB5B,OAA+B,EAAEC,OAA4B,EAAEC,OAA6B,EAAiB;QACvI,IAAI,CAAC,IAAI,CAACiB,MAAM,CAACC,SAAS,EAAE;YAC1B;QACF;QACA,IAAIlB,SAASM,QAAQ;YACnBN,QAAQM,MAAM,CAACwB,YAAY,GAAG,MAAMC,IAAAA,uBAAe,EAAC/B,QAAQM,MAAM,CAAC0B,KAAK;QAC1E;QACA,IAAI,CAACf,MAAM,CACRgB,SAAS,CACR,MAAMC,QAAQC,GAAG,CACfrC,QAAQK,GAAG,CAAC,OAAOC;YACjB,MAAM,CAACgC,OAAOC,KAAK,GAAG,IAAI,CAACC,OAAO,CAAClC,EAAEmC,QAAQ,EAAExC,SAASC;YACxD,OAAO;gBACLwC,IAAIpC,EAAEqC,KAAK;gBACXC,SAASN;gBACTC,MAAMA;YACR;QACF,KAGH9B,KAAK,CAAC,CAACC,IAAa,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACgB,qBAAqB,CAACf,IAAI,CAAC,GAAG,EAAEH,GAAG;IACtF;IAEA,MAAcH,kBAAkBH,SAAmB,EAAEH,OAA4B,EAAE4C,QAAiB,EAAiB;QACnH,iBAAiB;QACjB,IAAI;YACF,MAAM,IAAI,CAAChD,oBAAoB,CAACE,MAAM,CAAC8C,YAAY,MAAMzC,WAAWH;QACtE,EAAE,OAAOS,GAAG;YACV,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACb,MAAM,CAACc,IAAI,CAAC,GAAG,EAAEH,GAAG;QAChD;IACF;IAEQ8B,QAAQC,QAAgB,EAAExC,OAA4B,EAAEC,OAA6B,EAAoB;QAC/G,OAAQD,QAAQ6C,GAAG;YACjB,KAAKC,+BAAgB,CAACC,QAAQ;gBAC5B,OAAOC,IAAAA,mBAAW,EAACR,UAAUxC,SAAS;oBAAEA,SAASC,QAAQD,OAAO;oBAAEiD,YAAYhD,QAAQgD,UAAU;oBAAE1C,QAAQN,QAAQM,MAAM;gBAAC;YAC3H,KAAKuC,+BAAgB,CAACI,MAAM;gBAC1B,OAAOC,IAAAA,iBAAS,EAACX,UAAUxC,SAAS;oBAAEiD,YAAYhD,QAAQgD,UAAU;oBAAEG,QAAQnD,QAAQmD,MAAM;gBAAC;YAC/F,KAAKN,+BAAgB,CAACO,WAAW;gBAC/B,OAAOC,IAAAA,qBAAa,EAACd,UAAUxC,SAAS;oBAAEiD,YAAYhD,QAAQgD,UAAU;oBAAE1C,QAAQN,QAAQM,MAAM;oBAAE6C,QAAQnD,QAAQmD,MAAM;gBAAC;YAC3H,KAAKN,+BAAgB,CAACS,MAAM;gBAC1B,OAAOC,IAAAA,iBAAS,EAAChB,UAAUxC,SAAS;oBAAEiD,YAAYhD,QAAQgD,UAAU;oBAAE1C,QAAQN,QAAQM,MAAM;oBAAE6C,QAAQnD,QAAQmD,MAAM;gBAAC;YACvH,KAAKN,+BAAgB,CAACW,KAAK;gBACzB,OAAOC,IAAAA,gBAAQ,EAAClB,UAAUxC,SAAS;oBACjCiD,YAAYhD,QAAQgD,UAAU;oBAC9B1C,QAAQN,QAAQM,MAAM;oBACtBoD,UAAU1D,QAAQ0D,QAAQ;oBAC1BC,cAAc3D,QAAQ2D,YAAY;oBAClCR,QAAQnD,QAAQmD,MAAM;gBACxB;YACF,KAAKN,+BAAgB,CAACe,IAAI;gBACxB,OAAOC,IAAAA,gBAAQ,EAACtB,UAAUxC,SAAS;oBAAEiD,YAAYhD,QAAQgD,UAAU;oBAAEG,QAAQnD,QAAQmD,MAAM;gBAAC;YAC9F,KAAKN,+BAAgB,CAACiB,QAAQ;gBAC5B,OAAOC,IAAAA,mBAAW,EAACxB,UAAUxC;YAC/B,KAAK8C,+BAAgB,CAACmB,WAAW;gBAC/B,OAAOC,IAAAA,kBAAU,EAAC1B,UAAUxC;YAC9B;gBACE,IAAI,CAACU,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAAC4B,OAAO,CAAC3B,IAAI,CAAC,sBAAsB,EAAEZ,QAAQ6C,GAAG,EAAE;QAChF;IACF;IAlGA,YACE,AAAiB3B,MAAc,EAC/B,AAAiBtB,oBAA0C,EAC3D,AAAiBiB,sBAA8C,CAC/D;aAHiBK,SAAAA;aACAtB,uBAAAA;aACAiB,yBAAAA;aALFH,SAAS,IAAIyD,cAAM,CAAC3E,qBAAqBoB,IAAI;IAM3D;AA+FL"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/notifications/services/notifications-manager.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 { Injectable, Logger } from '@nestjs/common'\nimport { i18nLocale } from '../../../common/i18n'\nimport { MailProps } from '../../../infrastructure/mailer/interfaces/mail.interface'\nimport { Mailer } from '../../../infrastructure/mailer/mailer.service'\nimport { USER_NOTIFICATION } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { NOTIFICATION_APP } from '../constants/notifications'\nimport { NOTIFICATIONS_WS } from '../constants/websocket'\nimport type { NotificationContent, NotificationFromUser, NotificationOptions } from '../interfaces/notification-properties.interface'\nimport type { UserMailNotification } from '../interfaces/user-mail-notification'\nimport { auth2FaMail, authLocked, commentMail, linkMail, shareMail, spaceMail, spaceRootMail, syncMail } from '../mails/models'\nimport { WebSocketNotifications } from '../notifications.gateway'\nimport { NotificationsQueries } from './notifications-queries.service'\n\n@Injectable()\nexport class NotificationsManager {\n private readonly logger = new Logger(NotificationsManager.name)\n\n constructor(\n private readonly mailer: Mailer,\n private readonly notificationsQueries: NotificationsQueries,\n private readonly webSocketNotifications: WebSocketNotifications\n ) {}\n\n list(user: UserModel, onlyUnread: boolean = false): Promise<NotificationFromUser[]> {\n return this.notificationsQueries.list(user.id, onlyUnread)\n }\n\n async create(toUsers: UserMailNotification[] | number[], content: NotificationContent, options?: NotificationOptions): Promise<void> {\n // store it in db\n const isArrayOfUsers: boolean = typeof toUsers[0] === 'object'\n const toUserIds = isArrayOfUsers ? (toUsers as UserMailNotification[]).map((m) => m.id) : (toUsers as number[])\n this.storeNotification(toUserIds, content, options?.author?.id).catch((e: Error) => this.logger.error(`${this.create.name} - ${e}`))\n\n // send websocket notification\n this.webSocketNotifications.sendMessageToUsers(toUserIds, NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check')\n\n // send emails\n if (this.mailer.available) {\n const usersNotifiedByEmail: UserMailNotification[] = isArrayOfUsers\n ? (toUsers as UserMailNotification[]).filter((u) => u.notification === USER_NOTIFICATION.APPLICATION_EMAIL)\n : await this.notificationsQueries.usersNotifiedByEmail(toUsers as number[])\n if (!usersNotifiedByEmail.length) {\n return\n }\n this.sendEmailNotification(usersNotifiedByEmail, content, options).catch((e: Error) => this.logger.error(`${this.create.name} - ${e}`))\n }\n }\n\n wasRead(user: UserModel, notificationId?: number): void {\n this.notificationsQueries.wasRead(user.id, notificationId).catch((e: Error) => this.logger.error(`${this.wasRead.name} - ${e}`))\n }\n\n async delete(user: UserModel, notificationId?: number): Promise<void> {\n return this.notificationsQueries.delete(user.id, notificationId)\n }\n\n async sendEmailNotification(toUsers: UserMailNotification[], content: NotificationContent, options?: NotificationOptions): Promise<void> {\n if (!this.mailer.available) {\n return\n }\n if (options?.author) {\n options.author.avatarBase64 = await getAvatarBase64(options.author.login)\n }\n this.mailer\n .sendMails(\n await Promise.all(\n toUsers.map(async (m) => {\n const [title, html] = this.genMail(m.language as i18nLocale, content, options)\n return {\n to: m.email,\n subject: title,\n html: html\n } satisfies MailProps\n })\n )\n )\n .catch((e: Error) => this.logger.error(`${this.sendEmailNotification.name} - ${e}`))\n }\n\n private async storeNotification(toUserIds: number[], content: NotificationContent, authorId?: number): Promise<void> {\n // store it in db\n try {\n await this.notificationsQueries.create(authorId || null, toUserIds, content)\n } catch (e) {\n this.logger.error(`${this.create.name} - ${e}`)\n }\n }\n\n private genMail(language: i18nLocale, content: NotificationContent, options?: NotificationOptions): [string, string] {\n switch (content.app) {\n case NOTIFICATION_APP.COMMENTS:\n return commentMail(language, content, { content: options.content, currentUrl: options.currentUrl, author: options.author })\n case NOTIFICATION_APP.SPACES:\n return spaceMail(language, content, { currentUrl: options.currentUrl, action: options.action })\n case NOTIFICATION_APP.SPACE_ROOTS:\n return spaceRootMail(language, content, { currentUrl: options.currentUrl, author: options.author, action: options.action })\n case NOTIFICATION_APP.SHARES:\n return shareMail(language, content, { currentUrl: options.currentUrl, author: options.author, action: options.action })\n case NOTIFICATION_APP.LINKS:\n return linkMail(language, content, {\n currentUrl: options.currentUrl,\n author: options.author,\n linkUUID: options.linkUUID,\n linkPassword: options.linkPassword,\n action: options.action\n })\n case NOTIFICATION_APP.SYNC:\n return syncMail(language, content, { currentUrl: options.currentUrl, action: options.action })\n case NOTIFICATION_APP.AUTH_2FA:\n return auth2FaMail(language, content)\n case NOTIFICATION_APP.AUTH_LOCKED:\n return authLocked(language, content)\n default:\n this.logger.error(`${this.genMail.name} - case not handled : ${content.app}`)\n }\n }\n}\n"],"names":["NotificationsManager","list","user","onlyUnread","notificationsQueries","id","create","toUsers","content","options","isArrayOfUsers","toUserIds","map","m","storeNotification","author","catch","e","logger","error","name","webSocketNotifications","sendMessageToUsers","NOTIFICATIONS_WS","EVENTS","NOTIFICATION","mailer","available","usersNotifiedByEmail","filter","u","notification","USER_NOTIFICATION","APPLICATION_EMAIL","length","sendEmailNotification","wasRead","notificationId","delete","avatarBase64","getAvatarBase64","login","sendMails","Promise","all","title","html","genMail","language","to","email","subject","authorId","app","NOTIFICATION_APP","COMMENTS","commentMail","currentUrl","SPACES","spaceMail","action","SPACE_ROOTS","spaceRootMail","SHARES","shareMail","LINKS","linkMail","linkUUID","linkPassword","SYNC","syncMail","AUTH_2FA","auth2FaMail","AUTH_LOCKED","authLocked","Logger"],"mappings":"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"}
@@ -154,6 +154,7 @@ _ts_decorate([
154
154
  let CreateOrUpdateShareDto = class CreateOrUpdateShareDto {
155
155
  constructor(){
156
156
  this.externalPath = null;
157
+ this.storageQuota = null;
157
158
  this.// contains members (users, guests, links, groups, personal groups)
158
159
  members = [];
159
160
  this.// contains links
@@ -197,6 +198,16 @@ _ts_decorate([
197
198
  (0, _classvalidator.IsBoolean)(),
198
199
  _ts_metadata("design:type", Boolean)
199
200
  ], CreateOrUpdateShareDto.prototype, "enabled", void 0);
201
+ _ts_decorate([
202
+ (0, _classvalidator.IsOptional)(),
203
+ (0, _classvalidator.IsInt)(),
204
+ _ts_metadata("design:type", Number)
205
+ ], CreateOrUpdateShareDto.prototype, "storageQuota", void 0);
206
+ _ts_decorate([
207
+ (0, _classvalidator.IsOptional)(),
208
+ (0, _classvalidator.IsBoolean)(),
209
+ _ts_metadata("design:type", Boolean)
210
+ ], CreateOrUpdateShareDto.prototype, "storageIndexing", void 0);
200
211
  _ts_decorate([
201
212
  (0, _classvalidator.IsOptional)(),
202
213
  (0, _classvalidator.ValidateNested)(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/shares/dto/create-or-update-share.dto.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 { Transform, Type } from 'class-transformer'\nimport { IsArray, IsBoolean, IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, ValidateIf, ValidateNested } from 'class-validator'\nimport { FileSpace } from '../../files/interfaces/file-space.interface'\nimport { sanitizeName, sanitizePath } from '../../files/utils/files'\nimport { CreateOrUpdateLinkDto } from '../../links/dto/create-or-update-link.dto'\nimport { MEMBER_TYPE, MEMBER_TYPE_REVERSE } from '../../users/constants/member'\nimport { SHARE_TYPE } from '../constants/shares'\n\nexport class ShareMemberDto {\n @IsNotEmpty()\n @IsInt()\n id: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => MEMBER_TYPE_REVERSE[value])\n type: MEMBER_TYPE\n\n @IsOptional()\n @IsString()\n permissions?: string = ''\n\n @IsOptional()\n @IsInt()\n linkId?: number\n\n // used only to update the link\n @IsOptional()\n @ValidateNested()\n @Type(() => CreateOrUpdateLinkDto)\n linkSettings?: CreateOrUpdateLinkDto = null\n}\n\nexport class ShareFileSpaceRootDto {\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n alias: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n name: string\n}\n\nexport class ShareFileSpaceDto {\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n alias: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n name: string\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareFileSpaceRootDto)\n root: ShareFileSpaceRootDto\n}\n\nexport class ShareParentDto {\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n alias: string\n}\n\nexport class ShareFileDto implements Omit<FileSpace, 'mime' | 'name' | 'inTrash' | 'isDir'> {\n @IsNotEmpty()\n @IsInt()\n id: number\n\n @ValidateIf((_, ownerId) => ownerId === null || typeof ownerId === 'number')\n ownerId: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => sanitizePath(value))\n path: string\n\n @IsOptional()\n @IsString()\n permissions?: string\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareFileSpaceDto)\n space: ShareFileSpaceDto\n}\n\nexport class CreateOrUpdateShareDto {\n @IsOptional()\n @IsInt()\n id?: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n name: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n alias?: string\n\n @IsOptional()\n @IsEnum(SHARE_TYPE)\n type?: SHARE_TYPE\n\n @IsOptional()\n @IsString()\n description?: string\n\n @IsOptional()\n @IsString()\n externalPath?: string = null\n\n @IsOptional()\n @IsBoolean()\n enabled?: boolean\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareParentDto)\n parent?: ShareParentDto\n\n @IsOptional()\n @ValidateIf((_, file) => !_.externalPath && file?.id)\n @ValidateNested()\n @Type(() => ShareFileDto)\n file?: ShareFileDto\n\n @IsOptional()\n @IsArray()\n @ValidateNested({ each: true })\n @Type(() => ShareMemberDto)\n // contains members (users, guests, links, groups, personal groups)\n members?: ShareMemberDto[] = []\n\n @IsOptional()\n @IsArray()\n @ValidateNested({ each: true })\n @Type(() => ShareMemberDto)\n // contains links\n links?: ShareMemberDto[] = []\n}\n"],"names":["CreateOrUpdateShareDto","ShareFileDto","ShareFileSpaceDto","ShareFileSpaceRootDto","ShareMemberDto","ShareParentDto","permissions","linkSettings","value","MEMBER_TYPE_REVERSE","CreateOrUpdateLinkDto","sanitizeName","trim","_","ownerId","sanitizePath","externalPath","members","links","file","id","each"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QA8FYA;eAAAA;;QAvBAC;eAAAA;;QAxBAC;eAAAA;;QAZAC;eAAAA;;QAzBAC;eAAAA;;QAsDAC;eAAAA;;;kCA9DmB;gCACgF;uBAErE;uCACL;wBACW;wBACtB;;;;;;;;;;AAEpB,IAAA,AAAMD,iBAAN,MAAMA;;aAYXE,cAAuB;QAMvB,+BAA+B;aAI/BC,eAAuC;;AACzC;;;;;;;;;sCAhBc,EAAEC,KAAK,EAAE,GAAKC,2BAAmB,CAACD,MAAM;;;;;;;;;;;;;;;;oCAcxCE,4CAAqB;;;AAI5B,IAAA,AAAMP,wBAAN,MAAMA;AAUb;;;;sCAPc,EAAEK,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;sCAKpD,EAAEJ,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;AAI3D,IAAA,AAAMV,oBAAN,MAAMA;AAeb;;;;sCAZc,EAAEM,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;;;;sCAKtC,EAAEJ,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;;;;oCAKtCT;;;AAIP,IAAA,AAAME,iBAAN,MAAMA;AAKb;;;;sCAFc,EAAEG,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;AAI7C,IAAA,AAAMX,eAAN,MAAMA;AAqBb;;;;;;;qCAhBeY,GAAGC,UAAYA,YAAY,QAAQ,OAAOA,YAAY;;;;;;sCAKvD,EAAEN,KAAK,EAAE,GAAKO,IAAAA,mBAAY,EAACP;;;;;;;;;;;oCAS3BN;;;AAIP,IAAA,AAAMF,yBAAN,MAAMA;;aAyBXgB,eAAwB;aAqBxB,mEAAmE;QACnEC,UAA6B,EAAE;aAM/B,iBAAiB;QACjBC,QAA2B,EAAE;;AAC/B;;;;;;;;;sCAhDc,EAAEV,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;sCAKpD,EAAEJ,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;oCAqBpDP;;;;;qCAICQ,GAAGM,OAAS,CAACN,EAAEG,YAAY,IAAIG,MAAMC;;oCAEtCnB;;;;;;;QAKMoB,MAAM;;oCACZjB;;;;;;;QAMMiB,MAAM;;oCACZjB"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/shares/dto/create-or-update-share.dto.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 { Transform, Type } from 'class-transformer'\nimport { IsArray, IsBoolean, IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, ValidateIf, ValidateNested } from 'class-validator'\nimport { FileSpace } from '../../files/interfaces/file-space.interface'\nimport { sanitizeName, sanitizePath } from '../../files/utils/files'\nimport { CreateOrUpdateLinkDto } from '../../links/dto/create-or-update-link.dto'\nimport { MEMBER_TYPE, MEMBER_TYPE_REVERSE } from '../../users/constants/member'\nimport { SHARE_TYPE } from '../constants/shares'\n\nexport class ShareMemberDto {\n @IsNotEmpty()\n @IsInt()\n id: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => MEMBER_TYPE_REVERSE[value])\n type: MEMBER_TYPE\n\n @IsOptional()\n @IsString()\n permissions?: string = ''\n\n @IsOptional()\n @IsInt()\n linkId?: number\n\n // used only to update the link\n @IsOptional()\n @ValidateNested()\n @Type(() => CreateOrUpdateLinkDto)\n linkSettings?: CreateOrUpdateLinkDto = null\n}\n\nexport class ShareFileSpaceRootDto {\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n alias: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n name: string\n}\n\nexport class ShareFileSpaceDto {\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n alias: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n name: string\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareFileSpaceRootDto)\n root: ShareFileSpaceRootDto\n}\n\nexport class ShareParentDto {\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => (value ? value.trim() : ''))\n alias: string\n}\n\nexport class ShareFileDto implements Omit<FileSpace, 'mime' | 'name' | 'inTrash' | 'isDir'> {\n @IsNotEmpty()\n @IsInt()\n id: number\n\n @ValidateIf((_, ownerId) => ownerId === null || typeof ownerId === 'number')\n ownerId: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => sanitizePath(value))\n path: string\n\n @IsOptional()\n @IsString()\n permissions?: string\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareFileSpaceDto)\n space: ShareFileSpaceDto\n}\n\nexport class CreateOrUpdateShareDto {\n @IsOptional()\n @IsInt()\n id?: number\n\n @IsNotEmpty()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n name: string\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => (value ? sanitizeName(value.trim()) : ''))\n alias?: string\n\n @IsOptional()\n @IsEnum(SHARE_TYPE)\n type?: SHARE_TYPE\n\n @IsOptional()\n @IsString()\n description?: string\n\n @IsOptional()\n @IsString()\n externalPath?: string = null\n\n @IsOptional()\n @IsBoolean()\n enabled?: boolean\n\n @IsOptional()\n @IsInt()\n storageQuota?: number = null\n\n @IsOptional()\n @IsBoolean()\n storageIndexing?: boolean\n\n @IsOptional()\n @ValidateNested()\n @Type(() => ShareParentDto)\n parent?: ShareParentDto\n\n @IsOptional()\n @ValidateIf((_, file) => !_.externalPath && file?.id)\n @ValidateNested()\n @Type(() => ShareFileDto)\n file?: ShareFileDto\n\n @IsOptional()\n @IsArray()\n @ValidateNested({ each: true })\n @Type(() => ShareMemberDto)\n // contains members (users, guests, links, groups, personal groups)\n members?: ShareMemberDto[] = []\n\n @IsOptional()\n @IsArray()\n @ValidateNested({ each: true })\n @Type(() => ShareMemberDto)\n // contains links\n links?: ShareMemberDto[] = []\n}\n"],"names":["CreateOrUpdateShareDto","ShareFileDto","ShareFileSpaceDto","ShareFileSpaceRootDto","ShareMemberDto","ShareParentDto","permissions","linkSettings","value","MEMBER_TYPE_REVERSE","CreateOrUpdateLinkDto","sanitizeName","trim","_","ownerId","sanitizePath","externalPath","storageQuota","members","links","file","id","each"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QA8FYA;eAAAA;;QAvBAC;eAAAA;;QAxBAC;eAAAA;;QAZAC;eAAAA;;QAzBAC;eAAAA;;QAsDAC;eAAAA;;;kCA9DmB;gCACgF;uBAErE;uCACL;wBACW;wBACtB;;;;;;;;;;AAEpB,IAAA,AAAMD,iBAAN,MAAMA;;aAYXE,cAAuB;QAMvB,+BAA+B;aAI/BC,eAAuC;;AACzC;;;;;;;;;sCAhBc,EAAEC,KAAK,EAAE,GAAKC,2BAAmB,CAACD,MAAM;;;;;;;;;;;;;;;;oCAcxCE,4CAAqB;;;AAI5B,IAAA,AAAMP,wBAAN,MAAMA;AAUb;;;;sCAPc,EAAEK,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;sCAKpD,EAAEJ,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;AAI3D,IAAA,AAAMV,oBAAN,MAAMA;AAeb;;;;sCAZc,EAAEM,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;;;;sCAKtC,EAAEJ,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;;;;oCAKtCT;;;AAIP,IAAA,AAAME,iBAAN,MAAMA;AAKb;;;;sCAFc,EAAEG,KAAK,EAAE,GAAMA,QAAQA,MAAMI,IAAI,KAAK;;;AAI7C,IAAA,AAAMX,eAAN,MAAMA;AAqBb;;;;;;;qCAhBeY,GAAGC,UAAYA,YAAY,QAAQ,OAAOA,YAAY;;;;;;sCAKvD,EAAEN,KAAK,EAAE,GAAKO,IAAAA,mBAAY,EAACP;;;;;;;;;;;oCAS3BN;;;AAIP,IAAA,AAAMF,yBAAN,MAAMA;;aAyBXgB,eAAwB;aAQxBC,eAAwB;aAqBxB,mEAAmE;QACnEC,UAA6B,EAAE;aAM/B,iBAAiB;QACjBC,QAA2B,EAAE;;AAC/B;;;;;;;;;sCAxDc,EAAEX,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;sCAKpD,EAAEJ,KAAK,EAAE,GAAMA,QAAQG,IAAAA,mBAAY,EAACH,MAAMI,IAAI,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA6BpDP;;;;;qCAICQ,GAAGO,OAAS,CAACP,EAAEG,YAAY,IAAII,MAAMC;;oCAEtCpB;;;;;;;QAKMqB,MAAM;;oCACZlB;;;;;;;QAMMkB,MAAM;;oCACZlB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-props.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 */\nimport type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { Member } from '../../users/interfaces/member.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport class ShareProps\n implements Pick<Share, 'id' | 'ownerId' | 'name' | 'alias' | 'enabled' | 'description' | 'externalPath' | 'createdAt' | 'modifiedAt' | 'disabledAt'>\n{\n id: number\n ownerId: number\n alias: string\n name: string\n description: string\n enabled: boolean\n externalPath: string\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n parent: Pick<Share, 'id' | 'ownerId' | 'alias' | 'name'>\n file: FileSpace\n\n // Extra properties\n members: Member[] = []\n}\n"],"names":["ShareProps","members"],"mappings":"AAAA;;;;CAIC;;;;+BAKYA;;;eAAAA;;;AAAN,IAAA,AAAMA,aAAN,MAAMA;;QAgBX,mBAAmB;aACnBC,UAAoB,EAAE;;AACxB"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-props.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 */\nimport type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { Member } from '../../users/interfaces/member.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport class ShareProps\n implements\n Pick<\n Share,\n | 'id'\n | 'ownerId'\n | 'name'\n | 'alias'\n | 'enabled'\n | 'description'\n | 'externalPath'\n | 'createdAt'\n | 'modifiedAt'\n | 'disabledAt'\n | 'storageUsage'\n | 'storageQuota'\n | 'storageIndexing'\n >\n{\n id: number\n ownerId: number\n alias: string\n name: string\n description: string\n enabled: boolean\n externalPath: string\n storageUsage: number\n storageQuota: number\n storageIndexing: boolean\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n parent: Pick<Share, 'id' | 'ownerId' | 'alias' | 'name'>\n file: FileSpace\n\n // Extra properties\n members: Member[] = []\n}\n"],"names":["ShareProps","members"],"mappings":"AAAA;;;;CAIC;;;;+BAKYA;;;eAAAA;;;AAAN,IAAA,AAAMA,aAAN,MAAMA;;QAmCX,mBAAmB;aACnBC,UAAoB,EAAE;;AACxB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/shares/schemas/share.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 { shares } from './shares.schema'\n\ntype ShareSchema = typeof shares.$inferSelect\n\nexport class Share implements ShareSchema {\n id: number\n ownerId: number\n parentId: number\n spaceId: number\n spaceRootId: number\n fileId: number\n externalPath: string\n type: number\n alias: string\n name: string\n enabled: boolean\n description: string\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n}\n"],"names":["Share"],"mappings":"AAAA;;;;CAIC;;;;+BAMYA;;;eAAAA;;;AAAN,IAAA,AAAMA,QAAN,MAAMA;AAgBb"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/shares/schemas/share.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 { shares } from './shares.schema'\n\ntype ShareSchema = typeof shares.$inferSelect\n\nexport class Share implements ShareSchema {\n id: number\n ownerId: number\n parentId: number\n spaceId: number\n spaceRootId: number\n fileId: number\n externalPath: string\n type: 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":["Share"],"mappings":"AAAA;;;;CAIC;;;;+BAMYA;;;eAAAA;;;AAAN,IAAA,AAAMA,QAAN,MAAMA;AAmBb"}
@@ -69,6 +69,15 @@ const shares = (0, _mysqlcore.mysqlTable)('shares', {
69
69
  description: (0, _mysqlcore.varchar)('description', {
70
70
  length: 255
71
71
  }),
72
+ storageUsage: (0, _mysqlcore.bigint)('storageUsage', {
73
+ mode: 'number',
74
+ unsigned: true
75
+ }).default(0).notNull(),
76
+ storageQuota: (0, _mysqlcore.bigint)('storageQuota', {
77
+ mode: 'number',
78
+ unsigned: true
79
+ }),
80
+ storageIndexing: (0, _mysqlcore.boolean)('storageIndexing').default(true).notNull(),
72
81
  createdAt: (0, _mysqlcore.datetime)('createdAt', {
73
82
  mode: 'date'
74
83
  }).default((0, _drizzleorm.sql)`CURRENT_TIMESTAMP`).notNull(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/shares/schemas/shares.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 } from 'drizzle-orm'\nimport { AnyMySqlColumn, bigint, boolean, datetime, index, mysqlTable, tinyint, uniqueIndex, varchar } from 'drizzle-orm/mysql-core'\nimport { files } from '../../files/schemas/files.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { users } from '../../users/schemas/users.schema'\n\n/*\n type:\n 0: common\n 1: share link\n ownerId: share owner\n parentId: parent share\n spaceId:\n - used to save the provenance of the space\n spaceRootId:\n - used to save the provenance of the space root (spaceId required)\n - if fileId is not defined, the share becomes a gateway to the space root (avoids to create entry file)\n - if fileId is defined, the spaceId and spaceRootId are used to translate the file location (in combination with file.path)\n fileId is defined if a file is related:\n - file.ownerId : personal space case\n - file.spaceId : space case\n - file.spaceId & file.spaceExternalRootId : space with an external root\n - file.shareExternalId: external path from share\n externalPath: if define the share use an external location\n alias: used to navigate over web & webdav, must be unique\n name: set by user and showed to others\n\n parent: if the share is a child share :\n - parentId is required\n - spaceId & spaceRootId must have the same value as their parents\n - fileId is required when the file is inside the parent share\n - fileId is not required when child share is directly linked to parent share (with a space root or an external path)\n - if the share has an external path : file.shareExternalId must match with the first parent share\n*/\n\nexport const shares = mysqlTable(\n 'shares',\n {\n id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),\n ownerId: bigint('ownerId', { mode: 'number', unsigned: true }).references(() => users.id, { onDelete: 'cascade' }),\n parentId: bigint('parentId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => shares.id, { onDelete: 'cascade' }),\n spaceId: bigint('spaceId', { mode: 'number', unsigned: true }).references(() => spaces.id, { onDelete: 'cascade' }),\n spaceRootId: bigint('spaceRootId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => spacesRoots.id, { onDelete: 'cascade' }),\n fileId: bigint('fileId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => files.id, { onDelete: 'cascade' }),\n externalPath: varchar('externalPath', { length: 4096 }),\n type: tinyint('type', { unsigned: true }).default(0).notNull(),\n alias: varchar('alias', { length: 255 }).notNull(),\n name: varchar('name', { length: 255 }).notNull(),\n enabled: boolean('enabled').default(true).notNull(),\n description: varchar('description', { length: 255 }),\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) => [\n uniqueIndex('alias_idx').on(table.alias),\n index('parent_idx').on(table.parentId),\n index('owner_idx').on(table.ownerId),\n index('space_idx').on(table.spaceId),\n index('space_root_idx').on(table.spaceRootId),\n index('file_idx').on(table.fileId),\n index('type_idx').on(table.type)\n ]\n)\n"],"names":["shares","mysqlTable","id","bigint","mode","unsigned","autoincrement","primaryKey","ownerId","references","users","onDelete","parentId","spaceId","spaces","spaceRootId","spacesRoots","fileId","files","externalPath","varchar","length","type","tinyint","default","notNull","alias","name","enabled","boolean","description","createdAt","datetime","sql","modifiedAt","disabledAt","table","uniqueIndex","on","index"],"mappings":"AAAA;;;;CAIC;;;;+BAsCYA;;;eAAAA;;;4BApCO;2BACwF;6BACtF;mCACM;8BACL;6BACD;AA+Bf,MAAMA,SAASC,IAAAA,qBAAU,EAC9B,UACA;IACEC,IAAIC,IAAAA,iBAAM,EAAC,MAAM;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGC,aAAa,GAAGC,UAAU;IAC/EC,SAASL,IAAAA,iBAAM,EAAC,WAAW;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGI,UAAU,CAAC,IAAMC,kBAAK,CAACR,EAAE,EAAE;QAAES,UAAU;IAAU;IAChHC,UAAUT,IAAAA,iBAAM,EAAC,YAAY;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGI,UAAU,CAAC,IAAsBT,OAAOE,EAAE,EAAE;QAAES,UAAU;IAAU;IACnIE,SAASV,IAAAA,iBAAM,EAAC,WAAW;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGI,UAAU,CAAC,IAAMK,oBAAM,CAACZ,EAAE,EAAE;QAAES,UAAU;IAAU;IACjHI,aAAaZ,IAAAA,iBAAM,EAAC,eAAe;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGI,UAAU,CAAC,IAAsBO,8BAAW,CAACd,EAAE,EAAE;QAAES,UAAU;IAAU;IAC9IM,QAAQd,IAAAA,iBAAM,EAAC,UAAU;QAAEC,MAAM;QAAUC,UAAU;IAAK,GAAGI,UAAU,CAAC,IAAsBS,kBAAK,CAAChB,EAAE,EAAE;QAAES,UAAU;IAAU;IAC9HQ,cAAcC,IAAAA,kBAAO,EAAC,gBAAgB;QAAEC,QAAQ;IAAK;IACrDC,MAAMC,IAAAA,kBAAO,EAAC,QAAQ;QAAElB,UAAU;IAAK,GAAGmB,OAAO,CAAC,GAAGC,OAAO;IAC5DC,OAAON,IAAAA,kBAAO,EAAC,SAAS;QAAEC,QAAQ;IAAI,GAAGI,OAAO;IAChDE,MAAMP,IAAAA,kBAAO,EAAC,QAAQ;QAAEC,QAAQ;IAAI,GAAGI,OAAO;IAC9CG,SAASC,IAAAA,kBAAO,EAAC,WAAWL,OAAO,CAAC,MAAMC,OAAO;IACjDK,aAAaV,IAAAA,kBAAO,EAAC,eAAe;QAAEC,QAAQ;IAAI;IAClDU,WAAWC,IAAAA,mBAAQ,EAAC,aAAa;QAAE5B,MAAM;IAAO,GAC7CoB,OAAO,CAACS,IAAAA,eAAG,CAAA,CAAC,iBAAiB,CAAC,EAC9BR,OAAO;IACVS,YAAYF,IAAAA,mBAAQ,EAAC,cAAc;QAAE5B,MAAM;IAAO,GAAGoB,OAAO,CAACS,IAAAA,eAAG,CAAA,CAAC,6CAA6C,CAAC;IAC/GE,YAAYH,IAAAA,mBAAQ,EAAC,cAAc;QAAE5B,MAAM;IAAO;AACpD,GACA,CAACgC,QAAU;QACTC,IAAAA,sBAAW,EAAC,aAAaC,EAAE,CAACF,MAAMV,KAAK;QACvCa,IAAAA,gBAAK,EAAC,cAAcD,EAAE,CAACF,MAAMxB,QAAQ;QACrC2B,IAAAA,gBAAK,EAAC,aAAaD,EAAE,CAACF,MAAM5B,OAAO;QACnC+B,IAAAA,gBAAK,EAAC,aAAaD,EAAE,CAACF,MAAMvB,OAAO;QACnC0B,IAAAA,gBAAK,EAAC,kBAAkBD,EAAE,CAACF,MAAMrB,WAAW;QAC5CwB,IAAAA,gBAAK,EAAC,YAAYD,EAAE,CAACF,MAAMnB,MAAM;QACjCsB,IAAAA,gBAAK,EAAC,YAAYD,EAAE,CAACF,MAAMd,IAAI;KAChC"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/shares/schemas/shares.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 } from 'drizzle-orm'\nimport { AnyMySqlColumn, bigint, boolean, datetime, index, mysqlTable, tinyint, uniqueIndex, varchar } from 'drizzle-orm/mysql-core'\nimport { files } from '../../files/schemas/files.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { users } from '../../users/schemas/users.schema'\n\n/*\n type:\n 0: common\n 1: share link\n ownerId: share owner\n parentId: parent share\n spaceId:\n - used to save the provenance of the space\n spaceRootId:\n - used to save the provenance of the space root (spaceId required)\n - if fileId is not defined, the share becomes a gateway to the space root (avoids to create entry file)\n - if fileId is defined, the spaceId and spaceRootId are used to translate the file location (in combination with file.path)\n fileId is defined if a file is related:\n - file.ownerId : personal space case\n - file.spaceId : space case\n - file.spaceId & file.spaceExternalRootId : space with an external root\n - file.shareExternalId: external path from share\n externalPath: if define the share use an external location\n alias: used to navigate over web & webdav, must be unique\n name: set by user and showed to others\n\n parent: if the share is a child share:\n - parentId is required\n - spaceId & spaceRootId must have the same value as their parents\n - fileId is required when the file is inside the parent share\n - fileId is not required when child share is directly linked to parent share (with a space root or an external path)\n - if the share has an external path: file.shareExternalId must match with the first parent share\n\n storageQuota:\n 0 : no storage\n null : unlimited\n other: limited to value\n\n Storage properties are only used for shares that have an external path.\n*/\n\nexport const shares = mysqlTable(\n 'shares',\n {\n id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),\n ownerId: bigint('ownerId', { mode: 'number', unsigned: true }).references(() => users.id, { onDelete: 'cascade' }),\n parentId: bigint('parentId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => shares.id, { onDelete: 'cascade' }),\n spaceId: bigint('spaceId', { mode: 'number', unsigned: true }).references(() => spaces.id, { onDelete: 'cascade' }),\n spaceRootId: bigint('spaceRootId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => spacesRoots.id, { onDelete: 'cascade' }),\n fileId: bigint('fileId', { mode: 'number', unsigned: true }).references((): AnyMySqlColumn => files.id, { onDelete: 'cascade' }),\n externalPath: varchar('externalPath', { length: 4096 }),\n type: tinyint('type', { unsigned: true }).default(0).notNull(),\n alias: varchar('alias', { length: 255 }).notNull(),\n name: varchar('name', { length: 255 }).notNull(),\n enabled: boolean('enabled').default(true).notNull(),\n description: varchar('description', { length: 255 }),\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) => [\n uniqueIndex('alias_idx').on(table.alias),\n index('parent_idx').on(table.parentId),\n index('owner_idx').on(table.ownerId),\n index('space_idx').on(table.spaceId),\n index('space_root_idx').on(table.spaceRootId),\n index('file_idx').on(table.fileId),\n index('type_idx').on(table.type)\n ]\n)\n"],"names":["shares","mysqlTable","id","bigint","mode","unsigned","autoincrement","primaryKey","ownerId","references","users","onDelete","parentId","spaceId","spaces","spaceRootId","spacesRoots","fileId","files","externalPath","varchar","length","type","tinyint","default","notNull","alias","name","enabled","boolean","description","storageUsage","storageQuota","storageIndexing","createdAt","datetime","sql","modifiedAt","disabledAt","table","uniqueIndex","on","index"],"mappings":"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"}
@@ -23,6 +23,7 @@ const _links = require("../../links/constants/links");
23
23
  const _linksqueriesservice = require("../../links/services/links-queries.service");
24
24
  const _notifications = require("../../notifications/constants/notifications");
25
25
  const _notificationsmanagerservice = require("../../notifications/services/notifications-manager.service");
26
+ const _cache = require("../../spaces/constants/cache");
26
27
  const _spaces = require("../../spaces/constants/spaces");
27
28
  const _spaceenvmodel = require("../../spaces/models/space-env.model");
28
29
  const _spacesqueriesservice = require("../../spaces/services/spaces-queries.service");
@@ -66,7 +67,7 @@ let SharesManager = class SharesManager {
66
67
  } else if (share.file?.space?.alias) {
67
68
  share.file.ownerId = null;
68
69
  // retrieve space permissions (cached query)
69
- const spacePermissions = await this.spaceQueries.permissions(user.id, share.file.space.alias, share.file.space.root?.alias);
70
+ const spacePermissions = await this.spacesQueries.permissions(user.id, share.file.space.alias, share.file.space.root?.alias);
70
71
  if (!spacePermissions) {
71
72
  this.logger.warn(`${this.setAllowedPermissions.name} - missing space permissions : ${JSON.stringify(share)}`);
72
73
  throw new _common.HttpException('Space not found', _common.HttpStatus.NOT_FOUND);
@@ -106,6 +107,8 @@ let SharesManager = class SharesManager {
106
107
  description: createOrUpdateShareDto.description,
107
108
  externalPath: createOrUpdateShareDto.externalPath,
108
109
  enabled: createOrUpdateShareDto.enabled,
110
+ storageQuota: createOrUpdateShareDto.storageQuota,
111
+ storageIndexing: createOrUpdateShareDto.storageIndexing,
109
112
  disabledAt: createOrUpdateShareDto.enabled ? null : new Date(),
110
113
  type: createOrUpdateShareDto.type || _shares.SHARE_TYPE.COMMON
111
114
  };
@@ -133,9 +136,9 @@ let SharesManager = class SharesManager {
133
136
  ...await (0, _files.getProps)(realPath, createOrUpdateShareDto.file.path),
134
137
  id: createOrUpdateShareDto.file.id
135
138
  };
136
- share.fileId = await this.spaceQueries.getOrCreateUserFile(user.id, fileProps);
139
+ share.fileId = await this.spacesQueries.getOrCreateUserFile(user.id, fileProps);
137
140
  } else if (createOrUpdateShareDto.file.space?.alias) {
138
- /* SPACE CASE */ const spacePermissions = await this.spaceQueries.permissions(user.id, createOrUpdateShareDto.file.space.alias, createOrUpdateShareDto.file.space.root.alias);
141
+ /* SPACE CASE */ const spacePermissions = await this.spacesQueries.permissions(user.id, createOrUpdateShareDto.file.space.alias, createOrUpdateShareDto.file.space.root.alias);
139
142
  if (!spacePermissions) {
140
143
  throw new _common.HttpException('Space not found', _common.HttpStatus.NOT_FOUND);
141
144
  }
@@ -175,7 +178,7 @@ let SharesManager = class SharesManager {
175
178
  id: undefined
176
179
  };
177
180
  // get or create file id
178
- share.fileId = await this.spaceQueries.getOrCreateSpaceFile(createOrUpdateShareDto.file.id, fileProps, space.dbFile);
181
+ share.fileId = await this.spacesQueries.getOrCreateSpaceFile(createOrUpdateShareDto.file.id, fileProps, space.dbFile);
179
182
  }
180
183
  } else {
181
184
  // unexpected case
@@ -190,17 +193,20 @@ let SharesManager = class SharesManager {
190
193
  return this.getShareWithMembers(user, share.id);
191
194
  }
192
195
  async updateShare(user, shareId, createOrUpdateShareDto, asAdmin = false) {
193
- // asAdmin : true if the user is the owner of the parent share or if the share is requested from the administration
196
+ // asAdmin: true if the user is the owner of the parent share or if the share is requested from the administration
194
197
  const share = await this.getShareWithMembers(user, shareId, asAdmin);
195
- // check & update share info
198
+ // check and update share info
196
199
  const shareDiffProps = {
197
200
  modifiedAt: new Date()
198
201
  };
199
- for (const prop of [
202
+ const props = [
200
203
  'name',
201
204
  'description',
202
- 'enabled'
203
- ]){
205
+ 'enabled',
206
+ 'storageQuota',
207
+ 'storageIndexing'
208
+ ];
209
+ for (const prop of props){
204
210
  if (createOrUpdateShareDto[prop] !== share[prop]) {
205
211
  shareDiffProps[prop] = createOrUpdateShareDto[prop];
206
212
  if (prop === 'name') {
@@ -211,9 +217,9 @@ let SharesManager = class SharesManager {
211
217
  }
212
218
  }
213
219
  // update in db
214
- this.sharesQueries.updateShare(shareDiffProps, {
215
- id: shareId
216
- }).catch((e)=>this.logger.error(`${this.updateShare.name} - ${e}`));
220
+ if (!await this.sharesQueries.updateShare(shareId, shareDiffProps)) {
221
+ throw new _common.HttpException('Unable to update share', _common.HttpStatus.INTERNAL_SERVER_ERROR);
222
+ }
217
223
  // check & update members
218
224
  const linkMembers = await this.createOrUpdateLinksAsMembers(user, share, _links.LINK_TYPE.SHARE, createOrUpdateShareDto.links);
219
225
  // intersect share permissions for members
@@ -316,7 +322,7 @@ let SharesManager = class SharesManager {
316
322
  ...await (0, _files.getProps)(pShareEnv.realPath, pShareEnv.dbFile.path),
317
323
  id: undefined
318
324
  };
319
- fileId = await this.spaceQueries.getOrCreateSpaceFile(createOrUpdateShareDto.file.id, fileProps, pShareEnv.dbFile);
325
+ fileId = await this.spacesQueries.getOrCreateSpaceFile(createOrUpdateShareDto.file.id, fileProps, pShareEnv.dbFile);
320
326
  }
321
327
  const share = {
322
328
  name: createOrUpdateShareDto.name,
@@ -627,6 +633,29 @@ let SharesManager = class SharesManager {
627
633
  async deleteLinkMembers(members) {
628
634
  await this.deleteGuestLinks(members);
629
635
  }
636
+ async updateSharesExternalPathQuota(shareId) {
637
+ for (const share of (await this.sharesQueries.sharesQuotaExternalPaths(shareId))){
638
+ if (!await (0, _files.isPathExists)(share.externalPath)) {
639
+ this.logger.warn(`${this.updateSharesExternalPathQuota.name} - *${share.alias}* home path does not exist`);
640
+ continue;
641
+ }
642
+ const [size, errors] = await (0, _files.dirSize)(share.externalPath);
643
+ for (const [path, error] of Object.entries(errors)){
644
+ this.logger.warn(`${this.updateSharesExternalPathQuota.name} - unable to get size for *${share.alias}* on ${path} : ${error}`);
645
+ }
646
+ const shareQuota = {
647
+ storageUsage: size,
648
+ storageQuota: share.storageQuota
649
+ };
650
+ this.sharesQueries.cache.set(`${_cache.CACHE_QUOTA_SHARE_PREFIX}-${share.id}`, shareQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updateSharesExternalPathQuota.name} - ${e}`));
651
+ if (share.storageUsage !== shareQuota.storageUsage) {
652
+ this.logger.log(`${this.updateSharesExternalPathQuota.name} - share *${share.alias}* (${share.id}) : storage usage updated : ${shareQuota.storageUsage}`);
653
+ await this.sharesQueries.updateShare(share.id, {
654
+ storageUsage: shareQuota.storageUsage
655
+ });
656
+ }
657
+ }
658
+ }
630
659
  async updateMembers(user, share, oldMembers, currentMembers) {
631
660
  if (oldMembers.length === 0 && currentMembers.length === 0) {
632
661
  return;
@@ -849,8 +878,8 @@ let SharesManager = class SharesManager {
849
878
  ], null, false);
850
879
  await this.sharesQueries.deleteShare(share.id);
851
880
  this.logger.log(`${this.removeShareFromOwners.name} - share *${share.alias}* (${share.id}) from owner (${share.ownerId}) was removed`);
852
- // clear cache & notify users
853
- if (!fromUserId || fromUserId !== share.ownerId) {
881
+ // clear cache and notify users
882
+ if (share.ownerId && (!fromUserId || fromUserId !== share.ownerId)) {
854
883
  this.clearCachePermissionsAndOrNotify(share, _constants.ACTION.DELETE_PERMANENTLY, [
855
884
  share.ownerId
856
885
  ]).catch((e)=>this.logger.error(`${this.removeShareFromOwners.name} - ${e}`));
@@ -985,11 +1014,11 @@ let SharesManager = class SharesManager {
985
1014
  action: action
986
1015
  }).catch((e)=>this.logger.error(`${this.notifyGuestLink.name} - ${e}`));
987
1016
  }
988
- constructor(contextManager, notificationsManager, sharesQueries, spaceQueries, usersQueries, linksQueries){
1017
+ constructor(contextManager, notificationsManager, sharesQueries, spacesQueries, usersQueries, linksQueries){
989
1018
  this.contextManager = contextManager;
990
1019
  this.notificationsManager = notificationsManager;
991
1020
  this.sharesQueries = sharesQueries;
992
- this.spaceQueries = spaceQueries;
1021
+ this.spacesQueries = spacesQueries;
993
1022
  this.usersQueries = usersQueries;
994
1023
  this.linksQueries = linksQueries;
995
1024
  this.logger = new _common.Logger(SharesManager.name);