@jesec/flood 0.0.0-master.485bb1f → 0.0.0-master.4867480

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 (383) hide show
  1. package/CHANGELOG.md +606 -103
  2. package/README.md +111 -45
  3. package/SECURITY.md +27 -0
  4. package/dist/assets/icon_128x128.png +0 -0
  5. package/dist/assets/icon_192x192.png +0 -0
  6. package/dist/assets/icon_256x256.png +0 -0
  7. package/dist/assets/icon_384x384.png +0 -0
  8. package/dist/assets/icon_512x512.png +0 -0
  9. package/dist/assets/icon_96x96.png +0 -0
  10. package/dist/assets/icon_maskable.png +0 -0
  11. package/dist/assets/icon_maskable_180x180.png +0 -0
  12. package/dist/assets/index.html +1 -1
  13. package/dist/assets/manifest.json +35 -7
  14. package/dist/assets/static/css/739.37bdb6f87f387ec14604.css +1 -0
  15. package/dist/assets/static/css/main.1e2641565fedeca72205.css +1 -0
  16. package/dist/assets/static/js/179.3c561f18.chunk.js +1 -0
  17. package/dist/assets/static/js/739.8137a4e3.chunk.js +1 -0
  18. package/dist/assets/static/js/963.94abcb99.chunk.js +1 -0
  19. package/dist/assets/static/js/996.f0e63eaa.chunk.js +1 -0
  20. package/dist/assets/static/js/flag0.56298b91.chunk.js +1 -0
  21. package/dist/assets/static/js/flag1.badfc781.chunk.js +1 -0
  22. package/dist/assets/static/js/flag2.c5a910ff.chunk.js +1 -0
  23. package/dist/assets/static/js/flag3.2a4050b4.chunk.js +1 -0
  24. package/dist/assets/static/js/i18n0.bbba23c0.chunk.js +1 -0
  25. package/dist/assets/static/js/i18n1.525034ab.chunk.js +1 -0
  26. package/dist/assets/static/js/i18n10.04799933.chunk.js +1 -0
  27. package/dist/assets/static/js/i18n11.d3db204f.chunk.js +1 -0
  28. package/dist/assets/static/js/i18n12.9521b48f.chunk.js +1 -0
  29. package/dist/assets/static/js/i18n13.c8168e17.chunk.js +1 -0
  30. package/dist/assets/static/js/i18n14.9410308a.chunk.js +1 -0
  31. package/dist/assets/static/js/i18n15.1b73c9b5.chunk.js +1 -0
  32. package/dist/assets/static/js/i18n16.d878b440.chunk.js +1 -0
  33. package/dist/assets/static/js/i18n17.13747eb1.chunk.js +1 -0
  34. package/dist/assets/static/js/i18n18.5eaf9fbc.chunk.js +1 -0
  35. package/dist/assets/static/js/i18n19.dd724997.chunk.js +1 -0
  36. package/dist/assets/static/js/i18n2.314f9d9b.chunk.js +1 -0
  37. package/dist/assets/static/js/i18n20.73fe1003.chunk.js +1 -0
  38. package/dist/assets/static/js/i18n21.ddacc27d.chunk.js +1 -0
  39. package/dist/assets/static/js/i18n22.cfce8716.chunk.js +1 -0
  40. package/dist/assets/static/js/i18n23.2a7653e9.chunk.js +1 -0
  41. package/dist/assets/static/js/i18n24.8f60cf8b.chunk.js +1 -0
  42. package/dist/assets/static/js/i18n25.7daba586.chunk.js +1 -0
  43. package/dist/assets/static/js/i18n26.97969f67.chunk.js +1 -0
  44. package/dist/assets/static/js/i18n27.8637db59.chunk.js +1 -0
  45. package/dist/assets/static/js/i18n28.ded89a8a.chunk.js +1 -0
  46. package/dist/assets/static/js/i18n3.47250d33.chunk.js +1 -0
  47. package/dist/assets/static/js/i18n4.dd4ca73b.chunk.js +1 -0
  48. package/dist/assets/static/js/i18n5.1788a7d3.chunk.js +1 -0
  49. package/dist/assets/static/js/i18n6.de9fcab7.chunk.js +1 -0
  50. package/dist/assets/static/js/i18n8.6320258a.chunk.js +1 -0
  51. package/dist/assets/static/js/i18n9.c97c17ff.chunk.js +1 -0
  52. package/dist/assets/static/js/main.07277f9f.js +1 -0
  53. package/dist/index.js +145865 -0
  54. package/package.json +212 -144
  55. package/dist/assets/android-chrome-192x192.png +0 -0
  56. package/dist/assets/android-chrome-512x512.png +0 -0
  57. package/dist/assets/apple-touch-icon.png +0 -0
  58. package/dist/assets/asset-manifest.json +0 -257
  59. package/dist/assets/browserconfig.xml +0 -9
  60. package/dist/assets/favicon-16x16.png +0 -0
  61. package/dist/assets/favicon-32x32.png +0 -0
  62. package/dist/assets/mstile-144x144.png +0 -0
  63. package/dist/assets/mstile-150x150.png +0 -0
  64. package/dist/assets/mstile-310x150.png +0 -0
  65. package/dist/assets/mstile-310x310.png +0 -0
  66. package/dist/assets/mstile-70x70.png +0 -0
  67. package/dist/assets/static/js/1.71ae8956.chunk.js +0 -1
  68. package/dist/assets/static/js/10.a45a228e.chunk.js +0 -1
  69. package/dist/assets/static/js/11.7f6bbbb3.chunk.js +0 -1
  70. package/dist/assets/static/js/12.3f02638d.chunk.js +0 -1
  71. package/dist/assets/static/js/13.003145b8.chunk.js +0 -1
  72. package/dist/assets/static/js/14.bbe409ac.chunk.js +0 -1
  73. package/dist/assets/static/js/15.ce71c4e1.chunk.js +0 -1
  74. package/dist/assets/static/js/16.f4193ed8.chunk.js +0 -1
  75. package/dist/assets/static/js/17.581fdacc.chunk.js +0 -1
  76. package/dist/assets/static/js/18.59a0c94f.chunk.js +0 -1
  77. package/dist/assets/static/js/19.a839a65b.chunk.js +0 -1
  78. package/dist/assets/static/js/2.58962026.chunk.js +0 -1
  79. package/dist/assets/static/js/20.818f1b24.chunk.js +0 -1
  80. package/dist/assets/static/js/21.04285aec.chunk.js +0 -1
  81. package/dist/assets/static/js/22.1e571711.chunk.js +0 -1
  82. package/dist/assets/static/js/23.97097f6f.chunk.js +0 -1
  83. package/dist/assets/static/js/24.9603687d.chunk.js +0 -1
  84. package/dist/assets/static/js/25.af7435f0.chunk.js +0 -1
  85. package/dist/assets/static/js/26.ce65fd84.chunk.js +0 -1
  86. package/dist/assets/static/js/27.71fcd72e.chunk.js +0 -1
  87. package/dist/assets/static/js/28.b40ebdf2.chunk.js +0 -1
  88. package/dist/assets/static/js/3.1a68b7c7.chunk.js +0 -1
  89. package/dist/assets/static/js/4.12725714.chunk.js +0 -1
  90. package/dist/assets/static/js/5.edc14adb.chunk.js +0 -1
  91. package/dist/assets/static/js/6.102dfd16.chunk.js +0 -1
  92. package/dist/assets/static/js/7.458ee78a.chunk.js +0 -1
  93. package/dist/assets/static/js/8.070d774c.chunk.js +0 -1
  94. package/dist/assets/static/js/9.9f52d404.chunk.js +0 -1
  95. package/dist/assets/static/js/main.1797aead.js +0 -347
  96. package/dist/assets/static/media/ABOUT.d02918c9.md +0 -13
  97. package/dist/assets/static/media/Roboto-500.64e69384.woff +0 -0
  98. package/dist/assets/static/media/Roboto-500.7f8f0146.eot +0 -0
  99. package/dist/assets/static/media/Roboto-500.916656a2.ttf +0 -0
  100. package/dist/assets/static/media/Roboto-500.abd255e8.svg +0 -305
  101. package/dist/assets/static/media/Roboto-700.8d11d1e1.ttf +0 -0
  102. package/dist/assets/static/media/Roboto-700.9c9c164e.svg +0 -310
  103. package/dist/assets/static/media/Roboto-700.c65552c8.eot +0 -0
  104. package/dist/assets/static/media/Roboto-700.ee82bda2.woff +0 -0
  105. package/dist/assets/static/media/Roboto-700italic.1dc5bfed.eot +0 -0
  106. package/dist/assets/static/media/Roboto-700italic.686da014.woff +0 -0
  107. package/dist/assets/static/media/Roboto-700italic.896656dc.ttf +0 -0
  108. package/dist/assets/static/media/Roboto-700italic.cacb9681.svg +0 -325
  109. package/dist/assets/static/media/Roboto-italic.09ed2f27.svg +0 -323
  110. package/dist/assets/static/media/Roboto-italic.c1421604.woff +0 -0
  111. package/dist/assets/static/media/Roboto-italic.c38ecad2.ttf +0 -0
  112. package/dist/assets/static/media/Roboto-italic.f7677a07.eot +0 -0
  113. package/dist/assets/static/media/Roboto-regular.5107f918.eot +0 -0
  114. package/dist/assets/static/media/Roboto-regular.6a307cf2.woff +0 -0
  115. package/dist/assets/static/media/Roboto-regular.81dc9b21.ttf +0 -0
  116. package/dist/assets/static/media/Roboto-regular.bcf2ba9e.svg +0 -308
  117. package/dist/config.js +0 -173
  118. package/dist/server/app.js +0 -79
  119. package/dist/server/bin/enforce-prerequisites.js +0 -55
  120. package/dist/server/bin/migrations/fix-is-admin-flag.js +0 -41
  121. package/dist/server/bin/migrations/per-user-rtorrent-instances.js +0 -67
  122. package/dist/server/bin/migrations/run.js +0 -10
  123. package/dist/server/bin/start.js +0 -18
  124. package/dist/server/bin/web-server.js +0 -93
  125. package/dist/server/config/passport.js +0 -32
  126. package/dist/server/constants/clientGatewayServiceEvents.js +0 -15
  127. package/dist/server/constants/diskUsageServiceEvents.js +0 -8
  128. package/dist/server/constants/fileListPropMap.js +0 -29
  129. package/dist/server/constants/historyServiceEvents.js +0 -18
  130. package/dist/server/constants/notificationServiceEvents.js +0 -8
  131. package/dist/server/constants/taxonomyServiceEvents.js +0 -8
  132. package/dist/server/constants/torrentListPropMap.js +0 -200
  133. package/dist/server/constants/torrentServiceEvents.js +0 -8
  134. package/dist/server/constants/transferSummaryPropMap.js +0 -28
  135. package/dist/server/middleware/appendUserServices.js +0 -10
  136. package/dist/server/middleware/booleanCoerce.js +0 -9
  137. package/dist/server/middleware/clientActivityStream.js +0 -124
  138. package/dist/server/middleware/eventStream.js +0 -25
  139. package/dist/server/middleware/requireAdmin.js +0 -8
  140. package/dist/server/models/ClientRequest.js +0 -310
  141. package/dist/server/models/Feed.js +0 -65
  142. package/dist/server/models/Filesystem.js +0 -44
  143. package/dist/server/models/HistoryEra.js +0 -168
  144. package/dist/server/models/ServerEvent.js +0 -27
  145. package/dist/server/models/TemporaryStorage.js +0 -20
  146. package/dist/server/models/Users.js +0 -160
  147. package/dist/server/models/client.js +0 -363
  148. package/dist/server/models/settings.js +0 -119
  149. package/dist/server/routes/api.js +0 -69
  150. package/dist/server/routes/auth.js +0 -184
  151. package/dist/server/routes/client.js +0 -101
  152. package/dist/server/services/BaseService.js +0 -24
  153. package/dist/server/services/clientGatewayService.js +0 -220
  154. package/dist/server/services/clientRequestManager.js +0 -76
  155. package/dist/server/services/diskUsageService.js +0 -133
  156. package/dist/server/services/feedService.js +0 -290
  157. package/dist/server/services/historyService.js +0 -181
  158. package/dist/server/services/index.js +0 -108
  159. package/dist/server/services/notificationService.js +0 -108
  160. package/dist/server/services/taxonomyService.js +0 -107
  161. package/dist/server/services/torrentService.js +0 -235
  162. package/dist/server/util/ajaxUtil.js +0 -19
  163. package/dist/server/util/clientResponseUtil.js +0 -99
  164. package/dist/server/util/fileUtil.js +0 -45
  165. package/dist/server/util/mediainfo.js +0 -34
  166. package/dist/server/util/methodCallUtil.js +0 -22
  167. package/dist/server/util/numberUtils.js +0 -7
  168. package/dist/server/util/rTorrentDeserializer.js +0 -104
  169. package/dist/server/util/rTorrentPropMap.js +0 -13
  170. package/dist/server/util/scgiUtil.js +0 -36
  171. package/dist/server/util/torrentFileUtil.js +0 -23
  172. package/dist/shared/config/paths.js +0 -41
  173. package/dist/shared/constants/clientSettingsMap.js +0 -53
  174. package/dist/shared/constants/diffActionTypes.js +0 -6
  175. package/dist/shared/constants/historySnapshotTypes.js +0 -11
  176. package/dist/shared/constants/serverEventTypes.js +0 -18
  177. package/dist/shared/constants/torrentFilePropsMap.js +0 -6
  178. package/dist/shared/constants/torrentPeerPropsMap.js +0 -32
  179. package/dist/shared/constants/torrentStatusMap.js +0 -17
  180. package/dist/shared/constants/torrentTrackerPropsMap.js +0 -6
  181. package/dist/shared/util/formatUtil.js +0 -73
  182. package/dist/shared/util/objectUtil.js +0 -56
  183. package/dist/shared/util/regEx.js +0 -7
  184. /package/dist/assets/{safari-pinned-tab.svg → icon.svg} +0 -0
  185. /package/dist/assets/static/{images/flags/ad.png → media/ad.1b24595d.png} +0 -0
  186. /package/dist/assets/static/{images/flags/ae.png → media/ae.4dd8f55e.png} +0 -0
  187. /package/dist/assets/static/{images/flags/af.png → media/af.4ce660eb.png} +0 -0
  188. /package/dist/assets/static/{images/flags/ag.png → media/ag.fd9409e4.png} +0 -0
  189. /package/dist/assets/static/{images/flags/al.png → media/al.a297aacf.png} +0 -0
  190. /package/dist/assets/static/{images/flags/am.png → media/am.c84ee0cf.png} +0 -0
  191. /package/dist/assets/static/{images/flags/ao.png → media/ao.a7c9214e.png} +0 -0
  192. /package/dist/assets/static/{images/flags/ar.png → media/ar.7e57ef92.png} +0 -0
  193. /package/dist/assets/static/{images/flags/at.png → media/at.5aa9728a.png} +0 -0
  194. /package/dist/assets/static/{images/flags/au.png → media/au.155b51d8.png} +0 -0
  195. /package/dist/assets/static/{images/flags/az.png → media/az.63afef5b.png} +0 -0
  196. /package/dist/assets/static/{images/flags/ba.png → media/ba.5ce8f273.png} +0 -0
  197. /package/dist/assets/static/{images/flags/bb.png → media/bb.f369fc62.png} +0 -0
  198. /package/dist/assets/static/{images/flags/bd.png → media/bd.516278fc.png} +0 -0
  199. /package/dist/assets/static/{images/flags/be.png → media/be.08ec4a8d.png} +0 -0
  200. /package/dist/assets/static/{images/flags/bf.png → media/bf.50bfcb31.png} +0 -0
  201. /package/dist/assets/static/{images/flags/bg.png → media/bg.d9346b96.png} +0 -0
  202. /package/dist/assets/static/{images/flags/bh.png → media/bh.f06d5914.png} +0 -0
  203. /package/dist/assets/static/{images/flags/bi.png → media/bi.4923e3a3.png} +0 -0
  204. /package/dist/assets/static/{images/flags/bj.png → media/bj.019fa79b.png} +0 -0
  205. /package/dist/assets/static/{images/flags/bn.png → media/bn.077671e2.png} +0 -0
  206. /package/dist/assets/static/{images/flags/bo.png → media/bo.8fb15fc6.png} +0 -0
  207. /package/dist/assets/static/{images/flags/br.png → media/br.ec051f0c.png} +0 -0
  208. /package/dist/assets/static/{images/flags/bs.png → media/bs.a74a126f.png} +0 -0
  209. /package/dist/assets/static/{images/flags/bt.png → media/bt.4217b804.png} +0 -0
  210. /package/dist/assets/static/{images/flags/bw.png → media/bw.21fe1567.png} +0 -0
  211. /package/dist/assets/static/{images/flags/by.png → media/by.d247fe16.png} +0 -0
  212. /package/dist/assets/static/{images/flags/bz.png → media/bz.98ec59f6.png} +0 -0
  213. /package/dist/assets/static/{images/flags/ca.png → media/ca.25743e11.png} +0 -0
  214. /package/dist/assets/static/{images/flags/cd.png → media/cd.a5bfda53.png} +0 -0
  215. /package/dist/assets/static/{images/flags/cf.png → media/cf.de7d5d92.png} +0 -0
  216. /package/dist/assets/static/{images/flags/cg.png → media/cg.a47b626b.png} +0 -0
  217. /package/dist/assets/static/{images/flags/ch.png → media/ch.445f47a1.png} +0 -0
  218. /package/dist/assets/static/{images/flags/ci.png → media/ci.a6009c5b.png} +0 -0
  219. /package/dist/assets/static/{images/flags/cl.png → media/cl.de1d715e.png} +0 -0
  220. /package/dist/assets/static/{images/flags/cm.png → media/cm.3ce8a86a.png} +0 -0
  221. /package/dist/assets/static/{images/flags/cn.png → media/cn.e6a26073.png} +0 -0
  222. /package/dist/assets/static/{images/flags/co.png → media/co.e9244faa.png} +0 -0
  223. /package/dist/assets/static/{images/flags/cr.png → media/cr.c895e035.png} +0 -0
  224. /package/dist/assets/static/{images/flags/cu.png → media/cu.e486c055.png} +0 -0
  225. /package/dist/assets/static/{images/flags/cv.png → media/cv.a9585acf.png} +0 -0
  226. /package/dist/assets/static/{images/flags/cw.png → media/cw.df13039d.png} +0 -0
  227. /package/dist/assets/static/{images/flags/cy.png → media/cy.b31f43a9.png} +0 -0
  228. /package/dist/assets/static/{images/flags/cz.png → media/cz.8ec5948b.png} +0 -0
  229. /package/dist/assets/static/{images/flags/de.png → media/de.d12f391a.png} +0 -0
  230. /package/dist/assets/static/{images/flags/dj.png → media/dj.154c3580.png} +0 -0
  231. /package/dist/assets/static/{images/flags/dk.png → media/dk.da382fe2.png} +0 -0
  232. /package/dist/assets/static/{images/flags/dm.png → media/dm.f452e6cd.png} +0 -0
  233. /package/dist/assets/static/{images/flags/do.png → media/do.c6bd7637.png} +0 -0
  234. /package/dist/assets/static/{images/flags/dz.png → media/dz.672a69c0.png} +0 -0
  235. /package/dist/assets/static/{images/flags/ec.png → media/ec.349d9bd7.png} +0 -0
  236. /package/dist/assets/static/{images/flags/ee.png → media/ee.2396205f.png} +0 -0
  237. /package/dist/assets/static/{images/flags/eg.png → media/eg.ccbf3f45.png} +0 -0
  238. /package/dist/assets/static/{images/flags/eh.png → media/eh.af65674a.png} +0 -0
  239. /package/dist/assets/static/{images/flags/er.png → media/er.21afb638.png} +0 -0
  240. /package/dist/assets/static/{images/flags/es.png → media/es.2a6eaee4.png} +0 -0
  241. /package/dist/assets/static/{images/flags/et.png → media/et.8beb65c8.png} +0 -0
  242. /package/dist/assets/static/{images/flags/fi.png → media/fi.331f70fd.png} +0 -0
  243. /package/dist/assets/static/{images/flags/fj.png → media/fj.7724d800.png} +0 -0
  244. /package/dist/assets/static/{images/flags/fm.png → media/fm.eeaf71e9.png} +0 -0
  245. /package/dist/assets/static/{images/flags/fr.png → media/fr.5d5ab008.png} +0 -0
  246. /package/dist/assets/static/{images/flags/ga.png → media/ga.77ed474c.png} +0 -0
  247. /package/dist/assets/static/{images/flags/gb.png → media/gb.e00065bf.png} +0 -0
  248. /package/dist/assets/static/{images/flags/gd.png → media/gd.b4522267.png} +0 -0
  249. /package/dist/assets/static/{images/flags/ge.png → media/ge.91a7654d.png} +0 -0
  250. /package/dist/assets/static/{images/flags/gh.png → media/gh.4759f92f.png} +0 -0
  251. /package/dist/assets/static/{images/flags/gm.png → media/gm.81cd9f75.png} +0 -0
  252. /package/dist/assets/static/{images/flags/gn.png → media/gn.9f3d376e.png} +0 -0
  253. /package/dist/assets/static/{images/flags/gq.png → media/gq.e8ad58be.png} +0 -0
  254. /package/dist/assets/static/{images/flags/gr.png → media/gr.26f3ac0b.png} +0 -0
  255. /package/dist/assets/static/{images/flags/gt.png → media/gt.9d81c52e.png} +0 -0
  256. /package/dist/assets/static/{images/flags/gw.png → media/gw.dc906982.png} +0 -0
  257. /package/dist/assets/static/{images/flags/gy.png → media/gy.a4f62b6c.png} +0 -0
  258. /package/dist/assets/static/{images/flags/hk.png → media/hk.56555c3f.png} +0 -0
  259. /package/dist/assets/static/{images/flags/hn.png → media/hn.64ee6aad.png} +0 -0
  260. /package/dist/assets/static/{images/flags/hr.png → media/hr.93ebecd3.png} +0 -0
  261. /package/dist/assets/static/{images/flags/ht.png → media/ht.42ca1596.png} +0 -0
  262. /package/dist/assets/static/{images/flags/hu.png → media/hu.bb30f05d.png} +0 -0
  263. /package/dist/assets/static/{images/flags/id.png → media/id.2cb49f2d.png} +0 -0
  264. /package/dist/assets/static/{images/flags/ie.png → media/ie.b4dd1f19.png} +0 -0
  265. /package/dist/assets/static/{images/flags/il.png → media/il.cd1d1faf.png} +0 -0
  266. /package/dist/assets/static/{images/flags/in.png → media/in.2df03847.png} +0 -0
  267. /package/dist/assets/static/{images/flags/iq.png → media/iq.a9b670ab.png} +0 -0
  268. /package/dist/assets/static/{images/flags/ir.png → media/ir.9a3de085.png} +0 -0
  269. /package/dist/assets/static/{images/flags/is.png → media/is.d88f4fc9.png} +0 -0
  270. /package/dist/assets/static/{images/flags/it.png → media/it.b73713e3.png} +0 -0
  271. /package/dist/assets/static/{images/flags/je.png → media/je.0353f56a.png} +0 -0
  272. /package/dist/assets/static/{images/flags/jm.png → media/jm.20330ef4.png} +0 -0
  273. /package/dist/assets/static/{images/flags/jo.png → media/jo.eb66f1d1.png} +0 -0
  274. /package/dist/assets/static/{images/flags/jp.png → media/jp.63e382ae.png} +0 -0
  275. /package/dist/assets/static/{images/flags/ke.png → media/ke.ab2e43b8.png} +0 -0
  276. /package/dist/assets/static/{images/flags/kg.png → media/kg.2c47c2af.png} +0 -0
  277. /package/dist/assets/static/{images/flags/kh.png → media/kh.4732c810.png} +0 -0
  278. /package/dist/assets/static/{images/flags/ki.png → media/ki.5fba09fd.png} +0 -0
  279. /package/dist/assets/static/{images/flags/km.png → media/km.7bbed3e9.png} +0 -0
  280. /package/dist/assets/static/{images/flags/kn.png → media/kn.a9595a16.png} +0 -0
  281. /package/dist/assets/static/{images/flags/kp.png → media/kp.8a4dc30a.png} +0 -0
  282. /package/dist/assets/static/{images/flags/kr.png → media/kr.5273be1d.png} +0 -0
  283. /package/dist/assets/static/{images/flags/ks.png → media/ks.99f78645.png} +0 -0
  284. /package/dist/assets/static/{images/flags/kw.png → media/kw.af3521bc.png} +0 -0
  285. /package/dist/assets/static/{images/flags/kz.png → media/kz.ea47ef79.png} +0 -0
  286. /package/dist/assets/static/{images/flags/la.png → media/la.78a598d7.png} +0 -0
  287. /package/dist/assets/static/{images/flags/lb.png → media/lb.7a7c15a9.png} +0 -0
  288. /package/dist/assets/static/{images/flags/lc.png → media/lc.6083a4ff.png} +0 -0
  289. /package/dist/assets/static/{images/flags/li.png → media/li.61c564a4.png} +0 -0
  290. /package/dist/assets/static/{images/flags/lk.png → media/lk.6fa85802.png} +0 -0
  291. /package/dist/assets/static/{images/flags/lr.png → media/lr.8063f7db.png} +0 -0
  292. /package/dist/assets/static/{images/flags/ls.png → media/ls.901ddb71.png} +0 -0
  293. /package/dist/assets/static/{images/flags/lt.png → media/lt.9209ace3.png} +0 -0
  294. /package/dist/assets/static/{images/flags/lu.png → media/lu.c9872bc1.png} +0 -0
  295. /package/dist/assets/static/{images/flags/lv.png → media/lv.7bcacf0a.png} +0 -0
  296. /package/dist/assets/static/{images/flags/ly.png → media/ly.2830aa63.png} +0 -0
  297. /package/dist/assets/static/{images/flags/ma.png → media/ma.ce5f697b.png} +0 -0
  298. /package/dist/assets/static/{images/flags/mc.png → media/mc.4bd5d57a.png} +0 -0
  299. /package/dist/assets/static/{images/flags/md.png → media/md.fb4b5bdf.png} +0 -0
  300. /package/dist/assets/static/{images/flags/me.png → media/me.1f1d1772.png} +0 -0
  301. /package/dist/assets/static/{images/flags/mg.png → media/mg.89101bd2.png} +0 -0
  302. /package/dist/assets/static/{images/flags/mh.png → media/mh.ff11dff7.png} +0 -0
  303. /package/dist/assets/static/{images/flags/mk.png → media/mk.8420e604.png} +0 -0
  304. /package/dist/assets/static/{images/flags/ml.png → media/ml.4db47c66.png} +0 -0
  305. /package/dist/assets/static/{images/flags/mm.png → media/mm.8e4ac30a.png} +0 -0
  306. /package/dist/assets/static/{images/flags/mn.png → media/mn.dc1daa04.png} +0 -0
  307. /package/dist/assets/static/{images/flags/mr.png → media/mr.7cbca6d0.png} +0 -0
  308. /package/dist/assets/static/{images/flags/mt.png → media/mt.28a4b863.png} +0 -0
  309. /package/dist/assets/static/{images/flags/mu.png → media/mu.d93db6c7.png} +0 -0
  310. /package/dist/assets/static/{images/flags/mv.png → media/mv.7d026bf1.png} +0 -0
  311. /package/dist/assets/static/{images/flags/mw.png → media/mw.960cd4fb.png} +0 -0
  312. /package/dist/assets/static/{images/flags/mx.png → media/mx.39b78eb2.png} +0 -0
  313. /package/dist/assets/static/{images/flags/my.png → media/my.916a8392.png} +0 -0
  314. /package/dist/assets/static/{images/flags/mz.png → media/mz.facb4ea3.png} +0 -0
  315. /package/dist/assets/static/{images/flags/na.png → media/na.472666a9.png} +0 -0
  316. /package/dist/assets/static/{images/flags/ne.png → media/ne.d774701f.png} +0 -0
  317. /package/dist/assets/static/{images/flags/ng.png → media/ng.7b06a49f.png} +0 -0
  318. /package/dist/assets/static/{images/flags/ni.png → media/ni.7140131c.png} +0 -0
  319. /package/dist/assets/static/{images/flags/nl.png → media/nl.4c04aa96.png} +0 -0
  320. /package/dist/assets/static/{images/flags/no.png → media/no.c19eb00d.png} +0 -0
  321. /package/dist/assets/static/{images/flags/np.png → media/np.54fb4f2f.png} +0 -0
  322. /package/dist/assets/static/{images/flags/nr.png → media/nr.7527cc38.png} +0 -0
  323. /package/dist/assets/static/{images/flags/nz.png → media/nz.738be05b.png} +0 -0
  324. /package/dist/assets/static/{images/flags/om.png → media/om.b25e0a17.png} +0 -0
  325. /package/dist/assets/static/{images/flags/pa.png → media/pa.b28a9059.png} +0 -0
  326. /package/dist/assets/static/{images/flags/pe.png → media/pe.c1fc1d96.png} +0 -0
  327. /package/dist/assets/static/{images/flags/pg.png → media/pg.380115db.png} +0 -0
  328. /package/dist/assets/static/{images/flags/ph.png → media/ph.02199ddc.png} +0 -0
  329. /package/dist/assets/static/{images/flags/pk.png → media/pk.094f9517.png} +0 -0
  330. /package/dist/assets/static/{images/flags/pl.png → media/pl.41521283.png} +0 -0
  331. /package/dist/assets/static/{images/flags/pt.png → media/pt.1f82dc04.png} +0 -0
  332. /package/dist/assets/static/{images/flags/pw.png → media/pw.a26c2316.png} +0 -0
  333. /package/dist/assets/static/{images/flags/py.png → media/py.926c65ed.png} +0 -0
  334. /package/dist/assets/static/{images/flags/qa.png → media/qa.c6a3c20e.png} +0 -0
  335. /package/dist/assets/static/{images/flags/ro.png → media/ro.a36876c9.png} +0 -0
  336. /package/dist/assets/static/{images/flags/rs.png → media/rs.c6629de8.png} +0 -0
  337. /package/dist/assets/static/{images/flags/ru.png → media/ru.a9b948c1.png} +0 -0
  338. /package/dist/assets/static/{images/flags/rw.png → media/rw.e8aecba0.png} +0 -0
  339. /package/dist/assets/static/{images/flags/sa.png → media/sa.859049c8.png} +0 -0
  340. /package/dist/assets/static/{images/flags/sb.png → media/sb.4ad27b27.png} +0 -0
  341. /package/dist/assets/static/{images/flags/sc.png → media/sc.3293efde.png} +0 -0
  342. /package/dist/assets/static/{images/flags/sd.png → media/sd.19c94faa.png} +0 -0
  343. /package/dist/assets/static/{images/flags/se.png → media/se.195b3f93.png} +0 -0
  344. /package/dist/assets/static/{images/flags/sg.png → media/sg.19d81907.png} +0 -0
  345. /package/dist/assets/static/{images/flags/si.png → media/si.367c5443.png} +0 -0
  346. /package/dist/assets/static/{images/flags/sk.png → media/sk.4e5b8a39.png} +0 -0
  347. /package/dist/assets/static/{images/flags/sl.png → media/sl.4b174b1c.png} +0 -0
  348. /package/dist/assets/static/{images/flags/sm.png → media/sm.2cba3dac.png} +0 -0
  349. /package/dist/assets/static/{images/flags/sn.png → media/sn.a4c1041d.png} +0 -0
  350. /package/dist/assets/static/{images/flags/so.png → media/so.b455e3bf.png} +0 -0
  351. /package/dist/assets/static/{images/flags/sr.png → media/sr.5adc1c00.png} +0 -0
  352. /package/dist/assets/static/{images/flags/st.png → media/st.5ae44155.png} +0 -0
  353. /package/dist/assets/static/{images/flags/sv.png → media/sv.43aa6cdf.png} +0 -0
  354. /package/dist/assets/static/{images/flags/sy.png → media/sy.0fbd24f7.png} +0 -0
  355. /package/dist/assets/static/{images/flags/sz.png → media/sz.ff204912.png} +0 -0
  356. /package/dist/assets/static/{images/flags/td.png → media/td.c7aa2a4e.png} +0 -0
  357. /package/dist/assets/static/{images/flags/tg.png → media/tg.857c3bec.png} +0 -0
  358. /package/dist/assets/static/{images/flags/th.png → media/th.683600c7.png} +0 -0
  359. /package/dist/assets/static/{images/flags/tj.png → media/tj.d20c5570.png} +0 -0
  360. /package/dist/assets/static/{images/flags/tl.png → media/tl.5edd8ea7.png} +0 -0
  361. /package/dist/assets/static/{images/flags/tm.png → media/tm.15960215.png} +0 -0
  362. /package/dist/assets/static/{images/flags/tn.png → media/tn.40df718e.png} +0 -0
  363. /package/dist/assets/static/{images/flags/to.png → media/to.c3b054df.png} +0 -0
  364. /package/dist/assets/static/{images/flags/tr.png → media/tr.adeace6d.png} +0 -0
  365. /package/dist/assets/static/{images/flags/tt.png → media/tt.839bd7f1.png} +0 -0
  366. /package/dist/assets/static/{images/flags/tv.png → media/tv.628cae3e.png} +0 -0
  367. /package/dist/assets/static/{images/flags/tw.png → media/tw.4e885914.png} +0 -0
  368. /package/dist/assets/static/{images/flags/tz.png → media/tz.b2f0dc37.png} +0 -0
  369. /package/dist/assets/static/{images/flags/ua.png → media/ua.6b103313.png} +0 -0
  370. /package/dist/assets/static/{images/flags/ug.png → media/ug.c84042fc.png} +0 -0
  371. /package/dist/assets/static/{images/flags/us.png → media/us.8523c31d.png} +0 -0
  372. /package/dist/assets/static/{images/flags/uy.png → media/uy.a943f85e.png} +0 -0
  373. /package/dist/assets/static/{images/flags/uz.png → media/uz.25552673.png} +0 -0
  374. /package/dist/assets/static/{images/flags/va.png → media/va.a29e1b53.png} +0 -0
  375. /package/dist/assets/static/{images/flags/vc.png → media/vc.7480bd37.png} +0 -0
  376. /package/dist/assets/static/{images/flags/ve.png → media/ve.fd4273c2.png} +0 -0
  377. /package/dist/assets/static/{images/flags/vn.png → media/vn.7d2eff1b.png} +0 -0
  378. /package/dist/assets/static/{images/flags/vu.png → media/vu.48b64cf3.png} +0 -0
  379. /package/dist/assets/static/{images/flags/ws.png → media/ws.f3d9202f.png} +0 -0
  380. /package/dist/assets/static/{images/flags/ye.png → media/ye.311a0e50.png} +0 -0
  381. /package/dist/assets/static/{images/flags/za.png → media/za.090a856f.png} +0 -0
  382. /package/dist/assets/static/{images/flags/zm.png → media/zm.8371e197.png} +0 -0
  383. /package/dist/assets/static/{images/flags/zw.png → media/zw.a6809447.png} +0 -0
@@ -1,184 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = __importDefault(require("express"));
7
- const joi_1 = __importDefault(require("joi"));
8
- const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
- const passport_1 = __importDefault(require("passport"));
10
- const ajaxUtil_1 = __importDefault(require("../util/ajaxUtil"));
11
- const requireAdmin_1 = __importDefault(require("../middleware/requireAdmin"));
12
- const config_1 = __importDefault(require("../../config"));
13
- const services_1 = __importDefault(require("../services"));
14
- const Users_1 = __importDefault(require("../models/Users"));
15
- const router = express_1.default.Router();
16
- const failedLoginResponse = 'Failed login.';
17
- const setAuthToken = (res, username, isAdmin) => {
18
- const expirationSeconds = 60 * 60 * 24 * 7; // one week
19
- const cookieExpiration = Date.now() + expirationSeconds * 1000;
20
- // Create token if the password matched and no error was thrown.
21
- const token = jsonwebtoken_1.default.sign({ username }, config_1.default.secret, {
22
- expiresIn: expirationSeconds,
23
- });
24
- res.cookie('jwt', token, { expires: new Date(cookieExpiration), httpOnly: true, sameSite: 'Strict' });
25
- return res.json({
26
- success: true,
27
- token: `JWT ${token}`,
28
- username,
29
- isAdmin,
30
- });
31
- };
32
- const authValidation = joi_1.default.object().keys({
33
- username: joi_1.default.string(),
34
- password: joi_1.default.string(),
35
- host: joi_1.default.string(),
36
- port: joi_1.default.string(),
37
- socketPath: joi_1.default.string(),
38
- isAdmin: joi_1.default.bool(),
39
- });
40
- router.use('/', (req, res, next) => {
41
- const validation = authValidation.validate(req.body);
42
- if (!validation.error) {
43
- next();
44
- }
45
- else {
46
- res.status(422).json({
47
- message: 'Validation error.',
48
- error: validation.error,
49
- });
50
- }
51
- });
52
- router.use('/users', passport_1.default.authenticate('jwt', { session: false }), requireAdmin_1.default);
53
- router.post('/authenticate', (req, res) => {
54
- if (config_1.default.disableUsersAndAuth) {
55
- return setAuthToken(res, Users_1.default.getConfigUser()._id, true);
56
- }
57
- const credentials = {
58
- password: req.body.password,
59
- username: req.body.username,
60
- };
61
- Users_1.default.comparePassword(credentials, (isMatch, isAdmin, err) => {
62
- if (isMatch != null && !err) {
63
- return setAuthToken(res, credentials.username, isAdmin);
64
- }
65
- // Incorrect username or password.
66
- return res.status(401).json({
67
- message: failedLoginResponse,
68
- });
69
- });
70
- });
71
- // Allow unauthenticated registration if no users are currently registered.
72
- router.use('/register', (req, res, next) => {
73
- Users_1.default.initialUserGate({
74
- handleInitialUser: () => {
75
- next();
76
- },
77
- handleSubsequentUser: () => {
78
- passport_1.default.authenticate('jwt', { session: false }, (passportReq, passportRes) => {
79
- passportRes.json({ username: req.username });
80
- });
81
- },
82
- });
83
- });
84
- router.post('/register', (req, res) => {
85
- // No user can be registered when disableUsersAndAuth is true
86
- if (config_1.default.disableUsersAndAuth) {
87
- // Return 404
88
- res.status(404).send('Not found');
89
- return;
90
- }
91
- // Attempt to save the user
92
- Users_1.default.createUser({
93
- username: req.body.username,
94
- password: req.body.password,
95
- host: req.body.host,
96
- port: req.body.port,
97
- socketPath: req.body.socketPath,
98
- isAdmin: true,
99
- }, (createUserResponse, createUserError) => {
100
- if (createUserError) {
101
- ajaxUtil_1.default.getResponseFn(res)(createUserResponse, createUserError);
102
- return;
103
- }
104
- setAuthToken(res, req.body.username, true);
105
- });
106
- });
107
- // Allow unauthenticated verification if no users are currently registered.
108
- router.use('/verify', (req, res, next) => {
109
- if (config_1.default.disableUsersAndAuth) {
110
- return setAuthToken(res, Users_1.default.getConfigUser()._id, true);
111
- }
112
- Users_1.default.initialUserGate({
113
- handleInitialUser: () => {
114
- req.initialUser = true;
115
- next();
116
- },
117
- handleSubsequentUser: () => {
118
- req.initialUser = false;
119
- passport_1.default.authenticate('jwt', { session: false })(req, res, next);
120
- },
121
- });
122
- });
123
- router.get('/verify', (req, res) => {
124
- res.json({
125
- initialUser: req.initialUser,
126
- username: req.user && req.user.username,
127
- isAdmin: req.user && req.user.isAdmin,
128
- });
129
- });
130
- // All subsequent routes are protected.
131
- router.use('/', passport_1.default.authenticate('jwt', { session: false }));
132
- router.get('/logout', (req, res) => {
133
- res.clearCookie('jwt').send();
134
- });
135
- router.use('/users', (req, res, next) => {
136
- // No operation on user when disableUsersAndAuth is true
137
- if (config_1.default.disableUsersAndAuth) {
138
- // Return 404
139
- res.status(404).send('Not found');
140
- return;
141
- }
142
- if (req.user && req.user.isAdmin) {
143
- next();
144
- return;
145
- }
146
- res.status(401).send('Not authorized');
147
- });
148
- router.get('/users', (req, res) => {
149
- Users_1.default.listUsers(ajaxUtil_1.default.getResponseFn(res));
150
- });
151
- router.delete('/users/:username', (req, res) => {
152
- Users_1.default.removeUser(req.params.username, ajaxUtil_1.default.getResponseFn(res));
153
- services_1.default.destroyUserServices(req.user);
154
- });
155
- router.patch('/users/:username', (req, res) => {
156
- const { username } = req.params;
157
- const userPatch = req.body;
158
- if (!userPatch.socketPath) {
159
- userPatch.socketPath = null;
160
- }
161
- else {
162
- userPatch.host = null;
163
- userPatch.port = null;
164
- }
165
- Users_1.default.updateUser(username, userPatch, () => {
166
- Users_1.default.lookupUser({ username }, (err, user) => {
167
- if (err)
168
- return req.status(500).json({ error: err });
169
- services_1.default.updateUserServices(user);
170
- res.send();
171
- });
172
- });
173
- });
174
- router.put('/users', (req, res) => {
175
- Users_1.default.createUser({
176
- username: req.body.username,
177
- password: req.body.password,
178
- host: req.body.host,
179
- port: req.body.port,
180
- socketPath: req.body.socketPath,
181
- isAdmin: req.body.isAdmin,
182
- }, ajaxUtil_1.default.getResponseFn(res));
183
- });
184
- exports.default = router;
@@ -1,101 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = __importDefault(require("express"));
7
- const multer_1 = __importDefault(require("multer"));
8
- const ajaxUtil_1 = __importDefault(require("../util/ajaxUtil"));
9
- const booleanCoerce_1 = __importDefault(require("../middleware/booleanCoerce"));
10
- const client_1 = __importDefault(require("../models/client"));
11
- const router = express_1.default.Router();
12
- const upload = multer_1.default({
13
- dest: 'uploads/',
14
- limits: { fileSize: 10000000 },
15
- storage: multer_1.default.memoryStorage(),
16
- });
17
- router.get('/connection-test', (req, res) => {
18
- req.services.clientGatewayService
19
- .testGateway()
20
- .then(() => {
21
- res.status(200).json({ isConnected: true });
22
- })
23
- .catch(() => {
24
- res.status(500).json({ isConnected: false });
25
- });
26
- });
27
- router.post('/connection-test', (req, res) => {
28
- req.services.clientGatewayService
29
- .testGateway(req.body)
30
- .then(() => {
31
- res.status(200).json({ isConnected: true });
32
- })
33
- .catch(() => {
34
- res.status(500).json({ isConnected: false });
35
- });
36
- });
37
- router.post('/add', (req, res) => {
38
- client_1.default.addUrls(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
39
- });
40
- router.post('/add-files', upload.array('torrents'), booleanCoerce_1.default('isBasePath'), (req, res) => {
41
- client_1.default.addFiles(req.user, req.services, req, ajaxUtil_1.default.getResponseFn(res));
42
- });
43
- router.get('/settings', (req, res) => {
44
- client_1.default.getSettings(req.user, req.services, req.query, ajaxUtil_1.default.getResponseFn(res));
45
- });
46
- router.patch('/settings', (req, res) => {
47
- client_1.default.setSettings(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
48
- });
49
- router.put('/settings/speed-limits', (req, res) => {
50
- client_1.default.setSpeedLimits(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
51
- });
52
- router.post('/start', (req, res) => {
53
- client_1.default.startTorrent(req.user, req.services, req.body.hashes, ajaxUtil_1.default.getResponseFn(res));
54
- });
55
- router.post('/stop', (req, res) => {
56
- client_1.default.stopTorrent(req.user, req.services, req.body.hashes, ajaxUtil_1.default.getResponseFn(res));
57
- });
58
- router.post('/torrent-details', (req, res) => {
59
- client_1.default.getTorrentDetails(req.user, req.services, req.body.hash, ajaxUtil_1.default.getResponseFn(res));
60
- });
61
- router.patch('/torrents/:hash/priority', (req, res) => {
62
- client_1.default.setPriority(req.user, req.services, req.params.hash, req.body, ajaxUtil_1.default.getResponseFn(res));
63
- });
64
- router.patch('/torrents/:hash/file-priority', (req, res) => {
65
- client_1.default.setFilePriority(req.user, req.services, req.params.hash, req.body, ajaxUtil_1.default.getResponseFn(res));
66
- });
67
- router.post('/torrents/check-hash', (req, res) => {
68
- client_1.default.checkHash(req.user, req.services, req.body.hash, ajaxUtil_1.default.getResponseFn(res));
69
- });
70
- router.post('/torrents/move', (req, res) => {
71
- client_1.default.moveTorrents(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
72
- });
73
- router.post('/torrents/delete', (req, res) => {
74
- const { deleteData, hash: hashes } = req.body;
75
- const callback = ajaxUtil_1.default.getResponseFn(res);
76
- req.services.clientGatewayService
77
- .removeTorrents({ hashes, deleteData })
78
- .then(callback)
79
- .catch((err) => {
80
- callback(null, err);
81
- });
82
- });
83
- router.patch('/torrents/taxonomy', (req, res) => {
84
- client_1.default.setTaxonomy(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
85
- });
86
- router.patch('/torrents/tracker', (req, res) => {
87
- client_1.default.setTracker(req.user, req.services, req.body, ajaxUtil_1.default.getResponseFn(res));
88
- });
89
- router.get('/methods.json', (req, res) => {
90
- const { type } = req.query;
91
- const { args } = req.query;
92
- let method = 'system.listMethods';
93
- if (type === 'help') {
94
- method = 'system.methodHelp';
95
- }
96
- else if (type === 'signature') {
97
- method = 'system.methodSignature';
98
- }
99
- client_1.default.listMethods(req.user, req.services, method, args, ajaxUtil_1.default.getResponseFn(res));
100
- });
101
- exports.default = router;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const events_1 = __importDefault(require("events"));
7
- class BaseService extends events_1.default {
8
- constructor(user, services, ...eventEmitterConfig) {
9
- super(...eventEmitterConfig);
10
- if (!user || !user._id)
11
- throw new Error('Missing user ID');
12
- this.user = user;
13
- this.services = services;
14
- }
15
- destroy() {
16
- delete this.services;
17
- delete this.user;
18
- }
19
- updateUser(user, services) {
20
- this.user = user;
21
- this.services = services;
22
- }
23
- }
24
- exports.default = BaseService;
@@ -1,220 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const path_1 = __importDefault(require("path"));
7
- const fs_1 = __importDefault(require("fs"));
8
- const BaseService_1 = __importDefault(require("./BaseService"));
9
- const clientGatewayServiceEvents_1 = __importDefault(require("../constants/clientGatewayServiceEvents"));
10
- const fileListPropMap_1 = __importDefault(require("../constants/fileListPropMap"));
11
- const methodCallUtil_1 = __importDefault(require("../util/methodCallUtil"));
12
- const scgiUtil_1 = __importDefault(require("../util/scgiUtil"));
13
- const fileListMethodCallConfig = methodCallUtil_1.default.getMethodCallConfigFromPropMap(fileListPropMap_1.default, ['pathComponents']);
14
- class ClientGatewayService extends BaseService_1.default {
15
- constructor(...serviceConfig) {
16
- super(...serviceConfig);
17
- this.hasError = null;
18
- this.torrentListReducers = [];
19
- this.processClientRequestError = this.processClientRequestError.bind(this);
20
- this.processClientRequestSuccess = this.processClientRequestSuccess.bind(this);
21
- }
22
- /**
23
- * Adds a reducer to be applied when processing the torrent list.
24
- *
25
- * @param {Object} reducer - The reducer object
26
- * @param {string} reducer.key - The key of the reducer, to be applied to the
27
- * torrent list object.
28
- * @param {function} reducer.reduce - The actual reducer. This will recevie
29
- * the entire processed torrent list response and it should return it own
30
- * processed value, to be assigned to the provided key.
31
- */
32
- addTorrentListReducer(reducer = {}) {
33
- if (typeof reducer.key !== 'string') {
34
- throw new Error('reducer.key must be a string.');
35
- }
36
- if (typeof reducer.reduce !== 'function') {
37
- throw new Error('reducer.reduce must be a function.');
38
- }
39
- this.torrentListReducers.push(reducer);
40
- }
41
- removeTorrents(options = { hashes: [], deleteData: false }) {
42
- const methodCalls = options.hashes.reduce((accumulator, hash, index) => {
43
- let eraseFileMethodCallIndex = index;
44
- // If we're deleting files, we grab each torrents' file list before we
45
- // remove them.
46
- if (options.deleteData) {
47
- // We offset the indices of these method calls so that we know exactly
48
- // where to retrieve the responses in the future.
49
- const directoryBaseMethodCallIndex = index + options.hashes.length;
50
- // We also need to ensure that the erase method call occurs after
51
- // our request for information.
52
- eraseFileMethodCallIndex = index + options.hashes.length * 2;
53
- accumulator[index] = {
54
- methodName: 'f.multicall',
55
- params: [hash, ''].concat(fileListMethodCallConfig.methodCalls),
56
- };
57
- accumulator[directoryBaseMethodCallIndex] = {
58
- methodName: 'd.directory_base',
59
- params: [hash],
60
- };
61
- }
62
- accumulator[eraseFileMethodCallIndex] = {
63
- methodName: 'd.erase',
64
- params: [hash],
65
- };
66
- return accumulator;
67
- }, []);
68
- return this.services.clientRequestManager
69
- .methodCall('system.multicall', [methodCalls])
70
- .then((response) => {
71
- if (options.deleteData) {
72
- const torrentCount = options.hashes.length;
73
- const filesToDelete = options.hashes.reduce((accumulator, hash, hashIndex) => {
74
- const fileList = response[hashIndex][0];
75
- const directoryBase = response[hashIndex + torrentCount][0];
76
- const torrentFilesToDelete = fileList.reduce((fileListAccumulator, file) => {
77
- // We only look at the first path component returned because
78
- // if it's a directory within the torrent, then we'll remove
79
- // the entire directory.
80
- const filePath = path_1.default.join(directoryBase, file[0][0]);
81
- // filePath might be a directory, so it may have already been
82
- // added. If not, we add it.
83
- if (!fileListAccumulator.includes(filePath)) {
84
- fileListAccumulator.push(filePath);
85
- }
86
- return fileListAccumulator;
87
- }, []);
88
- return accumulator.concat(torrentFilesToDelete);
89
- }, []);
90
- filesToDelete.forEach((file) => {
91
- try {
92
- if (fs_1.default.lstatSync(file).isDirectory()) {
93
- fs_1.default.rmdirSync(file, { recursive: true });
94
- }
95
- else {
96
- fs_1.default.unlinkSync(file);
97
- }
98
- }
99
- catch (error) {
100
- console.error(`Error deleting file: ${file}\n${error}`);
101
- }
102
- });
103
- }
104
- this.emit(clientGatewayServiceEvents_1.default.TORRENTS_REMOVED);
105
- return response;
106
- })
107
- .catch(this.processClientError);
108
- }
109
- /**
110
- * Sends a multicall request to rTorrent with the requested method calls.
111
- *
112
- * @param {Object} options - An object of options...
113
- * @param {Array} options.methodCalls - An array of strings representing
114
- * method calls, which the client uses to retrieve details.
115
- * @param {Array} options.propLabels - An array of strings that are used as
116
- * keys for the transformed torrent details.
117
- * @param {Array} options.valueTransformations - An array of functions that
118
- * will be called with the values as returned by the client. These return
119
- * values will be assigned to the key from the propLabels array.
120
- * @return {Promise} - Resolves with the processed client response or rejects
121
- * with the processed client error.
122
- */
123
- fetchTorrentList(options) {
124
- return this.services.clientRequestManager
125
- .methodCall('d.multicall2', ['', 'main'].concat(options.methodCalls))
126
- .then(this.processClientRequestSuccess)
127
- .then((torrents) => this.processTorrentListResponse(torrents, options))
128
- .catch(this.processClientRequestError);
129
- }
130
- fetchTransferSummary(options) {
131
- const methodCalls = options.methodCalls.map((methodName) => ({ methodName, params: [] }));
132
- return this.services.clientRequestManager
133
- .methodCall('system.multicall', [methodCalls])
134
- .then(this.processClientRequestSuccess)
135
- .then((transferRate) => this.processTransferRateResponse(transferRate, options))
136
- .catch(this.processClientRequestError);
137
- }
138
- processClientRequestSuccess(response) {
139
- if (this.hasError == null || this.hasError === true) {
140
- this.hasError = false;
141
- this.emit(clientGatewayServiceEvents_1.default.CLIENT_CONNECTION_STATE_CHANGE);
142
- }
143
- return response;
144
- }
145
- processClientRequestError(error) {
146
- if (!this.hasError) {
147
- this.hasError = true;
148
- this.emit(clientGatewayServiceEvents_1.default.CLIENT_CONNECTION_STATE_CHANGE);
149
- }
150
- throw error;
151
- }
152
- /**
153
- * After rTorrent responds with the requested torrent details, we construct
154
- * an object with hashes as keys and processed details as values.
155
- *
156
- * @param {Array} response - The array of all torrents and their details.
157
- * @param {Object} options - An object of options that instruct us how to
158
- * process the client's response.
159
- * @param {Array} options.propLabels - An array of strings that map to the
160
- * method call. These are the keys of the torrent details.
161
- * @param {Array} options.valueTransformations - An array of functions that
162
- * transform the detail from the client's response.
163
- * @return {Object} - An object that represents all torrents with hashes as
164
- * keys, each value being an object of detail labels and values.
165
- */
166
- processTorrentListResponse(torrentList, options) {
167
- this.emit(clientGatewayServiceEvents_1.default.PROCESS_TORRENT_LIST_START);
168
- // We map the array of details to objects with sensibly named keys. We want
169
- // to return an object with torrent hashes as keys and an object of torrent
170
- // details as values.
171
- const processedTorrentList = torrentList.reduce((listAccumulator, torrentDetailValues) => {
172
- // Transform the array of torrent detail values to an object with
173
- // sensibly named keys.
174
- const processedTorrentDetailValues = torrentDetailValues.reduce((valueAccumulator, value, valueIndex) => {
175
- const key = options.propLabels[valueIndex];
176
- const transformValue = options.valueTransformations[valueIndex];
177
- valueAccumulator[key] = transformValue(value);
178
- return valueAccumulator;
179
- }, {});
180
- // Assign values from external reducers to the torrent list object.
181
- this.torrentListReducers.forEach((reducer) => {
182
- const { key, reduce } = reducer;
183
- processedTorrentDetailValues[key] = reduce(processedTorrentDetailValues);
184
- });
185
- listAccumulator.torrents[processedTorrentDetailValues.hash] = processedTorrentDetailValues;
186
- this.emit(clientGatewayServiceEvents_1.default.PROCESS_TORRENT, processedTorrentDetailValues);
187
- return listAccumulator;
188
- }, { torrents: {} });
189
- // Provide the number of torrents.
190
- processedTorrentList.length = torrentList.length;
191
- // Provide a unique ID for this specific torrent list.
192
- processedTorrentList.id = Date.now();
193
- this.emit(clientGatewayServiceEvents_1.default.PROCESS_TORRENT_LIST_END, processedTorrentList);
194
- return processedTorrentList;
195
- }
196
- processTransferRateResponse(transferRate = [], options) {
197
- this.emit(clientGatewayServiceEvents_1.default.PROCESS_TRANSFER_RATE_START);
198
- return transferRate.reduce((accumulator, value, index) => {
199
- const key = options.propLabels[index];
200
- const transformValue = options.valueTransformations[index];
201
- accumulator[key] = transformValue(value);
202
- return accumulator;
203
- }, {});
204
- }
205
- testGateway(clientSettings) {
206
- if (!clientSettings) {
207
- return this.services.clientRequestManager
208
- .methodCall('system.methodExist', ['system.multicall'])
209
- .then(this.processClientRequestSuccess)
210
- .catch(this.processClientRequestError);
211
- }
212
- return scgiUtil_1.default.methodCall({
213
- socket: clientSettings.socket,
214
- socketPath: clientSettings.socketPath,
215
- port: clientSettings.port,
216
- host: clientSettings.host,
217
- }, 'system.methodExist', ['system.multicall']);
218
- }
219
- }
220
- exports.default = ClientGatewayService;
@@ -1,76 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const BaseService_1 = __importDefault(require("./BaseService"));
7
- const scgiUtil_1 = __importDefault(require("../util/scgiUtil"));
8
- class ClientRequestManager extends BaseService_1.default {
9
- constructor(...serviceConfig) {
10
- super(...serviceConfig);
11
- this.isRequestPending = false;
12
- this.lastResponseTimestamp = 0;
13
- this.pendingRequests = [];
14
- this.sendDefferedMethodCall = this.sendDefferedMethodCall.bind(this);
15
- this.sendMethodCall = this.sendMethodCall.bind(this);
16
- this.methodCall = this.methodCall.bind(this);
17
- }
18
- handleRequestEnd() {
19
- this.isRequestPending = false;
20
- // We avoid initiating any deffered requests until at least 250ms have
21
- // since the previous response.
22
- const currentTimestamp = Date.now();
23
- const timeSinceLastResponse = currentTimestamp - this.lastResponseTimestamp;
24
- if (timeSinceLastResponse <= 250) {
25
- const delay = 250 - timeSinceLastResponse;
26
- setTimeout(this.sendDefferedMethodCall, delay);
27
- this.lastResponseTimestamp = currentTimestamp + delay;
28
- }
29
- else {
30
- this.sendDefferedMethodCall();
31
- this.lastResponseTimestamp = currentTimestamp;
32
- }
33
- }
34
- sendDefferedMethodCall() {
35
- if (this.pendingRequests.length > 0) {
36
- this.isRequestPending = true;
37
- const nextRequest = this.pendingRequests.shift();
38
- this.sendMethodCall(nextRequest.methodName, nextRequest.parameters)
39
- .then(nextRequest.resolve)
40
- .catch(nextRequest.reject);
41
- }
42
- }
43
- sendMethodCall(methodName, parameters) {
44
- const connectionMethod = {
45
- host: this.user.host,
46
- port: this.user.port,
47
- socketPath: this.user.socketPath,
48
- };
49
- return scgiUtil_1.default
50
- .methodCall(connectionMethod, methodName, parameters)
51
- .then((response) => {
52
- this.handleRequestEnd();
53
- return response;
54
- })
55
- .catch((error) => {
56
- this.handleRequestEnd();
57
- throw error;
58
- });
59
- }
60
- methodCall(methodName, parameters) {
61
- // We only allow one request at a time.
62
- if (this.isRequestPending) {
63
- return new Promise((resolve, reject) => {
64
- this.pendingRequests.push({
65
- methodName,
66
- parameters,
67
- resolve,
68
- reject,
69
- });
70
- });
71
- }
72
- this.isRequestPending = true;
73
- return this.sendMethodCall(methodName, parameters);
74
- }
75
- }
76
- exports.default = ClientRequestManager;