From 442879e80a8de8d97c47f5b80f6844b0dad0028f Mon Sep 17 00:00:00 2001 From: Thesourtimes Date: Sat, 18 Dec 2021 19:17:04 +0300 Subject: [PATCH] General work on API --- api/.env.example | 6 +++++- api/package-lock.json | Bin 658149 -> 810634 bytes api/package.json | 1 + api/scripts/droptables.sql | 1 + api/src/Server.ts | 27 +++++++++----------------- api/src/middlewares/Authentication.ts | 16 ++++++++------- api/src/routes/downloads.ts | 19 ++++++++++++++++++ api/src/routes/updates.ts | 20 +++++++++++++++++++ util/src/entities/Config.ts | 10 +++++++++- util/src/entities/clientRelase.ts | 26 +++++++++++++++++++++++++ util/src/entities/index.ts | 1 + 11 files changed, 100 insertions(+), 27 deletions(-) create mode 100644 api/src/routes/downloads.ts create mode 100644 api/src/routes/updates.ts create mode 100644 util/src/entities/clientRelase.ts diff --git a/api/.env.example b/api/.env.example index 0573c605..5974f628 100644 --- a/api/.env.example +++ b/api/.env.example @@ -1,4 +1,8 @@ MONGO_URL=mongodb://localhost/fosscord PORT=3001 PRODUCTION=TRUE -THREADS=# automatically use all available cores, only available if production = true \ No newline at end of file +THREADS=# automatically use all available cores, only available if production = true +#LOG_REQUESTS= +# only log 200 and 204: LOG_REQUESTS=200 204 +# log everything except 200 and 204: LOG_REQUESTS=-200 204 +# log all requests: LOG_REQUESTS=- \ No newline at end of file diff --git a/api/package-lock.json b/api/package-lock.json index a4ad6b2b9ebfe710fb022d77451a433fc2413790..aa0c07c5ac7e42777567eeb0b1192af1eb83d085 100644 GIT binary patch delta 33735 zcmc(|2UJzZ_CLNZx14jRSGaT(u%LqFVy}q3Ac9>K5PMf*jTK^#6+Mw{7h_^C7|XRw zj7jX07h^AIG{y=k8jbD$IWuPf&3o_r{r}d#ytVR{%$c%h?>)QC-gECQsW9hoWcDH> z?Q15x%B7R-RjO5qtWMF*q-ML$826Y}qp8HSEy}DdiUI#Q;Xfn(GdZ>><~e7mvZqt1 zp*n?nn5&c=-fQ@XJ|l*X7&)qH<*G%0RAw_$)_GG%XZ!H#!#Xx@-!?wAW!o-w<2rQf zR5PM!)n+w@jq5kAcJtojM%Aj@>f;*CtBo2kp<4IGH6yB5YhTCSr0(dpb>e%st=+BF z@D9xeHU79&)zsl5JGZIZt49AJo!WJx->#SgX_c4L*d@7UH#*?!behr|7~N(qykvGP zykz;8JNUBIlk#c#8PLsp=hv>TaAWc_7X~YAIM2Bx#!YQi{*7C58 zAp2Fh+~OElI#}HpNeOwDR_qgfQp3ogs?DdY!Z2)({*DaFu2PZ|Iowl;<}qEGKx;%M7bqm447_=ix{!^fK%H8Q@T5m`z# z3aM*!p)O&HFTJ;YcMbL^zDG-w_x1=Vtn@fQvZ>LbrPTUygEsf_oTCk;hY`LRDjoy%^N$h_Zq7_OX~h zIkedPYDhB=suIf?%Sr`#V2+$87EA`_p#JTOVO%Fv_otR=9MDx|boAKEZsO>Dav^c>S`a<9@WayfHXOfw(VAMUUBYKdv$%iarFNHGY07q4qVrc2 zcS>^t0>gS6*Kyosc}Wt*^)X(c=+~AOlvm#HUoZDF3CUJwJ@c25|hINP&)W51J$HMr~Mx%{;w6!}ec_NLWw!N{Rn6c=kNli^oO{ct51{@hDX**wG-N#~% z_-~x4pc+sy+=Nx;UBu8Qe_0@!BTCWG3A|Sk?uJtGTT4jhCBS_CqS2YIePd?K8%m=l zp)X|Ca(paFu~sfwsQDD$9737|bQG8+R|5xOW;*{;o5oIQCDrIfrzOc* zZ4+vvR#Q0))hT5m&iZOMa7fQ-#!cFGi??M@=P0N_t7ZVOI7QOw*JUOq$X29JsnloK z-1S-ioDUT8qf*1LY)CIjQS%ylQ-e=Mw?G%EBc;tTPSaMbK?SZ-c>?8ZbaXBb2_~}6fUrL_pk!EZ8Ur$dN+-OHb&=IVl zPHcfGN=wP~aG7xz|JO!OsXCwH&`{}+>H;| zyGlcZHl6(%h?QcK%2LD{4Pjc_%q-)ULiJZnYdWAcTj<;~WSyA7|2jnRec7lB(aT>L z=kjUte4)luPea>IUT++(O<2Tgp|syms;U8_uX(E`^j)ey2&Wk)bZL{=5sZOs%Ge_M zT@R3|@Gh0Ni7t@4G1}%rY3L2;;ceR?CNP1e+?7>^3Qk zT8ByvHN7&e5C^3x?*J4IgW2tt(T!#uIiD`z_##ZE#wSXgl?_afh~$C*_xw#!|sK&D{A01Yjc)@}Tmb92Xes|DAC&U+6vQ zY@#>6Tf7MZyadIU2N@ZzhM&;a$h?hZ-<21{dUaB)-QYHOVMPUe0Nr)Uo<3vTuEC=V zZ1;1`KY^AiCx@l$xl4D{Zvl7Y%X^&nfqzZquWr zIvmAmzZ!ee$;}EwqHE>@7>`e*G|NXbR#rd2C??ur5SONQ4~?}nHEyK?jldtwv>M#H zs7KpkCMQ_NPUqWzBQYwHw!U1O@!knI+QvYx^wdevWYQ{Tp})DRF-Xk*k3exgdv%}-y*}Rj+YhM+)8qzyf8(g?OS9kooNjUVU$&k z_bRJ(i^yyv)#MO)*ce0&7RR{I_%_m<_xn*utmF|2q2?G`6GEGzjz2OEubQoN|36YLIVOaeb_4&G99nEN zvz|+K&}XKU*kXir)6DY{bo8mkOb5pRy(uwb{#9j)<_Gk4K}!jidbsvSLrRG=TF4rU zBg<^+4IRZAu&Ijxs8DD>o2fx(td`LZmLJ>0fv}=(|S@WXW zoy7`syA<1nt7a;PahkwPW^+bzvb_hVAAD68iti#;7#>lyMQ!ykI@5)-j*Z#Nj&5MD z`Q707WOS9{IKyg2Guo@t(fzWS+`GXl(-@hUnT!t$8Rv1k_}CUXh;#DW-f}gv&w#PJ ztE}Rs&WmLHtF!sO1TZ1vYt3jbV*efe?}L){%CGdcYRrAYwaBa=+?M`88r7-o!Ovh zG|b~tbY+_4trNrCArwp$2uCVLG7XPlR+B3w3VlDs+ zg~v`)5WK4kx`yJexcW|J?7yng^YVuK1dmfc(Z(Z37UZh#|XeaSt zL-La%Y)XZ?LZ-9<(jbn-%s9?YnFFQ9yk$guVT(82S|&TI(e2GNd7!}NN9~iT{6s07 zat2Bh_>lb_k{t;3IO&3^OD8^qn%UojQU-HOdaJEECusxil;?(2Ng{rSRTVIY4n^4|psT%K@*jJw=YK*j;H$CacP#>{(tkmDg zn~o1=PHhA&7%wg3P4PqZfdIBNmJcP5EpjO}ZIn!hCP>41r=a1i({KE*A4lj!KYCma z*0A93m^?{(sAKJ?k?31NwinHFV2boLADKOxJJo8{y=4eG>kj4(k|=@aPOr|Iw~87fD7T-2`PrQZ0WCO0*A zyh8Io5gcHiQ0yC>|3pla%iBZM?IvdmnkocRY)O;8v%yoPQ99(4I4Z#UzEsdhG11xS zl8>4?*+SU0GmQv^6x|VQf;~1(TFJ)H<6z7KUA}<-`6Pt@X@75ye*B|*Y5uVR4VfXe zTt%EGkMXxX@DbTH2yEd8_|%|xsb*9 z;H=uGnQ6i+j65wyQf@iE#d<}3)h9s0>zPs+zIe~+`rKIjn%3m4=FPx)s313`h0`$g z@Y&L64twSBe@?b=l#=Og@}Rb#3R;$&&3B{nPbM{MjzZD%4eY487shC8>hI{t_$vQX zX)s^GqY7WaPH1z(NGn~N388ji4h$TRNRydMkBX6|1iC#(YQ{(9M}7zwk2=wG%v-3#FQZA=Bpxq1$dD z8{L%d%#((4L6G5M*45+3^QE19k)Ido>mI!UHQjcBz|Drmdi&f3LOtE6BVe3d0eJj% zfgnut&vZcRER;s@X_J=d!;gGxkm>9~9V)sUCD0a>A+%u?Vtr%Co*+)&TS}yFGo;#T z)>4j0^}y0ZdY7S#97=1(K?$H%iv+sDmnYNxE-)X~E`p3=7<5{ZOclx@Vw|@~O65&e zSF*(dsLq#WD~($$_Sw@QO0x}k)366hOfLUZD#Y*+C5TW z=2%Frw4*SUnYDN&0i#+Tgm<-JD?FRz?j|=!?or9bKs)LI0hqv_tUF9N0{38Y6y$&k z+Bmi6E|6}PT$vUa!G9?$;l{QPQ-Y{b5|EX(5`LaWPI{Gu=`XF6CaTuuI%aMpVtFA!HgwpPfj_yN2>O#T5TKYI8D1ar?B z5ah#P`Rw}~G6V~_s0)ue7ithcy85})oiDd-xV{`^e*q5&Hgl*WW1VzdzpWZL5}&(X z$8nsvUiyrzW&~frpngSaqly0z5sy8iXvdXPSFn#rA}?F2#?4VvE2KR({6+tajpI;Mk;3ZVX9N%~bq_$>hF zuQa2}UrERLs%K}R8xvGxB%ID`yL52Wd3W?FEAEEXo3oY+FfTeY8z-*MZmER&_N_!7 zpMo51oZ&}>d}=jG42|E zzbwbVg*hf~+OP)!^QWh9fx`Lh*93a8M}XJp0U|8>AZgm{<%ij(Mm*G;7VH(0GW3z& zbY1UdRogt)4|(7-M1eCp19XOd$`I&h_eMdBV2Wipbgf6$#rVqBv+RQsV&rR|uN$3T z_tx)%=;%`DY}ReuKJ1gheXf8t={6btrlU2^0V^zf5+p##ekspX3DTOf%PIltsy`A5 z{O3i@S60u)so-@pA; zA~iWIqDBQ@h>&VMJsT1VbBMFe_|49q|&&cYmudkJBpAsw2|A|Ic+&C|&F<2he#VEY4G_px$m> zMT8QJ?M1JRhSEmp+RU2RQJe`K&V8->4wPf zT|4Y6Q{gKXzlsQ{F4f5u}FR`PW=lqS=0Xwm44V$8ThrbKN|WKXyFQLW}OV&+q2 zlTf|B6zgJ0q}1b5T@K4HhXG6ZWk`C+Juc1VZS}tqJn>~I#e=%nezID&`#K!b{>fQ_7VF7m7t_Y>^9j;EkZ1WzFD6<{dMeckK;10wIIw6qPKYF^ak zqA6I`4L|2hMfM@b0vyEXUv=3$Fi?QxcA85UE4g0=NDOZ~w!timuZU~xL8oztlT{IT zV~qIrauEYfS!eJg$4-QIa%GuEZRzn9flaqFT=gMzcmr)rvurp6Zo3|g(9z%Xpy=^u zJx=X~A%KQaTRIDjFoWacP~f%VS0D>_p4TCkfE&Pinj zZ+cPHvOs3~IU&{dmKD3cc23t8WdB8gTLipGEwCR2;wsY`Bo4hRe1(UeBnF{{H*qn)7{|s(%%)ZCu=UQ9*Zb7=^^x} zS1y>cWC-#mdPbUQSgsHn3E=|ZtX#oO%_Gpp@Y$%G5>C;Np`a@MAZ2iz#8(z0a(~d> zAG(?^w&?vY-N~XO1){C%zn~~I$x91<1DlQem##F)C6X@`PLvD+XGI!Z9r^!~sxw2x zN)!GRC!+2J%*qf~rUo|H_kuVKZ)#u$5&80`jVX|p*)>7`w-;ayvx7coEbJ#ndY6lW zBq=Wdn?_eh%th%dn;H@`Z-|XWn}r-} zdjqC2o9|e2%*R+h<2BM}?3bWQlytcPtazq;tvRod}W{-gyW7;jt-CQJ7=%dAm4UNdtZuB*$ zka7Rh7@V8lUnx9LN!u+J9oVg3DgCMbZGn{+v48}Jd12vLFS=2}T$*0q7R=Yq6PpK@ zd($#IPEOukCyA2o2oCu%o=?!2Fmo{7cmi?GjOvx`;W)m#BW~Q%W&(mQ+sn9n+yIT4 z9xwaTsyH}W+9d-$|5-PPX;nwe$4D1-SBS&m-exWi9TV?rm;2eJE!_8|oW6!&&D?6L zu`m*$LXFT%8*mwtvmg0Wn7W0AaBrH`)sVzz4Y?0DH1RhlcZ&8mo4Epv-h;N3ZU_xA z+)e5RjGy>LD7K@48iQ&224i^`gEj_=!IcjYap6D324KNK?|tQbL53YnyyBMopt z^QGQQoc)Ij-w0}3AQXR-R8FuIx>leEg(>4Bfj#e$2A}`Mbn|`}#Hc(*-x%#nGr7^; z0L3eFEF>)BsReb!?uz0d<^O;-3{Df+jv5Et4fz9VipdDWcua?r*_H^8AU|4`bA)fAZsLrACtk<)H-=In7>80%Og8hSRlhGM6a6 zv}rQh_CMn+8$?M{088FCxE5rvELg_rh%DKuN-4^&1vNVOxnSs|bb+&D&mqVdUo34= zBwp8EM!u~5FHUGHEpMftX1dq~5v79FP(>F$HhWU%E|9<(r**sN>NJ7QYkxr&W(VqF zF&ZCZPRM)#N0fnfWQOQA@P*LJoH|H*n57{{v+`cQ5NfIQY>Z_rSMQ}1 zqXF(mm*OD&X1~Ot7A~=szWWr+xA!F%h*qjU2U9W4Rpm88#u*C@E?Q9Bt0>@2N8<$q ztV^~943Rw-$bP*7iqT%#V4{_O3+;A$F2G<30=SfMp__lhm128q*$K1Engj+v@=Dsu z+wLzwXGBXc{C6(z`3gGe={PKrcMFzx!#OY`&+QZ|e!CcxFd0$vtuW!7KSLWVgsSw; z39|XwTS#sO#js5Nf!$=`>gSz)vqX)MSPJ*?|f7^7})2 z?=Gz*zuKY)pQ9(h38#1mB2LT&uP@7A@b&i&0T!_12$B>zfw$fJ@;#V#jD_;kF7l{n zX}L7HJ0Xf4;wk&9vB|EgJz1vQfv}rbhXeQ7C4_~%YeO;c!!ljv`IMnuwZyx~{F)h| zuMc|s$X6deN>De?8*Apf%DP%OwzU{oAvAQGAxOLRbF6cdKhm+Xcn7+G*pYND!H8tz zY=c6$d{PKF40C+yA=lEwfe*hzM@FL)o^oddf(;(j+7r8DMCr4ee-$WGU;^y$lvnew z?tA$ncI|H0(=pFWZm2KcdLOM3HZBSm)fN%g#n|by6mQ4#aCxzgruQz?rjWfV%tHo3g-rs4)T%Nw;H{MS zvzQufE|jwbmgfC(NOB3;XQJ0t5xZkUrMp;-NoRDk(9=J_$Z!_mAKJm!49Ev}F%y&f zKmDnM(K)T(c00$Ul~&#>wvLHBBVkFhncpiX>By%_yDz4iR|`k*a->|B>k*G_=3pvO zO=eMg8y(n&4QWd{dRLPt8|d#AfS0*lA&;PW?^K7xa@!5V7->7WZmZ~&K+Gbu*Wg&R z(zlPX5^TL+I52Kcu}!uI7JvKnsi6!_tSRgMc$0kb)wz~DoR28@N(X@eD$mTP++70C zf7L=l1lwlN?_z9JZTS^%tG!qBi?1U{J^fDr#O#nYb>uO;-@<1Y%i8MKl{@gZ?a$H1 zv~jz72-R$@E0@U(_+neyvG^;mxse$J1DUo*6?73$$D)6&CV zKqF&V&0?Jo9TZb7tcPl!;6pI)VS9Peke9qOBIWfU(4yOj51S705hdt=svvi>J}Ahh z@A)@Il&df6>34GvWA}{t0}i9#g8DLZD`4Zl!q#y86;7|}%Wbr=L3AMp7IE_ia(!+0 zR+|4ctQ|IXeFMna)H*y`Wu*qkz##bza8`>V`8ST4S=18VB#h6Tcff}rhH`HX*hD8V)zm22llnv<_k#g@%1KKSr~Pd%kSqS^af$T5Y|1^2b>@n`dvkYkMKFMPoWgIhx0AyJTD<e1)E^*|MCv9?hie>BMxbu>IiaJJBpJy+OF?}MsyV7dR-*in6CUb7G`l= zHE`;ay}&PGsk$4MUQG=9q?5d!!*abk+Qh{Isu*kFBu?6ngEqRe;MvD_#X)Pf4rP`< zc9vHZlXER=L0S#h*n^$QH}?h1hq?$;I=eOpt%t_5ew1AYBbs#Og33yNKjuCpu0fud z5zXx;m!SP!A@wnzm6kmf9%hSYh^X4S!GmH8ovepRnK16xO=c+uHnKNB8-jn%H^ zJ$lIF_1Ykje}}`&(gRhK$2W&{j-b ztZrQ--IJOjMJv7yMxPmgOQX2Au#8!JW5in_7rQ0P-|}<9Qkz-sNqSdgMQTS=)v}sJ zfX<|4HBX@Oy@14`B!#qPxT|j03${2r%PielOk&Zh0^>7}itrzb0!wH1mK*b~A!dXa zS=X+;VeUe>6=p#rAlnDrChlpyP&F7#1Nz8Od}NPifS!#!*av0{i*{+bHPo{UQ0CTG zZp8bsqusKvJn%y~xTCM!O6vl(o&e@R=1dT|_mdNgu0(0J3u=7__k$uS+G~_6Zi`p< zgIs0E(Xy`@6v)2r&R1ljjI}|4_2oor;EsJV9$Fe=_M(^lAzX`W2>+e{*>eCFt|&n3 zDOjcV0CBdqriiu;18`u|dI)=~PYK*GUl<^i(UV@B(Qyem5DpgOkeR&&hcLU-sSmDS zXrTND!W)98ZuJFE%^w75ETHnGMg5?24h)i6S^=Wf{rN2VO@ZrR9NqKXK~~00T?Sx+ zT7$(oQU;18(+7jD42;Y{qHWj^7zjB%gd&?X7z;Uuh=sl!f`078dk>ZM$o=`DqHXC= zIlfTW+vtyB7`t;QRQS<>5NVcSK&&`hxLX?z#Imoq1|kIBK>J#-N7xP%M~Ja+2SRp^ z9VX;%-&6tVmSMvCo&1q#gI2LQB8JObnJHl<>u8{y(e~*GxCCskXGWv9@Y(%oSu2K*lgFk}qH83g_`V2z2b z!YnuH`5UbH0b}KK4%N6ymPC3uR`68949u*lPDjsi@(w4C#R{LIu}}~5I|^ia)}q-H z;Keg>w0#cm!qm4j4IHm2%k$XggfK|xqkTbomQ#0X?mwqmIZ;mIVRt5ugXV*uZchZ1 zRVTqMDPpuswQveMO%k9sSb(Vz1zgAXzj`75EI(PE&j0*21Aj7x8NCbMhcybpNOp*} zFTw}L`5Vm$Ar$-yt_hxoV`BeZE^WkP5iARY^6P^NiBrHJd5eTSzoj8?_1P3?7N!7Z zECKOyrU?J=WfTa&CiYJgRtKwYLlt&Y4%FRf!BXOGti0oCnmnZF>c*euEyt`ZqTjMU zLR-j&^`Qa}uB&{hRdYTANo^^DMV0BGPLU+L zx)$smKV5iQE7ytD)=Za|@tKq3#LV$C#Od*g7i}3cV2G#Lxd)76r4(J{ubpEK5~U7S z%I}QW45Ouc7Yt@w63I4x)G!bcgd9(kLXBq1dXZtTjRF{!H;}#!_garPLX@#vezeu* zT>M{BChIOD2AN$rIr%(b_1@^Q$I484AnT>G~0@mm~C@ki)qSI%v(d=7<<%T5Uql!3UgYu>*uTSEP%XZ?&_6r0w%=ux4c;7NaUuIL69*we*+b}^~JXa7xDH7gDIP@8g?DmCXgTcf31}hS}c+vH7a4^qX zfTrZbaLlS?z&>Ft{q!&(Wx`;31~-On@J7+bDD@yip2qw2$`LzCUxZXiHg@^fqOH+l z`O*K#Ctaw)XTnL^K2m^(uww}A`V1ilHfPoEF())vI5k)z>uC`S$B6C1Sx(UUSt)g_ zMVH^PnZojpIfb!oF9$NkA#y$~V0@kl&5g0%6nF;sXZ@0hi%cv1d`4)|%_Oww^0Q)W z0b#5Vx4x8p4hK4Vsfg5dn*{inHSU}1WTSmc<&k_ddAZtVmdUz9_U;GmPrV4q+kq;j zJ-T~1;Ud1U@a%yVpdgc>{VzeB++2ZZ58JT+Wx<^++`;l?x~vq==@acMbIX=SIk{2J zO3nvXikSyIG1w4tvr*70A#lfE#gYsOV^;|)Pg;PDu(pG%MEGR&b@XF`MX*C7QGw8D@`H3*pl4mOj=Iy++0pJHkr#r<=cEbEDV7Ib%A~ zdpTxcHtTn5wJ?rm_iMTQtO@anFq-f=j=eC(^`yxipJO35zRqJT1Sg>sy{ZTqci=I2 zJZK$I_d%xds?YE|0ULpG-v24<^80o2cf9j=SpvM#2V_6T!7pUIHo=HA<#Xu5r++HG zbn{EW+XvU7H^W$b1zB>0ua`^fWL}kKNp=8C#ZY)p9YDihfSFk2cIZZMtq^U#wDcuD ze6|tJm*6}vYPJn7!8aR)8+>ycmilX>yo3|t$ab-E)+V5_$j!9BapFge9esgo+CRR^@e=<7B~ZtOb^hDT*l4DknTs;klJt z(r|2yT5iQwIbR!LrP(I@30tXo=62ac*KgtygaQ%9P2C`p3B%1;hvl=M*(ML-d#YnW z8`B0ow#z;ESxA&H6KlJ^U6|-)Wb|Xa8^1%?9Ucb(BN#KBHt*nLZRF=%tREhDDS-l# zirGSJ-q5}x^=1!WyzNn3%3y*BiZ2Pp60#O5cu;5D(BtCSo6??JTzS8MqXO|r?kz!C zM=c(-ai@?E3DkBJ;W9IG4|M3EAH2 zTe1BfyJZK5w2e1l0qWSLT{GS`=mh#P)Xm)^A`JI^(T_3lsXZWt{gm*u+MEK%SKlja z@Zi&8?6kc=Vo|o?t^i{KeX$q&Wd~(mApZPeFIY$$4qaG_+2vpbdVhPcigi!&^s zeTYig-*ff$zz%s|Px;cS}6!#xz_`3>}2?mtJ5TN!ce9+@&AEsds&3u&G@- zvDc!U>G=_mF(k=sqn^Lxjfk8fN^Q!UZLUCT)*H-fsV+X0`dq8k9t1hqb0m&>{l%^d6U&|dUf#spS{O_W@JM=yn_7xL39e(Xg&Xk!ur;LU zXQ=UibP}4Leb{Bf2fS8cbM!nVchNzG>8(Elmv;_VfLG4S5o-2e_5zBh+ImPg%6|wP zq$Dc(#prwekzt_Wu(BIpQO8Eg$L3(Y91_)EJCKeJ#97peNqGCf-LzK2wm(gou9T#p zGzF*K6SoT~Gt(|FiBMJM{qI&Y^{y&7`GyMkjw9GB95Q+qx>~J`PgEkk9|z~+aXVUOiw7~C!yup z%{3Dh@3IiMWlv`P{F7`~SB~b0p_&(A$2X{qOy|P^Vu>9Wk)n{~ZVXV5j_pmhd^`x$ zW*p9^R_*3Yi<%&?>KO-<=b-4W5HZ^aGCm)@0S$0uF(z5=|;4t1JZHnST))~0i z+MbV0UF|tFH8~xx*<3|rE$61mMwT*SLs@r#$Lm++it3WkeoVws^u!**nH8C{k zJ3ujRb!~Dy9CA&rpthT)e`Lc;UB~daSQ~vCW*W)oDEk5w9a`R091Ez%#lu<+O)?Fe zg|w}n6--fVO4WHr5cRx)tGdS(#G;tjs$C9BRPZAfMa}8J#j}d9IpQXcLUvz+bxA6m zs>leFE*nnVlzWm#4ak9#vvpX`-jcO~-omQgNR;WaGg6FW)XYyy@cp4TG8aOP*39!L zX|Yz}6SJ-fG`}sl!J{fio+quylP6QUGuo=z1wz4u7CK@_*&IVx%58{~<+(UOsPNSR zLYs+>Hi4&kB+|s_=tbCY7zNzHRp;qyCPs+LG`D&&bi}A>^NUeL4PFpPRezSNfNnOL zRTFck{w!Bh>n$w8l8(XaKf`D1(H}N`kJ{)KeHYYvP~N6)SggZ?%3T}f+(#yccCV-= zs0%m|56+T2=<;0q)T zKwAy8kj!fO;vt@_=%Zrqq7a(Ls~*ZQ%#PvBfr4-nf$fcs^$zfQC`FMx($so zm7=QmA=_X38+Z>C3l|X-)p{8SvE)`nO*p!_Qo9Un1KaagA62rcRY-?+{5AOdsnI5t z%Ki#~vX)MwZofhS&bbauxi#T4deV+xaka_X+BOxd*dG9+=d;ld^~EERyDEnuN;8Uf zKY;vrihpR26{+J^)S^lcL7|}PHnr-?L8?_%XxKvlUZnv1*=`ks*^>@Ej!okK}N5%9_b+%zW*S5m|g%dSk=oBPxg`%7}yFyYomcqlQ(f<^GX@< za^j{m{ua~er*aJHgrg`p9}d8cPMlXgX;3~auap#{k6N%biT;%jPayXKj)T(G6h_Vk zatI24%@mgkj*8jdn{aLBMK8LVGC0yE?x;sQ3SbWudJkINFWnu3X+nMzp#)a#%Y^rP zanQeb-aZQ@v0`5YQLKd_7BKEg+|g=f5v=T&jfY!m!vk?Jr@y-b9eDM3VAH;P7%fdQ zAwlC0ST+x8!1;Ks)&DZ8PTo_7hW~+}L*89%>Q*u~wfYY^Od~S2?I}<#`IvnikN=SS z7_?fbDC+i1SQXB_foY~4OFc72Q^si!5(;4pMK=aDtNw*}NQ%SgL$Q6iXz(QEFL(hO z%V>4H?1e1t^{ln(+yLCAXvK zofdu=QT@wU$$yu}*GrwWClZk)@D`%!=m;C3_E+b#CnHVWx#5uc4*UamAb=u9n|jmt z?;r#Zk2Z~>hwtDLX(EOejnxsmq^gqiA(6w5C?%F;DPii(jW+7_G4JWMd@V<`QHj!xnE%D}Y^u8^OvO%3si|PFU5!xX?Q(q) zhuwLasR^lOY`E$TeLJVk3euRHg21S~9Z9tC^kYOGiZYxs z=9?yGdMYrS6y&08J&EUyBOVT7EoT*_nx>^_>_QW7@p6V~Sm{$(FQ}K*ZMqvCcv!L2 zB2z{FX4`yc1*x7`jR`&!&hn9`os~*-(iuV0+b^65UX19M5|oRg|L)wc6Hj7$4P^TYPY zNi;d@H)p#JpdEJ~L6i}Q^T!0>?1N}yCdkD=z>A_mAIfkx^e1x=m?5~V_K@Qj@Zj3H z7`o9tA5@~W2vQ;_-^DPEau-3BC*4KH?9Jow;I;-SdII2@rJ${Zhar&SzQtp-twX&DmAxbBi&6mCqbbORQeIueJuRi^ z4^XgDUTqVO{=tgfKzaMo5p}zI#}(h3+B5Cx8LFL*wYm^(_=!nY(@H4RJrn{E(r6~F z4FwKTs#~mtV%$1(HB|Ey|Ab?ecgi%5Or_!X$FG5xiE`UPlwA>$tZ`|@PU-C-@N&mN z;HhT>)qKyIf*d)(l3mKrV zE8^tC*RavstAZ5u!<8A@Wp)64d>x#b6RyQh|nc}M`RhG!GCQwq_n`Tu3 zUeffjLtRA~w3T z!ILKaX{yYpHdP15vbae3XP_AjO*`3rq2otXR~~avSq=pw+|fF?1x~L4rf&N}7wL|J zbqv*w|4*AnSf~bV^8gZ1I?HJ4N~xoO38gML;ZP%RLbbX|Q`#177`r3~?=8))3znMD z*ie%i7;pu8u&!pWl!nAzW-#}r-|B*j%rHc;t4@!odQfiOM)N4)vfM6Z_Mw|b^F5ka zA0%L|JL+3?#gkKC>4;2u$OY85>TS%kif&=}N>jc1P2>O8V)KZCQ!}R_xHIh;YzGv> z>TsQFsEp^lgJM{Hp@b-$H3V70B2>6C^lLZ0|vlVK>(yRQh$%e08`Af8D0^8KGFWfZK5B|4F`$J zwuKb984hYUYYTK7j40yW66?)@YS*tyXgBJvoYPTas_(Q;WhB)9(H63~l&kjQ^dQ4X zsvoP#wJMm40SG}JNt5xLxa*YtexAfX8jDfcyK>usKjd zT7tgSJ|M3ufLIA>L3?mKb9$2M3qGsaL1|5SUO>y*2EZ4yNR~~&FTgPG`bGy#fXApC zaX^DQD&>)rB&a&C0#b@nIw~z`N;gOvRFC$iyhi3t^h-x({o3fqXtTb@GM$uz)UpZS zzS#*oU>JyMDkxODvl7S8JQ6N-#BKRTcBZS%%x+9{@9V5oQR}U;5o$_xvOaDO%mj7; zKBu(6ye+$6cW}`>>F1Va++%bDBV=^ZJhS0Wp0u)+xeO;OYD+uw^-)O5pmU|tZOj|A z@USQ9!Ic(TNvT;qeb1X!l+xL*KvAK$j*vP?n*d2xTpfvQE{ddu*P2D)_SNx13hVL54cy1N%wRX-5{?~#n{i{MgvtO zHlaSX9v!}8`S&*&n8{AAW^j4AZiN#hDkHeE?45u%cGvSH!Q4)}pHT3qtzuE{ck{?h zhH1uB>fs*f#Z+oaB50B`0%u`aGMETor#UcukbajlHASD!;nvF>Z=jSv5o*Y7hSDB; zFL(yQQx*Lgo&TpUk@h;#qW&Nl1JiS`*dTmQU)nwx*c3Z5Q?CKw=Ip`VNFFuoL33P< zNaU(L+0v*n4lp*3nwSBQlx(`UL&dIBr=t!Vw`cH3pW~tAjDborWe+#Q@=sP8sIk4g zmqeR7QHql(h>i||h-AaROXavI>X17aL7YN2ecMPgg3?299y9|LC8t~;pvA0KOaRkw zMTwC0Ph${$G8(E3=>HnNxOOGgdK_lfVqO%SZK&b6HB2d~!sP1QrvN95fiWxs!kbiGqa~2+bK#-i*`yI4j?x$Ynpi_=PzLT z4VPK=F$!Kf)wWxDCSMPi(F4upY07xBEprx1O&Dp>%|b872;*<-Ec9jkjJwNb%tGRvx&IF%$)32FeISpm}A~t)9xg_Pj)_w$m zpwn=6{|`?|cMjy{rjS9&l_#P?W5DQw?%e87oSd;q(ue9qertw9^R zyAzjCt*Ky!(uxZ&R#wWAIFO;%l@@+(o=GQW!uOas2BIZ-oe=li9wVVCZyoA0<}Zbi zYcLC#(;{+&B2g~o94=p)LyVlr+veb~v7i$QLOEC5n*(D(i?LCY%`ka)ZZwFc}iykezQnO?1XIdX!>#iOr0wE zLcd;Jprla7eSju?rLP^k5XS-$XI;)OjE4EJ8eu+4-vtr2Z6SbVIu=!xI4+z9QCwMpzFG_}LrJ9%p_;M+-P8V@ zcN{(dYA7p^pNcK9uPC3aKy6fD7nPGy^i4h4myW(P#M3Sn`&wQH=2_rjm}j@O5iIPE zvPfNt2Ym)UV4Ffkq~139wE>Si%uswY1CW3k+(5kZ0X3IE%qqP389>R&0jC5m!M|{^ z)tqbR%U_#=Xxb7ii*iXbMI1A0DIx4CIqwoKOS6xeJJY=-FbSCRiJHifR5la5ECL0r z8nSsNEQRD3y3LJ>NFA`iZ_SZ(Fca#j$4LZpbG|hv(Va|KKs6PZP^==-jez(zCMTWH zt|uVh2NR4lX3(Gxk`rz_!V8poQgG253CW%EQp_~=lzEbxb!G+UOkgLJXeq2eTn4L_ zb2=Pg*i;(k>NJU3FT*KtIVa{3oQ&Thh%`zR@evNn=gRhq`(XJuMy`_u)@sO zYs-}5{0RQjB@3hHO<~=m%F&r_tptGo_kLC|;s2GN6>QwFVQG4`5`mrE zSFE104z*Z?19sEbX_RB|Dy4)W^9<;Wg2(RFw%1_+KYasR(&dJEA$4C4+`aRM5100nNIzpD zpT#~ty(2{t@+tHhJr?&X`jE92w-itF%(Kb;bNET@!0*2;*!6A|6yZ+l2p&lM9L9j= z%Av+@kOqn~t^OReWab}g@^rf%kw*N)pLT2Jx(U`vIr%5BPm1s3Q15?oW@UbLH;^Jj&pJS_0Y!5BRu^CESk1nsm#cSNk827#n2-1svxl2(03m}K2nK}(&MNsz(xwd%0{Op*qxE!ya!w0-)uclkVfO+G z7M?{YdJ_OZh=Tozq~hn;bDj%un7IjJh@k*QcY`wbDlU%PO-j0v#}r~)I+djOZQuu# z)CCZ#>3Y-DZ3vRUW495i>2$1DdILTF`!-Owtqb~zk~%FprdKn`ODm~k7rkDNr0vS* z++<+ob1cSC^b$3G9>ks8o>_R|B&()lJ^tq())N!CtBH2_qR%btS!t{G`yr*ZHzOl5 z%}^(Zb>N8%t&WcMM;%=tJ>3a-70=Dyqe*%X%VhR(zyKM~ z!lyW`CS@<|85GO;QNI$FFsio~N{ji~7fV=1(zv}aA5ez|-P;t=S5}9%d@q;`$CKrr zc+%s&N=G%Zw~bJNrn7K&Z}?@*6#B#g78VLjs{;!br|hGi@PLmvgts-{$D(^%2w--j z*cc^HO?jeF&QEwgV$D9`LKTHGFYVKibpYE#?7cs^@5d>|SwY=V0A^zTu*-O-NSeJL zXQf@Bg=;;>+5O6FGrbD6%%p)w!MO8lWKfuVzQlr%ar)oCV;UJm_^OR;uLE~xc) zR;6#gR%U-#1;X@I&tr(?X~BZA;n)X@X}k_c+3T@m!1|O3i*8LIQ^kYIe1kA(QYFhI z8u$&!X041}efbUY1oJ8j>fo2i6mmNbOXgh_^jmlgzekf*)uLykAxaZMH;%)U)B^XX z?E-URl&d59TSYcdhP$4gv$qX4ju=1|=6p87iJX_mR zkD^W}HJGYEwV2)xG~g$t>f*{Q`-FCXp_!E^9^;nGixceH+(xJx)2U}asWhRNiy=}+ zo`e>FU4UO*Y-s6Cn@_^z9I^yXWL?Xx%wJ6Z}D!LhDt z$U8G7twse#+&QHVw=hvYrekr_ImE|9vYdF3*W)~f-)tku3zWG~pYt&5;@eubl4~w3 z)c7YjXsu(#nSk;Oq${zOhN?>heo`qHr)kX}xHube5^f-B&U(|8T<|B$(L@>9Nb>ms z=SoxhC?I3BaVg(pOt841Zp=$78AFnq7U4?#N!*4OWr)7|2_lAF z zZ{M|h`y!_(91`@>yHzfF$y_Q z=dMHVFuiwafY7D+*AW$BZLIo^=_fovUxErY!9SXCLtF~~GXd9w>fOXSKRZOQX_uiE zM0nrgv}NDK8JluY@Or^br4u(+P%)-s7;RoO{uWHktA`z6 zK%vMTO%9F)zc8m|>q)TRyF1{VD&ruCzaD2H{$bqDh|7ZcXHxFZ{A$6I?wxU}%p7^| zyRd(?WG0ky>68C50g1wSS7e38-G!~o;sUImYt>!IIHu)M&!sDeo0BXt6nzi-Vs0Gj zx%3Yi_YnGJ@hHa>e#q$YJ)G>-&z#24+cbpd*^w&$+-Vj4>lYlF@TvNdcT~8qbkZX{ z`1J!l%K(+Q;hfaW>|tRMVfHkqv{^!4AmHXo+t~>1o6j@uweap0=)-H`wjI!3sJdKc81sLOS{8Rz1Bv+uW;n#O~Pi^C6+#sYB;4FWTyEDE3vX-3=R{h1s zvX{nk3zVo285D^=xVbn8bWi{T&$+naxrZmkj!3-=Ppiedoi&`(Cn3zS(>dAV%#GzqH5f67-7E<~glxdsB5F@R7f<8RD$9y)_s0&S+XM0A5@lW~Pm99es2pyw|{6Tgj+fd==h6Ni#W(Ix^1e3*JE3Fs+I*GJWD( zZxF?0$ucM-8%gLQQOsLd@!5yO3C(z`Oray80<9tMU>&k7mYm^;Fb8UdVoabRMJ=4Z zc!#klf*6HdO=Rh5rx=A{x}-u%UXTCN)U^o))FU(EC#psM**E%Vrf1)3L-<2h*O)@&;_vTOG!&)O| zXAUo_!A8LeJ333%!^^`%-caqu3u|eW1pR!{fLiIeQyE6h;3njj$O7U9^mH zF4{JIy%-*I>T45zaQupXic33V=T)!5hv?+&9LWl`qPHUH>8)191$IHi?7ocWNS&Qq F{$E$0J-+|| delta 19855 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 diff --git a/api/package.json b/api/package.json index 3be75f68..9701e12d 100644 --- a/api/package.json +++ b/api/package.json @@ -84,6 +84,7 @@ "missing-native-js-functions": "^1.2.18", "morgan": "^1.10.0", "multer": "^1.4.2", + "nanocolors": "^0.2.13", "node-fetch": "^2.6.1", "patch-package": "^6.4.7", "proxy-agent": "^5.0.0", diff --git a/api/scripts/droptables.sql b/api/scripts/droptables.sql index cabb9f31..57d1b271 100644 --- a/api/scripts/droptables.sql +++ b/api/scripts/droptables.sql @@ -26,5 +26,6 @@ DROP TABLE webhooks; DROP TABLE channels; DROP TABLE members; DROP TABLE guilds; +DROP TABLE client_relase; -- DROP TABLE users; -- DROP TABLE config; \ No newline at end of file diff --git a/api/src/Server.ts b/api/src/Server.ts index c16bac5c..259c2a6b 100644 --- a/api/src/Server.ts +++ b/api/src/Server.ts @@ -12,6 +12,7 @@ import { initTranslation } from "./middlewares/Translation"; import morgan from "morgan"; import { initInstance } from "./util/Instance"; import { registerRoutes } from "@fosscord/util"; +import { red } from "nanocolors" export interface FosscordServerOptions extends ServerOptions {} @@ -38,17 +39,6 @@ export class FosscordServer extends Server { await initEvent(); await initInstance(); - /* - DOCUMENTATION: uses LOG_REQUESTS environment variable - - # only log 200 and 204 - LOG_REQUESTS=200 204 - # log everything except 200 and 204 - LOG_REQUESTS=-200 204 - # log all requests - LOG_REQUESTS=- - */ - let logRequests = process.env["LOG_REQUESTS"] != undefined; if (logRequests) { this.app.use( @@ -60,7 +50,7 @@ export class FosscordServer extends Server { } }) ); - } + }; this.app.use(CORS); this.app.use(BodyParser({ inflate: true, limit: "10mb" })); @@ -85,19 +75,20 @@ export class FosscordServer extends Server { }); this.app = app; + + //app.use("/__development", ) + //app.use("/__internals", ) app.use("/api/v6", api); app.use("/api/v7", api); app.use("/api/v8", api); app.use("/api/v9", api); app.use("/api", api); // allow unversioned requests + this.app.use(ErrorHandler); TestClient(this.app); - if (logRequests) { - console.log( - "Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!" - ); - } + if (logRequests) console.log(red(`Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!`)); + return super.start(); } -} +}; \ No newline at end of file diff --git a/api/src/middlewares/Authentication.ts b/api/src/middlewares/Authentication.ts index 20ba42d8..429cf11e 100644 --- a/api/src/middlewares/Authentication.ts +++ b/api/src/middlewares/Authentication.ts @@ -3,25 +3,27 @@ import { HTTPError } from "lambert-server"; import { checkToken, Config, Rights } from "@fosscord/util"; export const NO_AUTHORIZATION_ROUTES = [ - //Authentication routes + // Authentication routes "/auth/login", "/auth/register", "/auth/location-metadata", - //Routes with a seperate auth system + // Routes with a seperate auth system "/webhooks/", - //Public information endpoints + // Public information endpoints "/ping", "/gateway", "/experiments", - //Public kubernetes integration + "/updates", + "/downloads/", + // Public kubernetes integration "/-/readyz", "/-/healthz", - //Client nalytics + // Client analytics "/science", "/track", - //Public policy pages + // Public policy pages "/policies/instance", - //Asset delivery + // Asset delivery /\/guilds\/\d+\/widget\.(json|png)/ ]; diff --git a/api/src/routes/downloads.ts b/api/src/routes/downloads.ts new file mode 100644 index 00000000..de261702 --- /dev/null +++ b/api/src/routes/downloads.ts @@ -0,0 +1,19 @@ +import { Router, Response, Request } from "express"; +import { route } from "@fosscord/api"; +import { Relase, Config } from "@fosscord/util"; + +const router = Router(); + +router.get("/:branch", route({}), async (req: Request, res: Response) => { + const { client } = Config.get(); + const { branch } = req.params; + const { platform } = req.query; + + if(!platform || !["linux", "osx", "win"].includes(platform.toString())) return res.status(404) + + const relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion }); + + res.redirect(relase[`win_url`]); +}); + +export default router; diff --git a/api/src/routes/updates.ts b/api/src/routes/updates.ts new file mode 100644 index 00000000..4682ce7c --- /dev/null +++ b/api/src/routes/updates.ts @@ -0,0 +1,20 @@ +import { Router, Response, Request } from "express"; +import { route } from "@fosscord/api"; +import { Config, Relase } from "@fosscord/util"; + +const router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + const { client } = Config.get(); + + const relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion}) + + res.json({ + name: relase.name, + pub_date: relase.pub_date, + url: relase.url, + notes: relase.notes + }); +}); + +export default router; diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts index 99e3537c..2d003c99 100644 --- a/util/src/entities/Config.ts +++ b/util/src/entities/Config.ts @@ -181,6 +181,10 @@ export interface ConfigValue { }, client: { useTestClient: Boolean; + relases: { + useLocalRelases: Boolean; //TODO + upstreamVersion: string; + } }, metrics: { timeout: number; @@ -365,7 +369,11 @@ export const DefaultConfigOptions: ConfigValue = { allowRaws: false }, client: { - useTestClient: true + useTestClient: true, + relases: { + useLocalRelases: true, + upstreamVersion: "0.0.264" + } }, metrics: { timeout: 30000 diff --git a/util/src/entities/clientRelase.ts b/util/src/entities/clientRelase.ts new file mode 100644 index 00000000..e021b82b --- /dev/null +++ b/util/src/entities/clientRelase.ts @@ -0,0 +1,26 @@ +import { Column, Entity} from "typeorm"; +import { BaseClass } from "./BaseClass"; + +@Entity("client_relase") +export class Relase extends BaseClass { + @Column() + name: string; + + @Column() + pub_date: string; + + @Column() + url: string; + + @Column() + deb_url: string; + + @Column() + osx_url: string; + + @Column() + win_url: string; + + @Column({ nullable: true }) + notes?: string; +} diff --git a/util/src/entities/index.ts b/util/src/entities/index.ts index b52841c9..fdf18f23 100644 --- a/util/src/entities/index.ts +++ b/util/src/entities/index.ts @@ -26,3 +26,4 @@ export * from "./Template"; export * from "./User"; export * from "./VoiceState"; export * from "./Webhook"; +export * from "./clientRelase"; \ No newline at end of file