From 9a294fa6307b86e368cc4064dc6f5251cc24b7c7 Mon Sep 17 00:00:00 2001 From: Innei Date: Mon, 6 Sep 2021 21:22:43 +0800 Subject: [PATCH] feat: analyze middleware --- .gitignore | 1 + package.json | 1 + paw.paw | Bin 38748 -> 40438 bytes pnpm-lock.yaml | 32 +++++ src/common/middlewares/analyze.middleware.ts | 139 ++++++++++++++++++- src/constants/path.constant.ts | 14 +- src/modules/link/link.controller.ts | 12 +- src/processors/helper/helper.cron.service.ts | 30 ++++ src/processors/helper/helper.module.ts | 10 +- 9 files changed, 223 insertions(+), 16 deletions(-) create mode 100644 src/processors/helper/helper.cron.service.ts diff --git a/.gitignore b/.gitignore index ec7a92b6..4d16205d 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ lerna-debug.log* !.vscode/extensions.json patch/dist +tmp \ No newline at end of file diff --git a/package.json b/package.json index 711c4ab2..32d579a5 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@nestjs/passport": "^8.0.1", "@nestjs/platform-fastify": "^8.0.6", "@nestjs/platform-socket.io": "8.0.6", + "@nestjs/schedule": "^1.0.1", "@nestjs/swagger": "^5.0.9", "@nestjs/websockets": "^8.0.6", "@typegoose/auto-increment": "^0.9.0", diff --git a/paw.paw b/paw.paw index 1945d4406c345dbe63f7c92fd20ffcbf3ff75765..87dc68d6cc0f7be7d643b9732b8d4d2f70cc5a9a 100644 GIT binary patch delta 17200 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 Rw)?yHI&H$v2lFT4{|87O47LCO delta 15987 zcmZvC2S8KT`}RF|2a4b?NJJt#5`oAN5aWno1QHWP5RFj+F(Qcwfe?tZxwm!Is#S5% z;?}zN-h0%owXRyNwbiP%)>>=rcW#mkk?-%78xoZBJkLANd(WGF=$(z|^q|P;&k)xi zveNyEbaTH>U+;M@pOIeHoI-q&PmqboB;*TZGV&!dWyYE^=UL<&av8aT+(7OiKOj$$ zXUK2JbL18B2Kfv58+i{9KmZan1O6ZY1OgEV0qsEw=m63|M<53Z&;zJIUr+#aU;r?H zp=tS(R{QJHK0axC|ZHq&{}jFIs=`F z)}iyzCFnAAFS-vsh#o=@qbJaF=y~)KdK*i5Vrn}yBCmSW4X zjo2n^E4B^WjUB{}Vi&M)vCG&M>?U>}dx-sv{fDDChU2&Z_s4~JC?1AK;!(I1Z-*!2 zYP=`j3-68R;sy9XyvT_U!^`jr+=|=rF*t*d!x!O;@vrfEd>OtP-+*ty_u~if!}t;W zB>pXa1;2qm$6w&D@IUa^_@DSY0wHihOtdD#i3lQ+h#_P|5}_j0gqG+<^d|Zedcr`| z5)NV%F`5`du*5{-OJWW&msmh7B)%qA5zfuTUSc0{kT^!1BQ6qGiKoOf;sx=N_?>t| z{6+jnA|xOw(w7vHfux8OldVY!*@lcEsc31adMtjhs!+Bj=M#$Q9%oavQmw+(qst50J;mQ%>?e`2+cod_?|4J|>@% zzmtEG|4|5qQ8X1m1yU`kFe;LYqNG$?Dv3&_I#8Xc?v#?srZiMvN=FT%>{Jakf*MJU zqMX!3>PzY?YBjZn`i5FhZJ;(%+o*liVd^+_p1MF?qOMbSsfX0h)C=k*^#}EqMrbEa z({wl;K}XXPx(yve$J5Dl8l6FB(mm)bT1^k8P4rN@ls41lbOl{YJLnPgr}XFam-H0+ zD|!~ah+a(B(<|xq^d@>Uy`A1m@1qaW$LMqPdHNE4jlNCaqwmv?=wInS=zr-C0w5p- z%>+V$NDw9n7euKAQb9XGvOq29Dd;8WEyxx05flje2~2_^1<@5X!-ro*{E%jdKN5iS zL?-m_mEW$cWMs7-zFG$lD>2!t`$e0E8>_1~1<33EN7(D85Ox9l9?>9Lq*tAQtZ*`& z87(uA8O#i4?93SEGiEX~gPF@LWmYqrn4Qdi<^*$=xypRcJYardUNUc)|5!k?z@G)d zEQnx1TNWg-Ae{wWS&+?wJ}el>g261Xu%MC!4i+#hn81RmESSTBr7T#>g3T=0#eyR& zIL(5V-?HF47W}}1M=W^8f>$i~n?+G3vo4kz(flZK3^|URKu#j3kkc?VovGVKb&Jz5 zU77Ao7rjQ?vt(pHx5$Kg)E~&}q5%J1`Pv%0aq#exeAmBNj{JfAiQKMRED&v5?%xbJFGJJ5WqP{* z%RA(se!cR0L8~uA-XXW$AO4GcC<+jIL)989ds&B+EJyxD{zGmXdgbTat+o=+r`O>x zY)}=T07E7LoY647nF6NQ0F5@Uq^hQ*+U^n52`J!$OjrhJAYgKtKFfeF_=L%0`ZAgQ z%_YVmCAR8*l}1}hh25nOXbyz+NOJ~d@?GFS3lId?_fX8R*^DEXgBDPKh#fjDXvrC- z1w(R%;oggp>ze{vfYwk}H3*0I!B0RGh=yNLP<8k91jKWyyDz36)VmYY-=({b8Nle^ zrSx2CM(_HZvkA1yKo7NWX>!{uPz7ilkOoaMsd)?v?X{`75rl7R{=b&MIowiFRvlS5 z_G7I&gD$Wzo`G5oVhl_dk3ygu$mCrPbY}{gOgEJ*j#?l?@YK{E&jDKGA?OWqIs7iq zDT1C;%oyDmivos>j;vcJ97=KM`ZGD(M1k4B*=VqVU=T9dWiS&nlEJ6n7%);qh)LI8Gc7&7N(I9&+r~DJ(iwSbYViBVU3UP}&NniYYfVxM8-`8Y9SCVLjqx-6EM_0Out61uLkuHxDu>z!)I&|Tq;w| zgn01jGL6+G-EB2Pc!2AnQ;Z9a^TM|YY(}QIRIgzijjC@0J2*fBrcXWC$<*>{@8Q%H zF*I-b18#K>!u8eQ2!{eHd!j*Ix40MF=(syG0wV0hbQ&%6Ub906#V;`jGjQC-9gPG6-qOP>g^V@+l|e zGYGE-c;SZ1Fc3!?!+OwU^vyMvHemRR$tkMaD30|K@g4XFndTDlb7p*_h#ydd7ZC-_ zI1dIC|5!wnc8Q1z;Mxz-PdEf13Jv&JM6{(F8FyzUKwLeTl!-2QI%ZN65x?-jcBO`V zD56I_G!m-!W$X1`>Y*{H6#2>(`Cl?q8zLW#LuC-TtJt9Jm?=E+Bo289^NGj&XsRdj z(R7Ghj&^dP<7&n<`1KVt-327W75POqHI^Zf^2nr;q@i^?!}MGhKr^{45bm7?&@40? zneH;@OlDStIZ-vL;mwI^nK~X&E*JeAAa_ileW5AQ0th1u)wu;@WZ%h2J>d}aZU#mZp`W_)-o z)tp$Z7++p2hgT*-M|0?)nVk)0&T$0`I?)ZAyL&RxA{TTWv$%i?r|p$8y?j*@dAxuG(kN6}+Qoy$qrFyAyf=}Gi7WPqMx z*4CqEn02rtN{b2WfL`Djgfq=~2A83e!Xo<+y#^WFKySLF)jf_Ho5?1)J=&o zx_t5;Op&i+E><)y|0DVkndMr3GqbgE`N!y!hUI@@w(tTzYqI=He)&Hjgg?%>C8TlF*0=BjrNjKE7uFUx(5ssLmVq&y($G3hJ_<@ zTz+(bInv-qSQOTViwXfIVfru!mtirOlsUv4W-<$FY{PSnHe-2-9rjYLI)=r6>|IzQ zhqg5m$~0sAd9*O8z)s1X4l#X44lszqx_s<%SPwT5?(WHlM_pue%&{gOcicnLJ5I1( z(971uZ2=lj6OQF0bFsd#N}pm*4%BG7Tdif561CChhTR{zz8upbDooFuX5`EnCSyQ; zNp&^MBjL%sVntA}l`?O^24f~$={6_uEGD!B+n=)_#|NOZZ0L|42e>X%<) zw3*C2uNhFOW$m_mWfW` zt0DNc*gBU9xuS6sBK(fI<-!7s#=y~$e9=fZrj*oOPwc}*2(|?ZElZlv7@*h=Y$vk7 zh37VNw-L`CY+nPO{mdO6&!HxGj`4U-A`h|C*qH`A_aLVG%nxonbrH!WuH`Sm<)ygDiHb`#bYTgSvQIJdR6$T!V_oGp~3& z2_LJ9w|A+Cr$8KPyaR^@MB$wpRCEOj-ktm0eKD^g!cI);pB@$8G*R&{Zx#D$EMT-PAw0OlPJeGmt|Ez^pZvY40B1f?v&hjIX2 zQoe^${>yyer5w;GW&8HY?dx*oy^`|AqxVJhzP;w>U=3>%NuOeFxNi7rvW=%jwR-@c_K}v7i|*J>1c{ zQ&gRe+Lmh#BbwwT&mx9souX)b=M@vtvm|?A#_Nh1q*`UcRCh`n#$hN zTlRunqrIUN;J-t1cehdoA4-d z^C*T$vk8-jM`;rtR&O3MrZem$Sk)=U^oF+mWhd#g%pflWEF6~a>!JKTb@pfiNli3MHw7|iI~%WCH< z3;}mWb-jCgb(q9q;s~!MJB~(I zcn+1%&D{>f4cji_58^elhWL|HUd4i5EXb(~&kJ)BZ;5{(H{x&N9ShVf=(&t|PyEXQ z_|LRVX1`i)W?tQIh_&2kaSzW(6bP3i?U7U@jfrO3Ffks^B%Hg{Bi)%4kL!@1AlFxt zeu$d%cN6N(*&^2kI-|gDE#ro9{=VFBl?-x^4K@}a4UlVM~y3;MF4U>O-nMzNqD3kRW@b-nXLx=T4Q$xIXv#(0{9u=K z4R$*-GJZ{Nu*>b7NjTUgdz0?LF5Ee@08VyUP|O1F*{-J&n)|t8iR31{7yHfdO0(oZ zauD*3TO1P$hC*>X(>k(<j}#hBjzQMD0S#k8xfdWO`B@V{pOfQQP{xAco)97@HUab{_r4Po z&jb3312mnS;RaN}0&5dMb0MJ313v<^kX(dpaGR`(1=S7dk6cRD^XZRV#sV7;VkNg| z7p5J*=vq(uBiBQdZ6r5wi@VdGoikYt3u@gcyoPdhWd^s&c0xc`4BqLF+)M65Ho7y+ z2o{WL$S~wV@-SafNcgyGBoF8~2dEgrL(uwX323S;QgrkTX);^4_71sZE97wYaf_z`lrQGD1t4xW&|Ae-DNoMpl1 z4Jn*_Mn30LIQfDFpYa@Camg{AY0D>yH!xL`e?fFA@*R(I9E1Sd*YO@C8GSQq?EIdY zLSd$EF~loVQv^jKo86u^kp+_*J&h7jaAW1|`jj8lj0KZe@P!8t)tu8*!6bS#rCNOK zX;d)uG^!O9;@0m=7EE!W%HUm};&xSMhpg`1kX$JV)dtx@#c+A*D;CtTU|OL@+oPh^ zVzXA1!)IQez@%a+I0#-w#c|1YI+tvzc2oijX0Tu;Ok9UcTJ~$t%_rnAx5hPORw|tX z*qB+V&M>o5T@V$ea6_EMNyiOl;j=5f#%eMSmsQ%V{8I`l3&L$T)LT9krAD^8-Eb}o z7BsjarKNHqzJ?x}>O*zR^V$_~woG9p9$QiaIB1PK8LH6bpOgUt%b|=MJP<{d zxcqZ)Lk~@rb3brjELaF(!$Rko%d()!V3q|RO=jVf(8lK&;oLUHsKH@pu&6CSUS=1~FZp9$a zc`lxV8hL)rv*ZGC1>^}k)Rin)1;2xFxVmW^u7RKPSBBoTSNMqGI>_+0MTs?T7^uzE z7G%5I@z$|m19Uvz)wWZ+nz-6-Y7YzGR&6~`azE#5Sx73=0oHMMA4MH$;%g^3UptAY zsnZ-67Hou7JREFt;mjDMEU7ISZmlfge4Mw#Md)q^%e~$03Uw9P;ch*)uwXlEJ$R5e zs9O-ESMx!APu*t0Ru*jILEhuqjVu@vN(eI!K9BPNebfZ#6AtJv$V2L>8)(=LE<^8h z1MO?}a+Fu@ZsS3GwDY5GgZh(tgY0y>%Wf9zYjl^tsrMhb%fA%dgF!L(dO*^EbC(Pz z*#nM-+c0l;p#?5?p?x5_JgJoK;Hj6i9P;c;ci{-R>*WcK z%t;oUavQ|EUhb`S)k|6l-8;e#>!oLiOy?lG-PSn6^l}YO=$>vJH7*@{bH5$xnE!G4 zqX&A+c-AfBIoGmK#q&*7yx^^3-#n|;&gXf$1Oj?hvjX&QNc8kDx(wMv59bp7B^F#~ z!9{qa;-gfrbhXMJ2dAyH4SEh;NyGl*G7GLOqpN8<3$C)@8cg`VIa&`I$@zB<(h2Db zyVH2sfVusfc5=a~fIVy?>|#Bije|Z;kB8E_X3;FT!HIg)t*EYigsi&KXyW%b^fVZU zLq~YUAw7ehiR^V(&08$E+gLT}+4MXJlMJI_Ie-oI_si({^a2*ZP=s^dfhCQF%x#7x zoY@;ID7}n(-`HK#t6&ACSJP`aLx@;#j|KPLAU!#P-UzY9jI8g;TY4+9k9%Cef(Oh= z_YyncGXi=iqNZUa{>bed9&$eJuPhmAtQiiUW4oUh@V}4S%Lzw$b3IHSLH4`3{=|Y` zytp2xxy>Bp3cV3>eY}i5O~dWn&n$TIe{pp^|MKDrpMTXuTk(xDeVyZagLXX!gIs@Q z!PAeq-i6q%jat%}wCM-*kH`Uc2lX2ZUNm%2^iTB9dG34v!_6~3h9QZkVvEp z(iu)Qli*}p2-{Q{oNs!3<2CH6=s%(2IrLk10I=XCL;_3e?;Id*R0W^BH|9YB0)Y`@ zyhIaV0vtK$t|ou5;7wyS5l{jjD4JK}BJdS_!h+W<_|pSY;Lka1dzhx98B~J;D}nBkXKJ2SGZQLIh1l*aEK+HVgh`dbnmXFz5dV zk?L3!X_7?XaRk0@Ly-q{x0S%%xT|zm^GvvT_WrR?aJ|Rn1^LKf0q624&Y~DR$D*{F zYPd40su*f@g@6D)CR-=axozpb!`S%R#91V|m zvg9~&B0SjqC$T{$s=K^vOJm{J6HMtC)_FM(ed#)qb!%f&`aw|Odxf7oI+)M7~ zHcsSG@;G^tJWZa3JECvNOXL;u8hL~Kj{KgyL*65Qs5?4N=8T{c;bG5ws+bx~4WWio zW~!QkT_81{nnX>erchr~YvDo9jj*BG0}pv#fCoIkhX*{L(I_pTgXl0i5uWBuf#*5X zX*n!xUFmLgCar|$IycZe>BIC<`WO0@0Ea;l=#%J^>eIoen@_fn#;3ri%*W=#`pj|q z%=1~`v&d(O&l;Z{K6`!k`yBK+=5xa5l+PKT%Rb-vJn(ts^VsK!&+op7FXbEHEA(yQ zEAkEZ)%y1K?cO@E%saL zSMRsnZ>8UAzqNkf_-$ww*sOK4ux45QgZ&-;BmGDFkM(!@Pw}7OU*|vDe}VrZ|0Vuk z`>*w1@4wN1v;Q9d{r(625Bs0-f8+nw|DFGP{|^C302+V?kO6dnPrxSu%>n`f{udA! z5abMK8PF;~91t219uOH28_+%=HDFNl^5z$W&4f`xi7-akRv0Ig3$ul4p+?wS*hiQz z93(6e4igR+RtPJFBZZTMlZ8`+(}dH7GljE+bANwuq?1V z&>C13SRGgs=m;DcI681b;8%e&0(ZA)5tJWf4jL9TJg6e5GH7fN6ZBco_@IeFUj)qz znj17fXkpOepjAOTf_4S%3ECHQAm~ugk)UHiCxXrfT@AV(^j_3lBows}iA2GoHlnsp zQJkoqC{dIw>Llta>L$t*^%RW|jS`I!eJWx^pNYnaCWt19CX1$srirGDW{PHs=7{Er z7Kj#!mWaL zrNQ;V>w@-lm7>+qkk3NqhRhFH7_vBIX~_DJ zO(9!CwukHt*&T8ujI!84T}wn4{H~e7?vEC5|$R0 z9wra#9M(0gTUch8GAt`BCrlmIFRUoc80MT5_EUs3qDzD#A|s-EM30EPh=Pdz5&DQh z5r&8n5p2Y`hzSvsB4$J^i&zn{Dq>Bn6+**vmUq&TvBUs_B9kOYk|YXAj-;nVE9ouK zNeU%J5~IW<87`SGStwa7St_ZQESId5I9E&7O1_b7kZh7{k!+LfknED|k?fNkkQ|a6 zksOnpkbEn-B>AgN-g#ET?pi zbe?p9bdhw4^lRxd=?dv8=^E)e>3Zo#>1OFx>2~Q(>2B#E>1pX%>F;fO#g2;oDt1O} zUF_`Gxv?u^SI4f6T_3wKc602W*!{5wV-LrkiTytIPVBwdA7X!ueH8mR_DSrovCrbv zartotabx0c#yyLB9``ctRov@%5Rb=`@lHX!Z@gc8P<(KFNPO$~Ht`+eJH~g4?-H+w z&xr3H-y=RdUKPJCep~#G_&c($vV2*AtiNo4Y@p06E0trNo%BNC$$C5bVKZ4=`XrzFl!oSS$s$&oZAX9|EB%h_V3!iZ~r01H>FuhK#DM>MT#gTJS8eck`j}W zn39pwJ*7uVc8V&cXNoqZcS@g>{FF^8yHob2JV?z?HKz_sEl;gXwWT^!$E8k4os>E? zb-FXPE_HV5lGOUt<*6%EH>Pe$-Ilr|^Ltken>;o&@?=a zOrz6$(mqM^PivkgOly%QN()X4NsCQupO%_7C~Z%NUpjn9N7Au$GM!Fuk=`=BReJ06 z@bt*^xb$}EiRsDdozgYwz0z~j^V18`b?F1sorUQ|>BjWa>6g>5roWR1$>ZcQd7`|% zJXM}4&z7s?J>|Lbe0e{)PHvPBkq?!d!-<98&|0I7df7waYWqg-MibzEVMMp(vg~F-G zQ1nvtQRFN7DF!G8DuyUZ6&6LA!mg-StWc~{tWkWU*r3>?*rM33*s0j9*sIvDIH)+R zII1|IIHfqFIH$OvxTv_S_+If)@l&@?x>+(dWE{;no^dMUY{vPFTN!sU?qxj4c$D!t z<3+}+jMo`&GXBeq&rHZn%50yRmYJUElxKF%RAgpkcF*jQnVqT1?3t;}%+1Wp?3>vy zQ z%H7Jn$^*(n$|K5S%9F~|%CpMz%5RmIlvkA3lsA>Pl(&_4mG_koln<3pl)pQbfAnb8 z!;!TxYjf7ttQ}dqv-W14$~v2MKI>xEm8@%7ce8%T`Z4QK)^AxKvXN{wo5-fJeX{+s z{j-~A3$sUMf1W))dwtI7oVz*qbAHVEDd*>$*ExUX{GIbY=RXxt`KW?bA*$A@Fja&q zN+nUnsM@NMRT(O!Dod54>Z#JIoV`_jRQW2M%BV7_CaadJ>QyULt5s`NJ5~Es2ULet z$5p3PXI1A_*Hz!CzE|B*{iJ%L`c?Hz^`|;gEm6m)+p6Q$?bM0tWOb^#gSw--le&vq zq0UfuS7)hn)M~Xx-AkRT&QlLi4^|IRf2n?=3DmUJ#A(`Tk~AqAjZ-r~W6&5iLo^o6 zaE(<{r5OP~o22d7t|JvEErudu3%!p7X@Dy%qo~$Fu!17!HR+n1)B@D73?V3Rj{Yv zXu14V@U3*=suB#3nxzzR0_0kpTj5?EUsLre_(^cpy zbvB({cU$*J=X^ZCPv2JGRo_kDU7w}T(HH1-dcD3-U#uUjFVk1(EA=-0X#E=fH~J0w zP5Q0+9r|7RJ^KCngZjhzqx$3ells&8v-%7Ai~7s@tNQEuoBCV&`}!yPUk5fH6gp^3 z;i|%Yg$D``7al7-QFx{Bdg0B&?+fo1-YI}0DOAPgf<%X4pjfO3TZH66& zgN9RvvxWV-$ctP=^;w8n)i&qt|E&ir>d-1N~J;nQqj~AaRK2vj0wghr?I;m5N-%Xc zWth5~dYIHEttr=(XBucSn2JqDpf8f{u*`o^@uw8^y9w8ON^w8ymHbkKCz zbkua*bkcO%bk=mibkTI#bk%g-bklUp^vLv^>BW$sl9?sHmnM`dOS4K73GerS+xjOE;BnDcxSWvvhaq-qKU0 zmrAdc{%vk%4loPNLFQm{8*`kwojJ*zX6|V2Z0>5#Huo~;n)A$k&HcKrsWEpBPTgoiu7OSPoQf;ZRI4mPAV=SLq7|Umt zah3^|NtT6{6_!<&3uR}A$CURhFD@TkUQ%u@A6D)tA5}i4+*$rv`M7fD)bi=&Gs|a{ zFD~C$zPWsB`Hu2k<$KEylpiWTQhux=wxWGSYQ-Sy2R8pusykJ`R6Vcyz3R2I>hG%eRsY$5t(mQ*Ey5cr}f)t#ybSASRiOSSW9_4DeN)qmR& zJ7y>BwB5%pwoB|W_Fi_Ay~J*|m)R@qqwS3SbNdAQm-cD)8TLB+Qu`YFH}(zoP4?aP zef9(PL-y15%l2#boAz7w+xENm$Mz>R{xzS~%&nPUv#4fiO?}PAnk_ZkYIfG_so7U^ zyykMv)tc)yH*0Ry+;-O7t+`+Gq~@=hcQx;8KGcF*td^*yY6Z2;YDKldwcTn9YWvsf zYYS_OYs+hGwKcUPYRA?xwV&6Huboy~S3A3QZteWqWwk47SJ$qs-CBE~_Hgad+7q>> zYR}Z3tG!WszxIKHcC>bcIU*erM~oxI(ZSKt(b=JJWH{6gt;5;d(Z`{8Oms|kOmR$e z%y7(d%yG|Dh42Swel Vf>Q4F6ZaeLKK9_Y33DsS{|A$YXQ%)G diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b9662f5d..4a50011b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,7 @@ specifiers: '@nestjs/passport': ^8.0.1 '@nestjs/platform-fastify': ^8.0.6 '@nestjs/platform-socket.io': 8.0.6 + '@nestjs/schedule': ^1.0.1 '@nestjs/schematics': ^8.0.2 '@nestjs/swagger': ^5.0.9 '@nestjs/testing': ^8.0.6 @@ -91,6 +92,7 @@ dependencies: '@nestjs/passport': 8.0.1_2c02db70fddcb59258fa0eed39c4b725 '@nestjs/platform-fastify': 8.0.6_67f7e5db8827badcb202b1d38f6b1aea '@nestjs/platform-socket.io': 8.0.6_875c1aa90becd3a53d7e39e33971fbfe + '@nestjs/schedule': 1.0.1_be74d10e7c1accb5ea6dd58471a1ec77 '@nestjs/swagger': 5.0.9_dc9defb2ccd6e5ace839769c2c65c2a3 '@nestjs/websockets': 8.0.6_d9cb7157596bf7c6176480174d173b36 '@typegoose/auto-increment': 0.9.0_mongoose@5.13.8 @@ -1165,6 +1167,20 @@ packages: - utf-8-validate dev: false + /@nestjs/schedule/1.0.1_be74d10e7c1accb5ea6dd58471a1ec77: + resolution: {integrity: sha512-EU2tB4rxuEgum8JlorAFvXkU982EYZm/IBa7n6kgkyps5BbxQSFf7iR1CLkP9zODO9ApZTWk5z3q9L3O7vrkoQ==} + peerDependencies: + '@nestjs/common': ^6.10.11 || ^7.0.0 || ^8.0.0 + '@nestjs/core': ^7.0.0 || ^8.0.0 + reflect-metadata: ^0.1.12 + dependencies: + '@nestjs/common': 8.0.6_4d0c20d2c2a765e9ff99ebac79ad2484 + '@nestjs/core': 8.0.6_214ebf00327c8ed1d6618d61764e6a91 + cron: 1.7.2 + reflect-metadata: 0.1.13 + uuid: 8.3.2 + dev: false + /@nestjs/schematics/8.0.3_typescript@4.3.5: resolution: {integrity: sha512-A5qyS9yv6v2RIBqbsyYG57NfYA8Jm/aypRV1nc7JXjhdfDHwWKqCsgQ/7/82vVjhlvVAfr5x/dpCWqcF3XYd7w==} peerDependencies: @@ -2721,6 +2737,12 @@ packages: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true + /cron/1.7.2: + resolution: {integrity: sha512-+SaJ2OfeRvfQqwXQ2kgr0Y5pzBR/lijf5OpnnaruwWnmI799JfWr2jN2ItOV9s3A/+TFOt6mxvKzQq5F0Jp6VQ==} + dependencies: + moment-timezone: 0.5.33 + dev: false + /cross-env/7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -5111,6 +5133,16 @@ packages: hasBin: true dev: false + /moment-timezone/0.5.33: + resolution: {integrity: sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==} + dependencies: + moment: 2.29.1 + dev: false + + /moment/2.29.1: + resolution: {integrity: sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==} + dev: false + /mongodb/3.6.11: resolution: {integrity: sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==} engines: {node: '>=4'} diff --git a/src/common/middlewares/analyze.middleware.ts b/src/common/middlewares/analyze.middleware.ts index b2bc15b8..2dca143d 100644 --- a/src/common/middlewares/analyze.middleware.ts +++ b/src/common/middlewares/analyze.middleware.ts @@ -1,7 +1,140 @@ import { NestMiddleware } from '@nestjs/common' -// TODO: +import { ReturnModelType } from '@typegoose/typegoose' +import { readFileSync } from 'fs' +import { IncomingMessage, ServerResponse } from 'http' +import { InjectModel } from 'nestjs-typegoose' +import { UAParser } from 'ua-parser-js' +import { RedisKeys } from '~/constants/cache.constant' +import { localBotListDataFilePath } from '~/constants/path.constant' +import { AnalyzeModel } from '~/modules/analyze/analyze.model' +import { OptionModel } from '~/modules/configs/configs.model' +import { CacheService } from '~/processors/cache/cache.service' +import { CronService } from '~/processors/helper/helper.cron.service' +import { getIp } from '~/utils/ip.util' +import { getRedisKey } from '~/utils/redis.util' + export class AnalyzeMiddleware implements NestMiddleware { - use(req, res, next) { - next() + private parser: UAParser + private botListData: RegExp[] = [] + + constructor( + @InjectModel(AnalyzeModel) + private readonly model: ReturnModelType, + @InjectModel(OptionModel) + private readonly options: ReturnModelType, + private readonly cronService: CronService, + private readonly cacheService: CacheService, + ) { + this.init() + } + + init() { + this.parser = new UAParser() + this.botListData = this.getLocalBotList() + this.cronService.updateBotList().then((res) => { + this.botListData = this.pickPattern2Regexp(res) + }) + } + + getLocalBotList() { + try { + return this.pickPattern2Regexp( + JSON.parse( + readFileSync(localBotListDataFilePath, { + encoding: 'utf-8', + }), + ), + ) + } catch { + return [] + } + } + + private pickPattern2Regexp(data: any): RegExp[] { + return data.map((item) => new RegExp(item.pattern)) + } + + async use(req: IncomingMessage, res: ServerResponse, next: () => void) { + const ip = getIp(req) + // @ts-ignore + const url = req.originalUrl?.replace(/^\/api(\/v\d)?/, '') + + // if req from SSR server, like 127.0.0.1, skip + if (['127.0.0.1', 'localhost', '::-1'].includes(ip)) { + return next() + } + + // if is login and is master, skip + if (req.headers['Authorization'] || req.headers['authorization']) { + return next() + } + + // if user agent is in bot list, skip + if (this.botListData.some((rg) => rg.test(req.headers['user-agent']))) { + return next() + } + + try { + this.parser.setUA(req.headers['user-agent']) + + const ua = this.parser.getResult() + // @ts-ignore + await this.model.create({ + ip, + ua, + path: new URL('http://a.com' + url).pathname, + }) + const apiCallTimeRecord = await this.options.findOne({ + name: 'apiCallTime', + }) + if (!apiCallTimeRecord) { + await this.options.create({ + name: 'apiCallTime', + value: 1, + }) + } else { + await this.options.updateOne( + { name: 'apiCallTime' }, + { + $inc: { + // @ts-ignore + value: 1, + }, + }, + ) + } + // ip access in redis + const client = this.cacheService.getClient() + const fromRedisIps = await client.get( + getRedisKey(RedisKeys.Access, 'ips'), + ) + const ips = fromRedisIps ? JSON.parse(fromRedisIps) : [] + if (!ips.includes(ip)) { + await client.set( + getRedisKey(RedisKeys.Access, 'ips'), + JSON.stringify([...ips, ip]), + ) + // record uv to db + process.nextTick(async () => { + const uvRecord = await this.options.findOne({ name: 'uv' }) + if (uvRecord) { + await uvRecord.updateOne({ + $inc: { + value: 1, + }, + }) + } else { + await this.options.create({ + name: 'uv', + value: 1, + }) + } + }) + } + } catch (e) { + console.error(e) + } finally { + next() + } } } diff --git a/src/constants/path.constant.ts b/src/constants/path.constant.ts index b3744fe1..470935e6 100644 --- a/src/constants/path.constant.ts +++ b/src/constants/path.constant.ts @@ -1,21 +1,15 @@ -/* - * @Author: Innei - * @Date: 2020-08-01 19:49:31 - * @LastEditTime: 2021-03-21 19:36:20 - * @LastEditors: Innei - * @FilePath: /server/shared/constants/index.ts - * @Coding with Love - */ import { homedir } from 'os' import { join } from 'path' import { isDev } from '~/utils/index.util' export const HOME = homedir() -export const TEMP_DIR = isDev ? join(__dirname, '../tmp') : '/tmp/mx-space' +export const TEMP_DIR = isDev ? join(process.cwd(), './tmp') : '/tmp/mx-space' export const DATA_DIR = isDev - ? join(__dirname, '../tmp') + ? join(process.cwd(), './tmp') : join(HOME, '.mx-space') export const LOGGER_DIR = join(DATA_DIR, 'log') + +export const localBotListDataFilePath = join(DATA_DIR, 'bot_list.json') diff --git a/src/modules/link/link.controller.ts b/src/modules/link/link.controller.ts index 75452bd3..22b48d26 100644 --- a/src/modules/link/link.controller.ts +++ b/src/modules/link/link.controller.ts @@ -1,4 +1,13 @@ -import { Body, Get, HttpCode, Param, Patch, Post, Query } from '@nestjs/common' +import { + Body, + Controller, + Get, + HttpCode, + Param, + Patch, + Post, + Query, +} from '@nestjs/common' import { InjectModel } from 'nestjs-typegoose' import { Auth } from '~/common/decorator/auth.decorator' import { BaseCrudFactory } from '~/utils/crud.util' @@ -7,6 +16,7 @@ import { LinkQueryDto } from './link.dto' import { LinkModel } from './link.model' import { LinkService } from './link.service' +@Controller(['links', 'friends']) export class LinkController extends BaseCrudFactory({ model: LinkModel, }) { diff --git a/src/processors/helper/helper.cron.service.ts b/src/processors/helper/helper.cron.service.ts new file mode 100644 index 00000000..602f1315 --- /dev/null +++ b/src/processors/helper/helper.cron.service.ts @@ -0,0 +1,30 @@ +import { Injectable, Logger } from '@nestjs/common' +import { Cron, CronExpression } from '@nestjs/schedule' +import { writeFileSync } from 'fs' +import { localBotListDataFilePath } from '~/constants/path.constant' +import { HttpService } from './helper.http.service' +@Injectable() +export class CronService { + private logger: Logger + constructor(private readonly http: HttpService) { + this.logger = new Logger(CronService.name) + } + + @Cron(CronExpression.EVERY_WEEK) + async updateBotList() { + try { + const { data: json } = await this.http.axiosRef.get( + 'https://cdn.jsdelivr.net/gh/atmire/COUNTER-Robots@master/COUNTER_Robots_list.json', + ) + + writeFileSync(localBotListDataFilePath, JSON.stringify(json), { + encoding: 'utf-8', + flag: 'w+', + }) + + return json + } catch { + this.logger.warn('更新 Bot 列表错误') + } + } +} diff --git a/src/processors/helper/helper.module.ts b/src/processors/helper/helper.module.ts index 6049b2f9..09a8939c 100644 --- a/src/processors/helper/helper.module.ts +++ b/src/processors/helper/helper.module.ts @@ -1,16 +1,22 @@ import { Global, Module, Provider } from '@nestjs/common' +import { ScheduleModule } from '@nestjs/schedule' import { CountingService } from './helper.counting.service' +import { CronService } from './helper.cron.service' import { EmailService } from './helper.email.service' import { HttpService } from './helper.http.service' import { ImageService } from './helper.image.service' - const providers: Provider[] = [ EmailService, HttpService, ImageService, + CronService, CountingService, ] -@Module({ imports: [], providers: providers, exports: providers }) +@Module({ + imports: [ScheduleModule.forRoot()], + providers: providers, + exports: providers, +}) @Global() export class HelperModule {}