@sync-in/server 1.9.3 → 1.10.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 (349) hide show
  1. package/CHANGELOG.md +41 -4
  2. package/environment/environment.dist.yaml +15 -5
  3. package/package.json +18 -19
  4. package/server/app.bootstrap.js +1 -1
  5. package/server/app.bootstrap.js.map +1 -1
  6. package/server/app.constants.js +3 -2
  7. package/server/app.constants.js.map +1 -1
  8. package/server/applications/files/constants/cache.js +2 -5
  9. package/server/applications/files/constants/cache.js.map +1 -1
  10. package/server/applications/files/constants/files.js +4 -0
  11. package/server/applications/files/constants/files.js.map +1 -1
  12. package/server/applications/files/constants/operations.js +4 -0
  13. package/server/applications/files/constants/operations.js.map +1 -1
  14. package/server/applications/files/constants/routes.js +1 -26
  15. package/server/applications/files/constants/routes.js.map +1 -1
  16. package/server/applications/files/files.config.js +15 -39
  17. package/server/applications/files/files.config.js.map +1 -1
  18. package/server/applications/files/files.controller.js +4 -4
  19. package/server/applications/files/files.controller.js.map +1 -1
  20. package/server/applications/files/files.module.js +12 -9
  21. package/server/applications/files/files.module.js.map +1 -1
  22. package/server/applications/files/interfaces/file-lock.interface.js.map +1 -1
  23. package/server/applications/files/interfaces/file-props.interface.js.map +1 -1
  24. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js +32 -0
  25. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js.map +1 -0
  26. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js +280 -0
  27. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js.map +1 -0
  28. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js +552 -0
  29. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js.map +1 -0
  30. package/server/applications/files/modules/collabora-online/collabora-online.config.js +40 -0
  31. package/server/applications/files/modules/collabora-online/collabora-online.config.js.map +1 -0
  32. package/server/applications/files/modules/collabora-online/collabora-online.constants.js +110 -0
  33. package/server/applications/files/modules/collabora-online/collabora-online.constants.js.map +1 -0
  34. package/server/applications/files/modules/collabora-online/collabora-online.controller.js +128 -0
  35. package/server/applications/files/modules/collabora-online/collabora-online.controller.js.map +1 -0
  36. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js +47 -0
  37. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js.map +1 -0
  38. package/server/applications/files/{interfaces/only-office-config.interface.js → modules/collabora-online/collabora-online.dtos.js} +1 -1
  39. package/server/applications/files/modules/collabora-online/collabora-online.dtos.js.map +1 -0
  40. package/server/applications/files/{guards/files-only-office.guard.js → modules/collabora-online/collabora-online.guard.js} +7 -21
  41. package/server/applications/files/modules/collabora-online/collabora-online.guard.js.map +1 -0
  42. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js +86 -0
  43. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js.map +1 -0
  44. package/server/applications/files/modules/collabora-online/collabora-online.interface.js +10 -0
  45. package/server/applications/files/modules/collabora-online/collabora-online.interface.js.map +1 -0
  46. package/server/applications/files/modules/collabora-online/collabora-online.module.js +41 -0
  47. package/server/applications/files/modules/collabora-online/collabora-online.module.js.map +1 -0
  48. package/server/applications/files/modules/collabora-online/collabora-online.routes.js +35 -0
  49. package/server/applications/files/modules/collabora-online/collabora-online.routes.js.map +1 -0
  50. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js +59 -0
  51. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js.map +1 -0
  52. package/server/applications/files/modules/collabora-online/collabora-online.utils.js +28 -0
  53. package/server/applications/files/modules/collabora-online/collabora-online.utils.js.map +1 -0
  54. package/server/applications/files/{decorators → modules/only-office}/only-office-environment.decorator.js +5 -5
  55. package/server/applications/files/modules/only-office/only-office-environment.decorator.js.map +1 -0
  56. package/server/applications/files/{services/files-only-office-manager.service.js → modules/only-office/only-office-manager.service.js} +101 -97
  57. package/server/applications/files/modules/only-office/only-office-manager.service.js.map +1 -0
  58. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js +477 -0
  59. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js.map +1 -0
  60. package/server/applications/files/modules/only-office/only-office.config.js +51 -0
  61. package/server/applications/files/modules/only-office/only-office.config.js.map +1 -0
  62. package/server/applications/files/modules/only-office/only-office.constants.js +417 -0
  63. package/server/applications/files/modules/only-office/only-office.constants.js.map +1 -0
  64. package/server/applications/files/{files-only-office.controller.js → modules/only-office/only-office.controller.js} +35 -52
  65. package/server/applications/files/modules/only-office/only-office.controller.js.map +1 -0
  66. package/server/applications/files/{files-only-office.controller.spec.js → modules/only-office/only-office.controller.spec.js} +24 -21
  67. package/server/applications/files/modules/only-office/only-office.controller.spec.js.map +1 -0
  68. package/server/applications/files/modules/only-office/only-office.dtos.js +10 -0
  69. package/server/applications/files/modules/only-office/only-office.dtos.js.map +1 -0
  70. package/server/applications/files/modules/only-office/only-office.guard.js +40 -0
  71. package/server/applications/files/modules/only-office/only-office.guard.js.map +1 -0
  72. package/server/applications/files/{guards/files-only-office.guard.spec.js → modules/only-office/only-office.guard.spec.js} +15 -21
  73. package/server/applications/files/modules/only-office/only-office.guard.spec.js.map +1 -0
  74. package/server/applications/files/modules/only-office/only-office.interface.js +10 -0
  75. package/server/applications/files/modules/only-office/only-office.interface.js.map +1 -0
  76. package/server/applications/files/modules/only-office/only-office.module.js +41 -0
  77. package/server/applications/files/modules/only-office/only-office.module.js.map +1 -0
  78. package/server/applications/files/modules/only-office/only-office.routes.js +45 -0
  79. package/server/applications/files/modules/only-office/only-office.routes.js.map +1 -0
  80. package/server/applications/files/{guards/files-only-office.strategy.js → modules/only-office/only-office.strategy.js} +11 -11
  81. package/server/applications/files/modules/only-office/only-office.strategy.js.map +1 -0
  82. package/server/applications/files/services/files-lock-manager.service.js +25 -33
  83. package/server/applications/files/services/files-lock-manager.service.js.map +1 -1
  84. package/server/applications/files/services/files-manager.service.js +17 -16
  85. package/server/applications/files/services/files-manager.service.js.map +1 -1
  86. package/server/applications/files/services/files-methods.service.js +2 -2
  87. package/server/applications/files/services/files-methods.service.js.map +1 -1
  88. package/server/applications/files/services/files-methods.service.spec.js +5 -5
  89. package/server/applications/files/services/files-methods.service.spec.js.map +1 -1
  90. package/server/applications/files/services/files-recents.service.js +4 -0
  91. package/server/applications/files/services/files-recents.service.js.map +1 -1
  92. package/server/applications/files/services/files-scheduler.service.js +24 -5
  93. package/server/applications/files/services/files-scheduler.service.js.map +1 -1
  94. package/server/applications/files/utils/files.js +10 -2
  95. package/server/applications/files/utils/files.js.map +1 -1
  96. package/server/applications/links/constants/routes.js +5 -0
  97. package/server/applications/links/constants/routes.js.map +1 -1
  98. package/server/applications/links/interfaces/link-space.interface.js.map +1 -1
  99. package/server/applications/links/links.controller.js +25 -5
  100. package/server/applications/links/links.controller.js.map +1 -1
  101. package/server/applications/links/services/links-manager.service.js +43 -21
  102. package/server/applications/links/services/links-manager.service.js.map +1 -1
  103. package/server/applications/links/services/links-manager.service.spec.js +4 -3
  104. package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
  105. package/server/applications/links/services/links-queries.service.js +9 -2
  106. package/server/applications/links/services/links-queries.service.js.map +1 -1
  107. package/server/applications/shares/interfaces/share-link.interface.js.map +1 -1
  108. package/server/applications/shares/services/shares-manager.service.js +3 -0
  109. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  110. package/server/applications/shares/services/shares-manager.service.spec.js +2 -1
  111. package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
  112. package/server/applications/shares/services/shares-queries.service.js +1 -0
  113. package/server/applications/shares/services/shares-queries.service.js.map +1 -1
  114. package/server/applications/spaces/constants/spaces.js +2 -2
  115. package/server/applications/spaces/constants/spaces.js.map +1 -1
  116. package/server/applications/spaces/decorators/space-override-permission.decorator.js +18 -0
  117. package/server/applications/spaces/decorators/space-override-permission.decorator.js.map +1 -0
  118. package/server/applications/spaces/guards/space.guard.js +40 -33
  119. package/server/applications/spaces/guards/space.guard.js.map +1 -1
  120. package/server/applications/spaces/guards/space.guard.spec.js +10 -15
  121. package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
  122. package/server/applications/spaces/services/spaces-scheduler.service.js +9 -1
  123. package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
  124. package/server/applications/webdav/constants/webdav.js +4 -0
  125. package/server/applications/webdav/constants/webdav.js.map +1 -1
  126. package/server/applications/webdav/guards/webdav-protocol.guard.js +9 -8
  127. package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
  128. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +1 -1
  129. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -1
  130. package/server/applications/webdav/interfaces/webdav.interface.js.map +1 -1
  131. package/server/applications/webdav/services/webdav-methods.service.js +40 -17
  132. package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
  133. package/server/applications/webdav/services/webdav-methods.service.spec.js +2157 -1289
  134. package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
  135. package/server/applications/webdav/utils/webdav.js +8 -4
  136. package/server/applications/webdav/utils/webdav.js.map +1 -1
  137. package/server/applications/webdav/webdav.controller.js +4 -4
  138. package/server/applications/webdav/webdav.controller.js.map +1 -1
  139. package/server/authentication/guards/auth-token-access.guard.js +8 -3
  140. package/server/authentication/guards/auth-token-access.guard.js.map +1 -1
  141. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +1 -1
  142. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -1
  143. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +350 -4
  144. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -1
  145. package/server/configuration/config.environment.js +5 -1
  146. package/server/configuration/config.environment.js.map +1 -1
  147. package/server/configuration/config.interfaces.js.map +1 -1
  148. package/static/3rdpartylicenses.txt +507 -507
  149. package/static/assets/pdfjs/build/pdf.mjs +93 -33
  150. package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
  151. package/static/assets/pdfjs/build/pdf.sandbox.mjs +3 -3
  152. package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
  153. package/static/assets/pdfjs/build/pdf.worker.mjs +166 -54
  154. package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
  155. package/static/assets/pdfjs/version +1 -1
  156. package/static/assets/pdfjs/web/images/checkmark.svg +5 -0
  157. package/static/assets/pdfjs/web/images/pages_closeButton.svg +3 -0
  158. package/static/assets/pdfjs/web/images/pages_selected.svg +7 -0
  159. package/static/assets/pdfjs/web/images/pages_viewArrow.svg +3 -0
  160. package/static/assets/pdfjs/web/images/pages_viewButton.svg +3 -0
  161. package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -2
  162. package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -5
  163. package/static/assets/pdfjs/web/locale/cs/viewer.ftl +4 -6
  164. package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -2
  165. package/static/assets/pdfjs/web/locale/da/viewer.ftl +0 -2
  166. package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -2
  167. package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -2
  168. package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -2
  169. package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +6 -2
  170. package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -2
  171. package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +82 -17
  172. package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -2
  173. package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -2
  174. package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -2
  175. package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +0 -2
  176. package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -2
  177. package/static/assets/pdfjs/web/locale/eu/viewer.ftl +0 -2
  178. package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -2
  179. package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -2
  180. package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -5
  181. package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +3 -5
  182. package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -2
  183. package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -2
  184. package/static/assets/pdfjs/web/locale/hr/viewer.ftl +66 -0
  185. package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -2
  186. package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -2
  187. package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +3 -8
  188. package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -2
  189. package/static/assets/pdfjs/web/locale/id/viewer.ftl +0 -5
  190. package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -5
  191. package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -2
  192. package/static/assets/pdfjs/web/locale/ja/viewer.ftl +0 -14
  193. package/static/assets/pdfjs/web/locale/ka/viewer.ftl +4 -6
  194. package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -5
  195. package/static/assets/pdfjs/web/locale/kk/viewer.ftl +0 -2
  196. package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -2
  197. package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +1 -3
  198. package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -2
  199. package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +4 -2
  200. package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -2
  201. package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -2
  202. package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -2
  203. package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +35 -0
  204. package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -5
  205. package/static/assets/pdfjs/web/locale/ro/viewer.ftl +4 -6
  206. package/static/assets/pdfjs/web/locale/ru/viewer.ftl +3 -5
  207. package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -2
  208. package/static/assets/pdfjs/web/locale/sl/viewer.ftl +0 -2
  209. package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -2
  210. package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -2
  211. package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -2
  212. package/static/assets/pdfjs/web/locale/th/viewer.ftl +2 -2
  213. package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -2
  214. package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -2
  215. package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -2
  216. package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -2
  217. package/static/assets/pdfjs/web/viewer.css +1778 -835
  218. package/static/assets/pdfjs/web/viewer.html +167 -86
  219. package/static/assets/pdfjs/web/viewer.mjs +1106 -801
  220. package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
  221. package/static/chunk-27V66YJV.js +2 -0
  222. package/static/{chunk-WJYVS27M.js → chunk-27Z3SYRL.js} +1 -1
  223. package/static/{chunk-NFIES7BC.js → chunk-2RWLNKZH.js} +1 -1
  224. package/static/chunk-2YQ4SX3A.js +13 -0
  225. package/static/{chunk-GENTF6JM.js → chunk-3JYMJQYT.js} +1 -1
  226. package/static/chunk-3QTROEHV.js +1 -0
  227. package/static/{chunk-ZPI7RQ2S.js → chunk-3RPUQ22U.js} +1 -1
  228. package/static/{chunk-R6VB3INJ.js → chunk-3WZ6F3LC.js} +1 -1
  229. package/static/chunk-3ZLBVUCX.js +2 -0
  230. package/static/{chunk-5HCVWZMA.js → chunk-45AZ6ZML.js} +1 -1
  231. package/static/chunk-46TJLPJY.js +1 -0
  232. package/static/chunk-4NIYCYRS.js +2 -0
  233. package/static/{chunk-XXYMVRSH.js → chunk-4TPFERL6.js} +1 -1
  234. package/static/{chunk-CAZSNVMS.js → chunk-5O66CLTD.js} +1 -1
  235. package/static/chunk-6OEOADR6.js +1 -0
  236. package/static/chunk-6WMXMIE4.js +1 -0
  237. package/static/{chunk-NK2NMAJI.js → chunk-7VRYTDX4.js} +1 -1
  238. package/static/{chunk-ASBPYTLT.js → chunk-ARS47O5X.js} +1 -1
  239. package/static/chunk-B6HQYQYG.js +1 -0
  240. package/static/chunk-BCN4T5DO.js +2 -0
  241. package/static/{chunk-PKU4IIIR.js → chunk-CCZWPM7Q.js} +1 -1
  242. package/static/{chunk-QUSS6SUC.js → chunk-CMNMPG6Z.js} +1 -1
  243. package/static/{chunk-GDPJRUVU.js → chunk-CSVPAZHK.js} +1 -1
  244. package/static/{chunk-BJARRIS6.js → chunk-D55YR5X7.js} +4 -4
  245. package/static/{chunk-Z6RJZIDG.js → chunk-D5FQ72R4.js} +1 -1
  246. package/static/{chunk-4DF2SQD4.js → chunk-DGCVA6BM.js} +1 -1
  247. package/static/{chunk-TVJQXN73.js → chunk-DVCN3P7Q.js} +1 -1
  248. package/static/chunk-E32J777S.js +5 -0
  249. package/static/{chunk-5NHB7SV3.js → chunk-FIUF2JM4.js} +1 -1
  250. package/static/{chunk-RJOHDAPM.js → chunk-G3PL6YX3.js} +1 -1
  251. package/static/chunk-G7RZN7HN.js +1 -0
  252. package/static/{chunk-DDRGLHOP.js → chunk-GQHXYX6Z.js} +1 -1
  253. package/static/{chunk-5HYSNQR4.js → chunk-GWRAGN3M.js} +1 -1
  254. package/static/{chunk-ZC5ZDCDC.js → chunk-GXWGB7WO.js} +1 -1
  255. package/static/{chunk-25PWAXTJ.js → chunk-HGODIZTV.js} +1 -1
  256. package/static/{chunk-4KXJ6C4N.js → chunk-HZAB6F4Q.js} +1 -1
  257. package/static/chunk-I3FR3A45.js +1 -0
  258. package/static/{chunk-A6J6SOM6.js → chunk-I5SPA4G2.js} +1 -1
  259. package/static/{chunk-TGHBDJZA.js → chunk-IMFO2MI7.js} +1 -1
  260. package/static/{chunk-CURVLK7L.js → chunk-JNTNMIUH.js} +1 -1
  261. package/static/chunk-JRXG43AA.js +2 -0
  262. package/static/{chunk-XAIOGRBO.js → chunk-KAUCN24H.js} +1 -1
  263. package/static/chunk-KDUAB76O.js +1 -0
  264. package/static/chunk-KPOQLDWF.js +1 -0
  265. package/static/{chunk-HE6EDXWI.js → chunk-KWFELZTM.js} +1 -1
  266. package/static/{chunk-2CAAJBRO.js → chunk-L3BIP4AA.js} +1 -1
  267. package/static/{chunk-U75PLYIJ.js → chunk-LGIVVJDD.js} +1 -1
  268. package/static/{chunk-JEVBUJQ4.js → chunk-LNLBIJZD.js} +1 -1
  269. package/static/chunk-LTJNLOX2.js +1 -0
  270. package/static/{chunk-SDR3UG2F.js → chunk-LZUHREOF.js} +1 -1
  271. package/static/{chunk-VO4WVT6K.js → chunk-NIR4YE2E.js} +1 -1
  272. package/static/{chunk-S6YKBWJE.js → chunk-NJJURHX4.js} +1 -1
  273. package/static/chunk-NNZWSNAW.js +1 -0
  274. package/static/chunk-NWKBB7J4.js +1 -0
  275. package/static/chunk-O3YLAEVE.js +3 -0
  276. package/static/chunk-OUHCDDT6.js +1 -0
  277. package/static/{chunk-ZRBLCAOK.js → chunk-PDG7DOEF.js} +1 -1
  278. package/static/chunk-POUWUMC4.js +1 -0
  279. package/static/{chunk-YTBSB2GE.js → chunk-PPJCVBJH.js} +1 -1
  280. package/static/{chunk-K3MOXDU5.js → chunk-PQZLR4P3.js} +1 -1
  281. package/static/chunk-PVYVY3GD.js +1 -0
  282. package/static/chunk-Q5X5TPAG.js +1 -0
  283. package/static/{chunk-LFAQLJZK.js → chunk-QHJT5H4M.js} +1 -1
  284. package/static/{chunk-A7DSX7VP.js → chunk-R4VMWCM5.js} +1 -1
  285. package/static/{chunk-27XEAHMV.js → chunk-R7PLNX75.js} +1 -1
  286. package/static/chunk-RJULB733.js +1 -0
  287. package/static/{chunk-MBFMTBVJ.js → chunk-RNVPQQKT.js} +5 -5
  288. package/static/chunk-RTNEBRKJ.js +1 -0
  289. package/static/{chunk-FXM7XXWA.js → chunk-S3TTWPQA.js} +1 -1
  290. package/static/{chunk-6VJI4X2A.js → chunk-SDJNZULP.js} +1 -1
  291. package/static/chunk-SNOOCDJD.js +1 -0
  292. package/static/chunk-T42BV6TR.js +1 -0
  293. package/static/{chunk-4OV3SAUS.js → chunk-TNCKNU6I.js} +1 -1
  294. package/static/{chunk-2LHHXDD5.js → chunk-ULSPQ3HP.js} +1 -1
  295. package/static/{chunk-4EUHBTWV.js → chunk-UOK3LKSX.js} +1 -1
  296. package/static/{chunk-7NI353LS.js → chunk-VD5JHSDS.js} +1 -1
  297. package/static/{chunk-YXWF2DGF.js → chunk-XBKCQCBI.js} +1 -1
  298. package/static/{chunk-KBWK65KM.js → chunk-XEWLBWFF.js} +1 -1
  299. package/static/{chunk-FLPZB3OX.js → chunk-XTVNHFKX.js} +1 -1
  300. package/static/chunk-ZCSHU3D7.js +1 -0
  301. package/static/{chunk-FRBTL2ER.js → chunk-ZEJLIGAY.js} +1 -1
  302. package/static/{chunk-7H5O4BLV.js → chunk-ZHOE5VEY.js} +1 -1
  303. package/static/chunk-ZOMRIN3G.js +2 -0
  304. package/static/index.html +2 -2
  305. package/static/main-YKDNJ7LK.js +11 -0
  306. package/static/{styles-S5HVK4H5.css → styles-XLLEY5Y3.css} +1 -1
  307. package/server/applications/files/constants/only-office.js +0 -531
  308. package/server/applications/files/constants/only-office.js.map +0 -1
  309. package/server/applications/files/decorators/only-office-environment.decorator.js.map +0 -1
  310. package/server/applications/files/files-only-office.controller.js.map +0 -1
  311. package/server/applications/files/files-only-office.controller.spec.js.map +0 -1
  312. package/server/applications/files/guards/files-only-office.guard.js.map +0 -1
  313. package/server/applications/files/guards/files-only-office.guard.spec.js.map +0 -1
  314. package/server/applications/files/guards/files-only-office.strategy.js.map +0 -1
  315. package/server/applications/files/interfaces/only-office-config.interface.js.map +0 -1
  316. package/server/applications/files/services/files-only-office-manager.service.js.map +0 -1
  317. package/server/applications/files/services/files-only-office-manager.service.spec.js +0 -58
  318. package/server/applications/files/services/files-only-office-manager.service.spec.js.map +0 -1
  319. package/static/chunk-2XY4PMI5.js +0 -1
  320. package/static/chunk-33WFRCUP.js +0 -1
  321. package/static/chunk-3LVFDMTN.js +0 -1
  322. package/static/chunk-42L6C5MT.js +0 -1
  323. package/static/chunk-5WCQBTXW.js +0 -1
  324. package/static/chunk-A7R246NW.js +0 -1
  325. package/static/chunk-BSB4VROD.js +0 -2
  326. package/static/chunk-DHFQIFOF.js +0 -1
  327. package/static/chunk-DRHPEERW.js +0 -2
  328. package/static/chunk-FCGTI42I.js +0 -1
  329. package/static/chunk-H4RLHI3Y.js +0 -1
  330. package/static/chunk-ITVA26X2.js +0 -2
  331. package/static/chunk-IUJ4IK26.js +0 -1
  332. package/static/chunk-L3PDWJZ3.js +0 -3
  333. package/static/chunk-LBXOAKBD.js +0 -1
  334. package/static/chunk-LZKI5P5T.js +0 -1
  335. package/static/chunk-MYM43ENO.js +0 -1
  336. package/static/chunk-MZBO5PAR.js +0 -1
  337. package/static/chunk-NAH4V2R6.js +0 -2
  338. package/static/chunk-O7UXVNR2.js +0 -1
  339. package/static/chunk-PCFH5HCI.js +0 -2
  340. package/static/chunk-SRBOO7AO.js +0 -1
  341. package/static/chunk-UUX3M6DC.js +0 -1
  342. package/static/chunk-VJ2HWQRJ.js +0 -5
  343. package/static/chunk-VZPCXSRG.js +0 -2
  344. package/static/chunk-W72JYHOH.js +0 -1
  345. package/static/chunk-XHQEF2IX.js +0 -1
  346. package/static/chunk-XKEBQNQJ.js +0 -1
  347. package/static/chunk-ZERBTNFW.js +0 -13
  348. package/static/main-FE6GWZXU.js +0 -11
  349. /package/static/assets/pdfjs/web/images/{toolbarButton-sidebarToggle.svg → toolbarButton-viewsManagerToggle.svg} +0 -0
@@ -6,36 +6,382 @@
6
6
  Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
+ const _common = require("@nestjs/common");
9
10
  const _testing = require("@nestjs/testing");
11
+ const _time2fa = require("time2fa");
10
12
  const _notificationsmanagerservice = require("../../../applications/notifications/services/notifications-manager.service");
11
13
  const _usersmanagerservice = require("../../../applications/users/services/users-manager.service");
12
14
  const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
15
+ const _cryptsecret = require("../../utils/crypt-secret");
13
16
  const _authmethodtwofaservice = require("./auth-method-two-fa.service");
17
+ function _getRequireWildcardCache(nodeInterop) {
18
+ if (typeof WeakMap !== "function") return null;
19
+ var cacheBabelInterop = new WeakMap();
20
+ var cacheNodeInterop = new WeakMap();
21
+ return (_getRequireWildcardCache = function(nodeInterop) {
22
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
23
+ })(nodeInterop);
24
+ }
25
+ function _interop_require_wildcard(obj, nodeInterop) {
26
+ if (!nodeInterop && obj && obj.__esModule) {
27
+ return obj;
28
+ }
29
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
30
+ return {
31
+ default: obj
32
+ };
33
+ }
34
+ var cache = _getRequireWildcardCache(nodeInterop);
35
+ if (cache && cache.has(obj)) {
36
+ return cache.get(obj);
37
+ }
38
+ var newObj = {
39
+ __proto__: null
40
+ };
41
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
42
+ for(var key in obj){
43
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
44
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
45
+ if (desc && (desc.get || desc.set)) {
46
+ Object.defineProperty(newObj, key, desc);
47
+ } else {
48
+ newObj[key] = obj[key];
49
+ }
50
+ }
51
+ }
52
+ newObj.default = obj;
53
+ if (cache) {
54
+ cache.set(obj, newObj);
55
+ }
56
+ return newObj;
57
+ }
58
+ jest.mock('../../utils/crypt-secret');
59
+ jest.mock('../../../common/qrcode');
14
60
  describe(_authmethodtwofaservice.AuthMethod2FA.name, ()=>{
15
61
  let service;
16
- beforeAll(async ()=>{
62
+ let cache;
63
+ let usersManager;
64
+ let notificationsManager;
65
+ const mockUser = {
66
+ id: 1,
67
+ login: 'testuser',
68
+ email: 'test@example.com',
69
+ secrets: {
70
+ twoFaSecret: 'encrypted-secret',
71
+ recoveryCodes: [
72
+ 'encrypted-code-1',
73
+ 'encrypted-code-2'
74
+ ]
75
+ }
76
+ };
77
+ const mockRequest = {
78
+ user: {
79
+ id: 1,
80
+ login: 'testuser'
81
+ },
82
+ ip: '127.0.0.1',
83
+ headers: {
84
+ 'user-agent': 'test-agent'
85
+ }
86
+ };
87
+ beforeEach(async ()=>{
17
88
  const module = await _testing.Test.createTestingModule({
18
89
  providers: [
19
90
  _authmethodtwofaservice.AuthMethod2FA,
20
91
  {
21
92
  provide: _cacheservice.Cache,
22
- useValue: {}
93
+ useValue: {
94
+ get: jest.fn(),
95
+ set: jest.fn()
96
+ }
23
97
  },
24
98
  {
25
99
  provide: _usersmanagerservice.UsersManager,
26
- useValue: {}
100
+ useValue: {
101
+ fromUserId: jest.fn(),
102
+ validateUserAccess: jest.fn(),
103
+ compareUserPassword: jest.fn(),
104
+ updateAccesses: jest.fn().mockResolvedValue(undefined),
105
+ updateSecrets: jest.fn()
106
+ }
27
107
  },
28
108
  {
29
109
  provide: _notificationsmanagerservice.NotificationsManager,
30
- useValue: {}
110
+ useValue: {
111
+ sendEmailNotification: jest.fn().mockResolvedValue(undefined)
112
+ }
31
113
  }
32
114
  ]
33
115
  }).compile();
116
+ module.useLogger([
117
+ 'fatal'
118
+ ]);
34
119
  service = module.get(_authmethodtwofaservice.AuthMethod2FA);
120
+ cache = module.get(_cacheservice.Cache);
121
+ usersManager = module.get(_usersmanagerservice.UsersManager);
122
+ notificationsManager = module.get(_notificationsmanagerservice.NotificationsManager);
123
+ _cryptsecret.encryptSecret.mockImplementation((secret)=>`encrypted-${secret}`);
124
+ _cryptsecret.decryptSecret.mockImplementation((secret)=>secret.replace('encrypted-', ''));
125
+ const { qrcodeToDataURL } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../common/qrcode")));
126
+ qrcodeToDataURL.mockReturnValue('data:image/png;base64,mock');
127
+ });
128
+ afterEach(()=>{
129
+ jest.clearAllMocks();
35
130
  });
36
131
  it('should be defined', ()=>{
37
132
  expect(service).toBeDefined();
38
133
  });
134
+ describe('initTwoFactor', ()=>{
135
+ it('should generate secret and QR code and store in cache', async ()=>{
136
+ const result = await service.initTwoFactor(mockUser);
137
+ expect(result).toHaveProperty('secret');
138
+ expect(result).toHaveProperty('qrDataUrl');
139
+ expect(result.qrDataUrl).toBe('data:image/png;base64,mock');
140
+ expect(cache.set).toHaveBeenCalledWith(`auth-2fa-pending-user-${mockUser.id}`, expect.any(String), 300);
141
+ });
142
+ });
143
+ describe('enableTwoFactor', ()=>{
144
+ const enableDto = {
145
+ code: '123456',
146
+ password: 'password123',
147
+ isRecoveryCode: false
148
+ };
149
+ it('should throw error if secret has expired', async ()=>{
150
+ cache.get.mockResolvedValue(null);
151
+ await expect(service.enableTwoFactor(enableDto, mockRequest)).rejects.toThrow(new _common.HttpException('The secret has expired', _common.HttpStatus.BAD_REQUEST));
152
+ });
153
+ it('should throw error if verification fails', async ()=>{
154
+ cache.get.mockResolvedValue('encrypted-secret');
155
+ usersManager.fromUserId.mockResolvedValue(mockUser);
156
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
157
+ success: false,
158
+ message: 'Invalid code'
159
+ });
160
+ await expect(service.enableTwoFactor(enableDto, mockRequest)).rejects.toThrow(new _common.HttpException('Invalid code', _common.HttpStatus.FORBIDDEN));
161
+ });
162
+ it('should throw error if password is incorrect', async ()=>{
163
+ cache.get.mockResolvedValue('encrypted-secret');
164
+ usersManager.fromUserId.mockResolvedValue(mockUser);
165
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
166
+ success: true,
167
+ message: ''
168
+ });
169
+ usersManager.compareUserPassword.mockResolvedValue(false);
170
+ await expect(service.enableTwoFactor(enableDto, mockRequest)).rejects.toThrow(new _common.HttpException('Incorrect code or password', _common.HttpStatus.BAD_REQUEST));
171
+ });
172
+ it('should enable 2FA and return recovery codes on success', async ()=>{
173
+ cache.get.mockResolvedValue('encrypted-secret');
174
+ usersManager.fromUserId.mockResolvedValue(mockUser);
175
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
176
+ success: true,
177
+ message: ''
178
+ });
179
+ usersManager.compareUserPassword.mockResolvedValue(true);
180
+ const result = await service.enableTwoFactor(enableDto, mockRequest);
181
+ expect(result.success).toBe(true);
182
+ expect(result.recoveryCodes).toHaveLength(5);
183
+ expect(usersManager.updateSecrets).toHaveBeenCalledWith(mockUser.id, {
184
+ twoFaSecret: 'encrypted-secret',
185
+ recoveryCodes: expect.any(Array)
186
+ });
187
+ expect(notificationsManager.sendEmailNotification).toHaveBeenCalledWith([
188
+ mockRequest.user
189
+ ], {
190
+ app: 'auth_2fa',
191
+ event: 'Two-factor authentication (2FA) on your account has been enabled',
192
+ element: 'test-agent',
193
+ url: '127.0.0.1'
194
+ });
195
+ });
196
+ });
197
+ describe('disableTwoFactor', ()=>{
198
+ const disableDto = {
199
+ code: '123456',
200
+ password: 'password123',
201
+ isRecoveryCode: false
202
+ };
203
+ it('should throw error if verification fails', async ()=>{
204
+ usersManager.fromUserId.mockResolvedValue(mockUser);
205
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
206
+ success: false,
207
+ message: 'Invalid code'
208
+ });
209
+ await expect(service.disableTwoFactor(disableDto, mockRequest)).rejects.toThrow(new _common.HttpException('Invalid code', _common.HttpStatus.FORBIDDEN));
210
+ });
211
+ it('should throw error if password is incorrect', async ()=>{
212
+ usersManager.fromUserId.mockResolvedValue(mockUser);
213
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
214
+ success: true,
215
+ message: ''
216
+ });
217
+ usersManager.compareUserPassword.mockResolvedValue(false);
218
+ await expect(service.disableTwoFactor(disableDto, mockRequest)).rejects.toThrow(new _common.HttpException('Incorrect code or password', _common.HttpStatus.BAD_REQUEST));
219
+ });
220
+ it('should disable 2FA on success', async ()=>{
221
+ usersManager.fromUserId.mockResolvedValue(mockUser);
222
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
223
+ success: true,
224
+ message: ''
225
+ });
226
+ usersManager.compareUserPassword.mockResolvedValue(true);
227
+ const result = await service.disableTwoFactor(disableDto, mockRequest);
228
+ expect(result.success).toBe(true);
229
+ expect(usersManager.updateSecrets).toHaveBeenCalledWith(mockUser.id, {
230
+ twoFaSecret: undefined,
231
+ recoveryCodes: undefined
232
+ });
233
+ expect(notificationsManager.sendEmailNotification).toHaveBeenCalledWith([
234
+ mockRequest.user
235
+ ], {
236
+ app: 'auth_2fa',
237
+ event: 'Two-factor authentication (2FA) on your account has been disabled',
238
+ element: 'test-agent',
239
+ url: '127.0.0.1'
240
+ });
241
+ });
242
+ });
243
+ describe('verify', ()=>{
244
+ const verifyDto = {
245
+ code: '123456',
246
+ isRecoveryCode: false
247
+ };
248
+ it('should verify 2FA code successfully', async ()=>{
249
+ usersManager.fromUserId.mockResolvedValue(mockUser);
250
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
251
+ success: true,
252
+ message: ''
253
+ });
254
+ const result = await service.verify(verifyDto, mockRequest);
255
+ expect(result.success).toBe(true);
256
+ expect(usersManager.updateAccesses).toHaveBeenCalledWith(mockUser, mockRequest.ip, true, true);
257
+ });
258
+ it('should verify recovery code successfully', async ()=>{
259
+ const recoveryDto = {
260
+ code: 'code-1',
261
+ isRecoveryCode: true
262
+ };
263
+ usersManager.fromUserId.mockResolvedValue(mockUser);
264
+ usersManager.updateSecrets.mockResolvedValue(undefined);
265
+ await service.verify(recoveryDto, mockRequest);
266
+ expect(usersManager.updateSecrets).toHaveBeenCalled();
267
+ });
268
+ it('should fail when recovery codes are empty', async ()=>{
269
+ const recoveryDto = {
270
+ code: 'code-1',
271
+ isRecoveryCode: true
272
+ };
273
+ const userWithoutCodes = {
274
+ ...mockUser,
275
+ secrets: {
276
+ ...mockUser.secrets,
277
+ recoveryCodes: []
278
+ }
279
+ };
280
+ usersManager.fromUserId.mockResolvedValue(userWithoutCodes);
281
+ const result = await service.verify(recoveryDto, mockRequest);
282
+ expect(result.success).toBe(false);
283
+ expect(result.message).toBe('Invalid code');
284
+ });
285
+ it('should fail when recovery code does not match', async ()=>{
286
+ const recoveryDto = {
287
+ code: 'wrong-code',
288
+ isRecoveryCode: true
289
+ };
290
+ usersManager.fromUserId.mockResolvedValue(mockUser);
291
+ const result = await service.verify(recoveryDto, mockRequest);
292
+ expect(result.success).toBe(false);
293
+ expect(result.message).toBe('Invalid code');
294
+ });
295
+ it('should handle errors during recovery code validation', async ()=>{
296
+ const recoveryDto = {
297
+ code: 'code-1',
298
+ isRecoveryCode: true
299
+ };
300
+ usersManager.fromUserId.mockResolvedValue(mockUser);
301
+ usersManager.updateSecrets.mockRejectedValue(new Error());
302
+ const result = await service.verify(recoveryDto, mockRequest);
303
+ expect(result.success).toBe(false);
304
+ expect(result.message).toBe('Invalid code');
305
+ });
306
+ it('should return user when fromLogin is true', async ()=>{
307
+ usersManager.fromUserId.mockResolvedValue(mockUser);
308
+ jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({
309
+ success: true,
310
+ message: ''
311
+ });
312
+ const result = await service.verify(verifyDto, mockRequest, true);
313
+ expect(Array.isArray(result)).toBe(true);
314
+ expect(result[0].success).toBe(true);
315
+ expect(result[1]).toBe(mockUser);
316
+ });
317
+ });
318
+ describe('adminResetUserTwoFa', ()=>{
319
+ it('should reset user 2FA successfully', async ()=>{
320
+ usersManager.updateSecrets.mockResolvedValue(undefined);
321
+ const result = await service.adminResetUserTwoFa(1);
322
+ expect(result.success).toBe(true);
323
+ expect(usersManager.updateSecrets).toHaveBeenCalledWith(1, {
324
+ twoFaSecret: undefined,
325
+ recoveryCodes: undefined
326
+ });
327
+ });
328
+ it('should handle errors during reset', async ()=>{
329
+ usersManager.updateSecrets.mockRejectedValue(new Error('Database error'));
330
+ const result = await service.adminResetUserTwoFa(1);
331
+ expect(result.success).toBe(false);
332
+ expect(result.message).toBe('Database error');
333
+ });
334
+ });
335
+ describe('loadUser', ()=>{
336
+ it('should load and validate user successfully', async ()=>{
337
+ usersManager.fromUserId.mockResolvedValue(mockUser);
338
+ const result = await service.loadUser(1, '127.0.0.1');
339
+ expect(result).toBe(mockUser);
340
+ expect(usersManager.validateUserAccess).toHaveBeenCalledWith(mockUser, '127.0.0.1');
341
+ });
342
+ it('should throw error if user not found', async ()=>{
343
+ usersManager.fromUserId.mockResolvedValue(null);
344
+ await expect(service.loadUser(1, '127.0.0.1')).rejects.toThrow(new _common.HttpException('User not found', _common.HttpStatus.NOT_FOUND));
345
+ });
346
+ });
347
+ describe('verifyUserPassword', ()=>{
348
+ it('should verify password successfully', async ()=>{
349
+ usersManager.compareUserPassword.mockResolvedValue(true);
350
+ await expect(service.verifyUserPassword(mockUser, 'password123', '127.0.0.1')).resolves.not.toThrow();
351
+ });
352
+ it('should throw error if password is incorrect', async ()=>{
353
+ usersManager.compareUserPassword.mockResolvedValue(false);
354
+ await expect(service.verifyUserPassword(mockUser, 'wrong-password', '127.0.0.1')).rejects.toThrow(new _common.HttpException('Incorrect code or password', _common.HttpStatus.BAD_REQUEST));
355
+ expect(usersManager.updateAccesses).toHaveBeenCalledWith(mockUser, '127.0.0.1', false, true);
356
+ });
357
+ });
358
+ describe('validateTwoFactorCode', ()=>{
359
+ it('should validate code successfully', ()=>{
360
+ jest.spyOn(_time2fa.Totp, 'validate').mockReturnValue(true);
361
+ const result = service.validateTwoFactorCode('123456', 'encrypted-secret');
362
+ expect(result.success).toBe(true);
363
+ expect(result.message).toBe('');
364
+ });
365
+ it('should fail validation for incorrect code', ()=>{
366
+ jest.spyOn(_time2fa.Totp, 'validate').mockReturnValue(false);
367
+ const result = service.validateTwoFactorCode('wrong-code', 'encrypted-secret');
368
+ expect(result.success).toBe(false);
369
+ expect(result.message).toBe('Incorrect code or password');
370
+ });
371
+ it('should return error if secret is not provided', ()=>{
372
+ const result = service.validateTwoFactorCode('123456', '');
373
+ expect(result.success).toBe(false);
374
+ expect(result.message).toBe('Incorrect code or password');
375
+ });
376
+ it('should handle validation errors', ()=>{
377
+ jest.spyOn(_time2fa.Totp, 'validate').mockImplementation(()=>{
378
+ throw new Error('Validation error');
379
+ });
380
+ const result = service.validateTwoFactorCode('123456', 'encrypted-secret');
381
+ expect(result.success).toBe(false);
382
+ expect(result.message).toBe('Validation error');
383
+ });
384
+ });
39
385
  });
40
386
 
41
387
  //# sourceMappingURL=auth-method-two-fa.service.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/authentication/services/auth-methods/auth-method-two-fa.service.spec.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 { Test, TestingModule } from '@nestjs/testing'\nimport { NotificationsManager } from '../../../applications/notifications/services/notifications-manager.service'\nimport { UsersManager } from '../../../applications/users/services/users-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { AuthMethod2FA } from './auth-method-two-fa.service'\n\ndescribe(AuthMethod2FA.name, () => {\n let service: AuthMethod2FA\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n AuthMethod2FA,\n { provide: Cache, useValue: {} },\n { provide: UsersManager, useValue: {} },\n { provide: NotificationsManager, useValue: {} }\n ]\n }).compile()\n\n service = module.get<AuthMethod2FA>(AuthMethod2FA)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n})\n"],"names":["describe","AuthMethod2FA","name","service","beforeAll","module","Test","createTestingModule","providers","provide","Cache","useValue","UsersManager","NotificationsManager","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;6CACC;qCACR;8BACP;wCACQ;AAE9BA,SAASC,qCAAa,CAACC,IAAI,EAAE;IAC3B,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBACTP,qCAAa;gBACb;oBAAEQ,SAASC,mBAAK;oBAAEC,UAAU,CAAC;gBAAE;gBAC/B;oBAAEF,SAASG,iCAAY;oBAAED,UAAU,CAAC;gBAAE;gBACtC;oBAAEF,SAASI,iDAAoB;oBAAEF,UAAU,CAAC;gBAAE;aAC/C;QACH,GAAGG,OAAO;QAEVX,UAAUE,OAAOU,GAAG,CAAgBd,qCAAa;IACnD;IAEAe,GAAG,qBAAqB;QACtBC,OAAOd,SAASe,WAAW;IAC7B;AACF"}
1
+ {"version":3,"sources":["../../../../../backend/src/authentication/services/auth-methods/auth-method-two-fa.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { Totp } from 'time2fa'\nimport { NotificationsManager } from '../../../applications/notifications/services/notifications-manager.service'\nimport { UserModel } from '../../../applications/users/models/user.model'\nimport { UsersManager } from '../../../applications/users/services/users-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { TwoFaVerifyDto, TwoFaVerifyWithPasswordDto } from '../../dto/two-fa-verify.dto'\nimport { FastifyAuthenticatedRequest } from '../../interfaces/auth-request.interface'\nimport { decryptSecret, encryptSecret } from '../../utils/crypt-secret'\nimport { AuthMethod2FA } from './auth-method-two-fa.service'\n\njest.mock('../../utils/crypt-secret')\njest.mock('../../../common/qrcode')\n\ndescribe(AuthMethod2FA.name, () => {\n let service: AuthMethod2FA\n let cache: jest.Mocked<Cache>\n let usersManager: jest.Mocked<UsersManager>\n let notificationsManager: jest.Mocked<NotificationsManager>\n\n const mockUser: Partial<UserModel> = {\n id: 1,\n login: 'testuser',\n email: 'test@example.com',\n secrets: {\n twoFaSecret: 'encrypted-secret',\n recoveryCodes: ['encrypted-code-1', 'encrypted-code-2']\n }\n }\n\n const mockRequest: Partial<FastifyAuthenticatedRequest> = {\n user: { id: 1, login: 'testuser' } as any,\n ip: '127.0.0.1',\n headers: { 'user-agent': 'test-agent' }\n }\n\n beforeEach(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n AuthMethod2FA,\n {\n provide: Cache,\n useValue: {\n get: jest.fn(),\n set: jest.fn()\n }\n },\n {\n provide: UsersManager,\n useValue: {\n fromUserId: jest.fn(),\n validateUserAccess: jest.fn(),\n compareUserPassword: jest.fn(),\n updateAccesses: jest.fn().mockResolvedValue(undefined),\n updateSecrets: jest.fn()\n }\n },\n {\n provide: NotificationsManager,\n useValue: {\n sendEmailNotification: jest.fn().mockResolvedValue(undefined)\n }\n }\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<AuthMethod2FA>(AuthMethod2FA)\n cache = module.get(Cache)\n usersManager = module.get(UsersManager)\n notificationsManager = module.get(NotificationsManager)\n ;(encryptSecret as jest.Mock).mockImplementation((secret: string) => `encrypted-${secret}`)\n ;(decryptSecret as jest.Mock).mockImplementation((secret: string) => secret.replace('encrypted-', ''))\n\n const { qrcodeToDataURL } = await import('../../../common/qrcode')\n ;(qrcodeToDataURL as jest.Mock).mockReturnValue('data:image/png;base64,mock')\n })\n\n afterEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('initTwoFactor', () => {\n it('should generate secret and QR code and store in cache', async () => {\n const result = await service.initTwoFactor(mockUser as UserModel)\n\n expect(result).toHaveProperty('secret')\n expect(result).toHaveProperty('qrDataUrl')\n expect(result.qrDataUrl).toBe('data:image/png;base64,mock')\n expect(cache.set).toHaveBeenCalledWith(`auth-2fa-pending-user-${mockUser.id}`, expect.any(String), 300)\n })\n })\n\n describe('enableTwoFactor', () => {\n const enableDto: TwoFaVerifyWithPasswordDto = {\n code: '123456',\n password: 'password123',\n isRecoveryCode: false\n }\n\n it('should throw error if secret has expired', async () => {\n cache.get.mockResolvedValue(null)\n\n await expect(service.enableTwoFactor(enableDto, mockRequest as FastifyAuthenticatedRequest)).rejects.toThrow(\n new HttpException('The secret has expired', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should throw error if verification fails', async () => {\n cache.get.mockResolvedValue('encrypted-secret')\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: false, message: 'Invalid code' })\n\n await expect(service.enableTwoFactor(enableDto, mockRequest as FastifyAuthenticatedRequest)).rejects.toThrow(\n new HttpException('Invalid code', HttpStatus.FORBIDDEN)\n )\n })\n\n it('should throw error if password is incorrect', async () => {\n cache.get.mockResolvedValue('encrypted-secret')\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n usersManager.compareUserPassword.mockResolvedValue(false)\n\n await expect(service.enableTwoFactor(enableDto, mockRequest as FastifyAuthenticatedRequest)).rejects.toThrow(\n new HttpException('Incorrect code or password', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should enable 2FA and return recovery codes on success', async () => {\n cache.get.mockResolvedValue('encrypted-secret')\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n usersManager.compareUserPassword.mockResolvedValue(true)\n\n const result = await service.enableTwoFactor(enableDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(true)\n expect(result.recoveryCodes).toHaveLength(5)\n expect(usersManager.updateSecrets).toHaveBeenCalledWith(mockUser.id, {\n twoFaSecret: 'encrypted-secret',\n recoveryCodes: expect.any(Array)\n })\n expect(notificationsManager.sendEmailNotification).toHaveBeenCalledWith([mockRequest.user], {\n app: 'auth_2fa',\n event: 'Two-factor authentication (2FA) on your account has been enabled',\n element: 'test-agent',\n url: '127.0.0.1'\n })\n })\n })\n\n describe('disableTwoFactor', () => {\n const disableDto: TwoFaVerifyWithPasswordDto = {\n code: '123456',\n password: 'password123',\n isRecoveryCode: false\n }\n\n it('should throw error if verification fails', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: false, message: 'Invalid code' })\n\n await expect(service.disableTwoFactor(disableDto, mockRequest as FastifyAuthenticatedRequest)).rejects.toThrow(\n new HttpException('Invalid code', HttpStatus.FORBIDDEN)\n )\n })\n\n it('should throw error if password is incorrect', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n usersManager.compareUserPassword.mockResolvedValue(false)\n\n await expect(service.disableTwoFactor(disableDto, mockRequest as FastifyAuthenticatedRequest)).rejects.toThrow(\n new HttpException('Incorrect code or password', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should disable 2FA on success', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n usersManager.compareUserPassword.mockResolvedValue(true)\n\n const result = await service.disableTwoFactor(disableDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(true)\n expect(usersManager.updateSecrets).toHaveBeenCalledWith(mockUser.id, {\n twoFaSecret: undefined,\n recoveryCodes: undefined\n })\n expect(notificationsManager.sendEmailNotification).toHaveBeenCalledWith([mockRequest.user], {\n app: 'auth_2fa',\n event: 'Two-factor authentication (2FA) on your account has been disabled',\n element: 'test-agent',\n url: '127.0.0.1'\n })\n })\n })\n\n describe('verify', () => {\n const verifyDto: TwoFaVerifyDto = {\n code: '123456',\n isRecoveryCode: false\n }\n\n it('should verify 2FA code successfully', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n\n const result = await service.verify(verifyDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(true)\n expect(usersManager.updateAccesses).toHaveBeenCalledWith(mockUser, mockRequest.ip, true, true)\n })\n\n it('should verify recovery code successfully', async () => {\n const recoveryDto: TwoFaVerifyDto = { code: 'code-1', isRecoveryCode: true }\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n usersManager.updateSecrets.mockResolvedValue(undefined)\n\n await service.verify(recoveryDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(usersManager.updateSecrets).toHaveBeenCalled()\n })\n\n it('should fail when recovery codes are empty', async () => {\n const recoveryDto: TwoFaVerifyDto = { code: 'code-1', isRecoveryCode: true }\n const userWithoutCodes = { ...mockUser, secrets: { ...mockUser.secrets, recoveryCodes: [] } }\n usersManager.fromUserId.mockResolvedValue(userWithoutCodes as UserModel)\n\n const result = await service.verify(recoveryDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Invalid code')\n })\n\n it('should fail when recovery code does not match', async () => {\n const recoveryDto: TwoFaVerifyDto = { code: 'wrong-code', isRecoveryCode: true }\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n\n const result = await service.verify(recoveryDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Invalid code')\n })\n\n it('should handle errors during recovery code validation', async () => {\n const recoveryDto: TwoFaVerifyDto = { code: 'code-1', isRecoveryCode: true }\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n usersManager.updateSecrets.mockRejectedValue(new Error())\n\n const result = await service.verify(recoveryDto, mockRequest as FastifyAuthenticatedRequest)\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Invalid code')\n })\n\n it('should return user when fromLogin is true', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n jest.spyOn(service, 'validateTwoFactorCode').mockReturnValue({ success: true, message: '' })\n\n const result = await service.verify(verifyDto, mockRequest as FastifyAuthenticatedRequest, true)\n\n expect(Array.isArray(result)).toBe(true)\n expect(result[0].success).toBe(true)\n expect(result[1]).toBe(mockUser)\n })\n })\n\n describe('adminResetUserTwoFa', () => {\n it('should reset user 2FA successfully', async () => {\n usersManager.updateSecrets.mockResolvedValue(undefined)\n\n const result = await service.adminResetUserTwoFa(1)\n\n expect(result.success).toBe(true)\n expect(usersManager.updateSecrets).toHaveBeenCalledWith(1, {\n twoFaSecret: undefined,\n recoveryCodes: undefined\n })\n })\n\n it('should handle errors during reset', async () => {\n usersManager.updateSecrets.mockRejectedValue(new Error('Database error'))\n\n const result = await service.adminResetUserTwoFa(1)\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Database error')\n })\n })\n\n describe('loadUser', () => {\n it('should load and validate user successfully', async () => {\n usersManager.fromUserId.mockResolvedValue(mockUser as UserModel)\n\n const result = await service.loadUser(1, '127.0.0.1')\n\n expect(result).toBe(mockUser)\n expect(usersManager.validateUserAccess).toHaveBeenCalledWith(mockUser, '127.0.0.1')\n })\n\n it('should throw error if user not found', async () => {\n usersManager.fromUserId.mockResolvedValue(null)\n\n await expect(service.loadUser(1, '127.0.0.1')).rejects.toThrow(new HttpException('User not found', HttpStatus.NOT_FOUND))\n })\n })\n\n describe('verifyUserPassword', () => {\n it('should verify password successfully', async () => {\n usersManager.compareUserPassword.mockResolvedValue(true)\n\n await expect(service.verifyUserPassword(mockUser as UserModel, 'password123', '127.0.0.1')).resolves.not.toThrow()\n })\n\n it('should throw error if password is incorrect', async () => {\n usersManager.compareUserPassword.mockResolvedValue(false)\n\n await expect(service.verifyUserPassword(mockUser as UserModel, 'wrong-password', '127.0.0.1')).rejects.toThrow(\n new HttpException('Incorrect code or password', HttpStatus.BAD_REQUEST)\n )\n expect(usersManager.updateAccesses).toHaveBeenCalledWith(mockUser, '127.0.0.1', false, true)\n })\n })\n\n describe('validateTwoFactorCode', () => {\n it('should validate code successfully', () => {\n jest.spyOn(Totp, 'validate').mockReturnValue(true)\n\n const result = service.validateTwoFactorCode('123456', 'encrypted-secret')\n\n expect(result.success).toBe(true)\n expect(result.message).toBe('')\n })\n\n it('should fail validation for incorrect code', () => {\n jest.spyOn(Totp, 'validate').mockReturnValue(false)\n\n const result = service.validateTwoFactorCode('wrong-code', 'encrypted-secret')\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Incorrect code or password')\n })\n\n it('should return error if secret is not provided', () => {\n const result = service.validateTwoFactorCode('123456', '')\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Incorrect code or password')\n })\n\n it('should handle validation errors', () => {\n jest.spyOn(Totp, 'validate').mockImplementation(() => {\n throw new Error('Validation error')\n })\n\n const result = service.validateTwoFactorCode('123456', 'encrypted-secret')\n\n expect(result.success).toBe(false)\n expect(result.message).toBe('Validation error')\n })\n })\n})\n"],"names":["jest","mock","describe","AuthMethod2FA","name","service","cache","usersManager","notificationsManager","mockUser","id","login","email","secrets","twoFaSecret","recoveryCodes","mockRequest","user","ip","headers","beforeEach","module","Test","createTestingModule","providers","provide","Cache","useValue","get","fn","set","UsersManager","fromUserId","validateUserAccess","compareUserPassword","updateAccesses","mockResolvedValue","undefined","updateSecrets","NotificationsManager","sendEmailNotification","compile","useLogger","encryptSecret","mockImplementation","secret","decryptSecret","replace","qrcodeToDataURL","mockReturnValue","afterEach","clearAllMocks","it","expect","toBeDefined","result","initTwoFactor","toHaveProperty","qrDataUrl","toBe","toHaveBeenCalledWith","any","String","enableDto","code","password","isRecoveryCode","enableTwoFactor","rejects","toThrow","HttpException","HttpStatus","BAD_REQUEST","spyOn","success","message","FORBIDDEN","toHaveLength","Array","app","event","element","url","disableDto","disableTwoFactor","verifyDto","verify","recoveryDto","toHaveBeenCalled","userWithoutCodes","mockRejectedValue","Error","isArray","adminResetUserTwoFa","loadUser","NOT_FOUND","verifyUserPassword","resolves","not","Totp","validateTwoFactorCode"],"mappings":"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"}
@@ -32,7 +32,11 @@ const _configvalidation = require("./config.validation");
32
32
  const configuration = loadConfiguration();
33
33
  const serverConfig = {
34
34
  twoFaEnabled: configuration.auth.mfa.totp.enabled,
35
- mailServerEnabled: !!configuration.mail?.host
35
+ mailServerEnabled: !!configuration.mail?.host,
36
+ fileEditors: {
37
+ collabora: configuration.applications.files.collabora.enabled,
38
+ onlyoffice: configuration.applications.files.onlyoffice.enabled
39
+ }
36
40
  };
37
41
  const exportConfiguration = (reload = false)=>reload ? loadConfiguration() : configuration;
38
42
  function loadConfiguration() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../backend/src/configuration/config.environment.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 { join } from 'node:path'\nimport { AuthTokenAccessConfig, AuthTokenRefreshConfig } from '../authentication/auth.config'\nimport { ACCESS_KEY, CSRF_KEY, TWO_FA_VERIFY_EXPIRATION, WS_KEY } from '../authentication/constants/auth'\nimport { TOKEN_TYPE } from '../authentication/interfaces/token.interface'\nimport { transformAndValidate } from '../common/functions'\nimport { ServerConfig } from './config.interfaces'\nimport { configLoader } from './config.loader'\nimport { GlobalConfig } from './config.validation'\n\nexport const configuration: GlobalConfig = loadConfiguration()\nexport const serverConfig: ServerConfig = { twoFaEnabled: configuration.auth.mfa.totp.enabled, mailServerEnabled: !!configuration.mail?.host }\nexport const exportConfiguration: (reload?: boolean) => GlobalConfig = (reload = false) => (reload ? loadConfiguration() : configuration)\n\nfunction loadConfiguration(): GlobalConfig {\n const config: GlobalConfig = configLoader()\n // AUTHENTICATION\n // CSRF & WS & 2FA settings\n config.auth.token[TOKEN_TYPE.CSRF] = { ...config.auth.token[TOKEN_TYPE.REFRESH], name: CSRF_KEY } satisfies AuthTokenRefreshConfig\n config.auth.token[TOKEN_TYPE.WS] = { ...config.auth.token[TOKEN_TYPE.REFRESH], name: WS_KEY } satisfies AuthTokenRefreshConfig\n config.auth.token[TOKEN_TYPE.ACCESS_2FA] = {\n ...config.auth.token[TOKEN_TYPE.ACCESS],\n name: ACCESS_KEY,\n expiration: TWO_FA_VERIFY_EXPIRATION\n } satisfies AuthTokenAccessConfig\n config.auth.token[TOKEN_TYPE.CSRF_2FA] = {\n ...config.auth.token[TOKEN_TYPE.CSRF],\n expiration: TWO_FA_VERIFY_EXPIRATION\n } satisfies AuthTokenAccessConfig\n // APPLICATIONS CONFIGURATION\n // SPACES & FILES\n if (!config.applications.files.dataPath) {\n throw new Error('dataPath is not defined in environment.yaml')\n }\n config.applications.files.usersPath = join(config.applications.files.dataPath, 'users')\n config.applications.files.spacesPath = join(config.applications.files.dataPath, 'spaces')\n config.applications.files.tmpPath = join(config.applications.files.dataPath, 'tmp')\n return transformAndValidate(GlobalConfig, config, { exposeDefaultValues: true }, { skipMissingProperties: false })\n}\n"],"names":["configuration","exportConfiguration","serverConfig","loadConfiguration","twoFaEnabled","auth","mfa","totp","enabled","mailServerEnabled","mail","host","reload","config","configLoader","token","TOKEN_TYPE","CSRF","REFRESH","name","CSRF_KEY","WS","WS_KEY","ACCESS_2FA","ACCESS","ACCESS_KEY","expiration","TWO_FA_VERIFY_EXPIRATION","CSRF_2FA","applications","files","dataPath","Error","usersPath","join","spacesPath","tmpPath","transformAndValidate","GlobalConfig","exposeDefaultValues","skipMissingProperties"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAWYA;eAAAA;;QAEAC;eAAAA;;QADAC;eAAAA;;;0BAVQ;sBAEkD;gCAC5C;2BACU;8BAER;kCACA;AAEtB,MAAMF,gBAA8BG;AACpC,MAAMD,eAA6B;IAAEE,cAAcJ,cAAcK,IAAI,CAACC,GAAG,CAACC,IAAI,CAACC,OAAO;IAAEC,mBAAmB,CAAC,CAACT,cAAcU,IAAI,EAAEC;AAAK;AACtI,MAAMV,sBAA0D,CAACW,SAAS,KAAK,GAAMA,SAAST,sBAAsBH;AAE3H,SAASG;IACP,MAAMU,SAAuBC,IAAAA,0BAAY;IACzC,iBAAiB;IACjB,2BAA2B;IAC3BD,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACC,IAAI,CAAC,GAAG;QAAE,GAAGJ,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACE,OAAO,CAAC;QAAEC,MAAMC,cAAQ;IAAC;IAChGP,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACK,EAAE,CAAC,GAAG;QAAE,GAAGR,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACE,OAAO,CAAC;QAAEC,MAAMG,YAAM;IAAC;IAC5FT,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACO,UAAU,CAAC,GAAG;QACzC,GAAGV,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACQ,MAAM,CAAC;QACvCL,MAAMM,gBAAU;QAChBC,YAAYC,8BAAwB;IACtC;IACAd,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACY,QAAQ,CAAC,GAAG;QACvC,GAAGf,OAAOR,IAAI,CAACU,KAAK,CAACC,0BAAU,CAACC,IAAI,CAAC;QACrCS,YAAYC,8BAAwB;IACtC;IACA,6BAA6B;IAC7B,iBAAiB;IACjB,IAAI,CAACd,OAAOgB,YAAY,CAACC,KAAK,CAACC,QAAQ,EAAE;QACvC,MAAM,IAAIC,MAAM;IAClB;IACAnB,OAAOgB,YAAY,CAACC,KAAK,CAACG,SAAS,GAAGC,IAAAA,cAAI,EAACrB,OAAOgB,YAAY,CAACC,KAAK,CAACC,QAAQ,EAAE;IAC/ElB,OAAOgB,YAAY,CAACC,KAAK,CAACK,UAAU,GAAGD,IAAAA,cAAI,EAACrB,OAAOgB,YAAY,CAACC,KAAK,CAACC,QAAQ,EAAE;IAChFlB,OAAOgB,YAAY,CAACC,KAAK,CAACM,OAAO,GAAGF,IAAAA,cAAI,EAACrB,OAAOgB,YAAY,CAACC,KAAK,CAACC,QAAQ,EAAE;IAC7E,OAAOM,IAAAA,+BAAoB,EAACC,8BAAY,EAAEzB,QAAQ;QAAE0B,qBAAqB;IAAK,GAAG;QAAEC,uBAAuB;IAAM;AAClH"}
1
+ {"version":3,"sources":["../../../backend/src/configuration/config.environment.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 { join } from 'node:path'\nimport { AuthTokenAccessConfig, AuthTokenRefreshConfig } from '../authentication/auth.config'\nimport { ACCESS_KEY, CSRF_KEY, TWO_FA_VERIFY_EXPIRATION, WS_KEY } from '../authentication/constants/auth'\nimport { TOKEN_TYPE } from '../authentication/interfaces/token.interface'\nimport { transformAndValidate } from '../common/functions'\nimport { ServerConfig } from './config.interfaces'\nimport { configLoader } from './config.loader'\nimport { GlobalConfig } from './config.validation'\n\nexport const configuration: GlobalConfig = loadConfiguration()\nexport const serverConfig: ServerConfig = {\n twoFaEnabled: configuration.auth.mfa.totp.enabled,\n mailServerEnabled: !!configuration.mail?.host,\n fileEditors: {\n collabora: configuration.applications.files.collabora.enabled,\n onlyoffice: configuration.applications.files.onlyoffice.enabled\n }\n}\nexport const exportConfiguration: (reload?: boolean) => GlobalConfig = (reload = false) => (reload ? loadConfiguration() : configuration)\n\nfunction loadConfiguration(): GlobalConfig {\n const config: GlobalConfig = configLoader()\n // AUTHENTICATION\n // CSRF & WS & 2FA settings\n config.auth.token[TOKEN_TYPE.CSRF] = { ...config.auth.token[TOKEN_TYPE.REFRESH], name: CSRF_KEY } satisfies AuthTokenRefreshConfig\n config.auth.token[TOKEN_TYPE.WS] = { ...config.auth.token[TOKEN_TYPE.REFRESH], name: WS_KEY } satisfies AuthTokenRefreshConfig\n config.auth.token[TOKEN_TYPE.ACCESS_2FA] = {\n ...config.auth.token[TOKEN_TYPE.ACCESS],\n name: ACCESS_KEY,\n expiration: TWO_FA_VERIFY_EXPIRATION\n } satisfies AuthTokenAccessConfig\n config.auth.token[TOKEN_TYPE.CSRF_2FA] = {\n ...config.auth.token[TOKEN_TYPE.CSRF],\n expiration: TWO_FA_VERIFY_EXPIRATION\n } satisfies AuthTokenAccessConfig\n // APPLICATIONS CONFIGURATION\n // SPACES & FILES\n if (!config.applications.files.dataPath) {\n throw new Error('dataPath is not defined in environment.yaml')\n }\n config.applications.files.usersPath = join(config.applications.files.dataPath, 'users')\n config.applications.files.spacesPath = join(config.applications.files.dataPath, 'spaces')\n config.applications.files.tmpPath = join(config.applications.files.dataPath, 'tmp')\n return transformAndValidate(GlobalConfig, config, { exposeDefaultValues: true }, { skipMissingProperties: false })\n}\n"],"names":["configuration","exportConfiguration","serverConfig","loadConfiguration","twoFaEnabled","auth","mfa","totp","enabled","mailServerEnabled","mail","host","fileEditors","collabora","applications","files","onlyoffice","reload","config","configLoader","token","TOKEN_TYPE","CSRF","REFRESH","name","CSRF_KEY","WS","WS_KEY","ACCESS_2FA","ACCESS","ACCESS_KEY","expiration","TWO_FA_VERIFY_EXPIRATION","CSRF_2FA","dataPath","Error","usersPath","join","spacesPath","tmpPath","transformAndValidate","GlobalConfig","exposeDefaultValues","skipMissingProperties"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAWYA;eAAAA;;QASAC;eAAAA;;QARAC;eAAAA;;;0BAVQ;sBAEkD;gCAC5C;2BACU;8BAER;kCACA;AAEtB,MAAMF,gBAA8BG;AACpC,MAAMD,eAA6B;IACxCE,cAAcJ,cAAcK,IAAI,CAACC,GAAG,CAACC,IAAI,CAACC,OAAO;IACjDC,mBAAmB,CAAC,CAACT,cAAcU,IAAI,EAAEC;IACzCC,aAAa;QACXC,WAAWb,cAAcc,YAAY,CAACC,KAAK,CAACF,SAAS,CAACL,OAAO;QAC7DQ,YAAYhB,cAAcc,YAAY,CAACC,KAAK,CAACC,UAAU,CAACR,OAAO;IACjE;AACF;AACO,MAAMP,sBAA0D,CAACgB,SAAS,KAAK,GAAMA,SAASd,sBAAsBH;AAE3H,SAASG;IACP,MAAMe,SAAuBC,IAAAA,0BAAY;IACzC,iBAAiB;IACjB,2BAA2B;IAC3BD,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACC,IAAI,CAAC,GAAG;QAAE,GAAGJ,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACE,OAAO,CAAC;QAAEC,MAAMC,cAAQ;IAAC;IAChGP,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACK,EAAE,CAAC,GAAG;QAAE,GAAGR,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACE,OAAO,CAAC;QAAEC,MAAMG,YAAM;IAAC;IAC5FT,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACO,UAAU,CAAC,GAAG;QACzC,GAAGV,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACQ,MAAM,CAAC;QACvCL,MAAMM,gBAAU;QAChBC,YAAYC,8BAAwB;IACtC;IACAd,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACY,QAAQ,CAAC,GAAG;QACvC,GAAGf,OAAOb,IAAI,CAACe,KAAK,CAACC,0BAAU,CAACC,IAAI,CAAC;QACrCS,YAAYC,8BAAwB;IACtC;IACA,6BAA6B;IAC7B,iBAAiB;IACjB,IAAI,CAACd,OAAOJ,YAAY,CAACC,KAAK,CAACmB,QAAQ,EAAE;QACvC,MAAM,IAAIC,MAAM;IAClB;IACAjB,OAAOJ,YAAY,CAACC,KAAK,CAACqB,SAAS,GAAGC,IAAAA,cAAI,EAACnB,OAAOJ,YAAY,CAACC,KAAK,CAACmB,QAAQ,EAAE;IAC/EhB,OAAOJ,YAAY,CAACC,KAAK,CAACuB,UAAU,GAAGD,IAAAA,cAAI,EAACnB,OAAOJ,YAAY,CAACC,KAAK,CAACmB,QAAQ,EAAE;IAChFhB,OAAOJ,YAAY,CAACC,KAAK,CAACwB,OAAO,GAAGF,IAAAA,cAAI,EAACnB,OAAOJ,YAAY,CAACC,KAAK,CAACmB,QAAQ,EAAE;IAC7E,OAAOM,IAAAA,+BAAoB,EAACC,8BAAY,EAAEvB,QAAQ;QAAEwB,qBAAqB;IAAK,GAAG;QAAEC,uBAAuB;IAAM;AAClH"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../backend/src/configuration/config.interfaces.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 interface ServerConfig {\n twoFaEnabled: boolean\n mailServerEnabled: boolean\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}
1
+ {"version":3,"sources":["../../../backend/src/configuration/config.interfaces.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 interface FileEditorProvider {\n collabora: boolean\n onlyoffice: boolean\n}\n\nexport interface ServerConfig {\n twoFaEnabled: boolean\n mailServerEnabled: boolean\n fileEditors: FileEditorProvider\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}