From 1b562f4f2fddae6354a656ad538be844e0f94099 Mon Sep 17 00:00:00 2001 From: tuhinpal Date: Sun, 8 May 2022 21:29:39 +0530 Subject: [PATCH 1/3] Created a .zip based auth sharing --- .gitignore | 4 ++- app.json | 4 --- config.js | 4 --- example.env | 1 - main.js | 6 ++-- package.json | 6 ++-- session/assets/loading.gif | Bin 40359 -> 0 bytes session/assets/qr.html | 67 ------------------------------------- session/genToken.js | 36 +++++++------------- session/genTokenLite.js | 60 --------------------------------- session/manage.js | 46 +++++++++++++++++++++++++ startProcess.js | 11 ++++++ 12 files changed, 77 insertions(+), 168 deletions(-) delete mode 100644 session/assets/loading.gif delete mode 100644 session/assets/qr.html delete mode 100644 session/genTokenLite.js create mode 100644 session/manage.js create mode 100644 startProcess.js diff --git a/.gitignore b/.gitignore index ae76441b..31ddb5ed 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ cache/* !cache/readme.txt public/* !public/readme.txt -session/assets/qr.svg \ No newline at end of file +session/assets/qr.svg +.wwebjs_auth/* +session.zip \ No newline at end of file diff --git a/app.json b/app.json index afc3499d..1ade1bbf 100644 --- a/app.json +++ b/app.json @@ -6,10 +6,6 @@ "keywords": ["whatsbot", "whatsapp-bot", "whatsapp"], "stack": "container", "env": { - "SESSION": { - "description": "Puppeteer Session. Get it by running genToken.js", - "value": "" - }, "PMPERMIT_ENABLED": { "description": "Enable Pmpermit write true or false only", "value": "true" diff --git a/config.js b/config.js index 147a338d..5ef826da 100644 --- a/config.js +++ b/config.js @@ -3,10 +3,6 @@ const fs = require("fs"); require("dotenv").config(); module.exports = { - session: JSON.parse( - process.env.SESSION || - fs.readFileSync(__dirname + "/session.json", { encoding: "utf8" }) - ), //if not using env vars create a file named session.json pmpermit_enabled: process.env.PMPERMIT_ENABLED || "true", mongodb_url: process.env.MONGODB_URL || process.env.MONGO_URL || "", default_tr_lang: process.env.DEFAULT_TR_LANG || "en", diff --git a/example.env b/example.env index 7dd41166..ffe1c0bd 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,3 @@ -SESSION = '' PMPERMIT_ENABLED = 'true' MONGODB_URL = '' DEFAULT_TR_LANG = 'en' diff --git a/main.js b/main.js index 35f201f7..e0ed654f 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,7 @@ //jshint esversion:8 const express = require("express"); const app = express(); -const { Client, LegacySessionAuth } = require("whatsapp-web.js"); +const { Client, LocalAuth } = require("whatsapp-web.js"); const pmpermit = require("./helpers/pmpermit"); const config = require("./config"); const fs = require("fs"); @@ -9,9 +9,7 @@ const logger = require("./logger"); const client = new Client({ puppeteer: { headless: true, args: ["--no-sandbox"] }, - authStrategy: new LegacySessionAuth({ - session: config.session, - }), + authStrategy: new LocalAuth({ clientId: "whatsbot" }), }); client.commands = new Map(); diff --git a/package.json b/package.json index 9ca538d4..614d0ff5 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,8 @@ "description": "Plugable U***b*t for WhatsApp", "main": "main.js", "scripts": { - "start": "node main.js", - "gentoken": "node session/genToken.js", - "gentokenlite": "node session/genTokenLite.js" + "start": "node startProcess.js", + "gentoken": "node session/genToken.js" }, "repository": { "type": "git", @@ -23,6 +22,7 @@ "homepage": "https://github.com/tuhinpal/WhatsBot#readme", "dependencies": { "@iamtraction/google-translate": "^1.1.2", + "adm-zip": "^0.5.9", "axios": "^0.21.0", "child_process": "^1.0.2", "dotenv": "^10.0.0", diff --git a/session/assets/loading.gif b/session/assets/loading.gif deleted file mode 100644 index 37128a0144e1ccef1de6bdfe63191b0d628748af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40359 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

e{ zoIZWO;!Jq~FwVrKalBZ#c+NDav^Y>Anw3M^o09-loL4I{Q6NTa_U*NJ1`vEcX9JPC znPJ#SOV0+qNMo^lQ8y+2nVzq5!ZWO|L1F~j7wXYlaozVt7S8%%;r1U78kdIJ2iW+} zg{cbG>b)F5bSR4YKGcHp;fZeAdIXr&hnrFa;EqQS>kZGd(ox& zhxIh+0CC$|p+JD$qF)h_w0jPcMZ2EO-0_$E&ya1aXKpLvA&et zpdu6YNyfDr@zzSSoqmi#S^228rpd$Pni} zd;0S&Lsz@OtzB`X6yfUt$Ai{i+I38nq=TqEjWi2;((NCQ^p}Ro8SwqD!=$Z}p+s_# zexH#nP7~4zki9CM&zYB2E7*MXnJY5Sf zaJbSFpu$4thAR>)vOA!HEP{~Oo!)^HI1w(Aq6F`#0=WZbA4_>PNR{ zYEi3`*fb~3Q!IaxHsH1krYMH3%+4DtWx^EV4~GhUnx=q_rgsO@)i!nns1UKdW1;Iy zP*tJpc$rd@97PD(B-d6#Qq6}8&-K~4rsTj^N@eCP!) z2rtiD-7G>I%`K_GA`XgLIhNBcHb%-P>nD^+ZAJ*<+^(>1o;FvJGpaT6Wxn&d_g3wxH_yxrg}p^avd!SzBo7r zPl~cOEA(V(TnupQqVj8mew|bsBNS~c00@Uw#gJd)v@+EjD= zg&ZHP7XZ81p`>&OpG~(hr*e)}WZd_)v;P)jj=ig5kJLn7RwP_PHrFA{)T>sxB( z7)qL8FD_Z{&>cmq=>s|#2fpCajFmXx(-H6}7?ZNvgNO-b;c`D|vc+DXCKvPo7;&{8 z-2~T_Aqc|N3k7_%1J6WdAJan<(`oA=hq;hQ1v1^ck1!2r6(|;L{CoojKAZJ~jF_F% zrSq_1tnKgLxQMrG{^BS;_O_uH;CJ7+=gguncFtD75eZYNZK@0$;gjbYkG%If95Dd9 z>Gj-!g<7SjOTP_kCGCVMKyvo~tSvP?jkU_qr6{^z zH^rW>IhT#QZ=R#IFDtm_4Fa>z;!P_ipX~t4ee+`l)&GDqf-}L(0lvJx@c~X@O+SeE zz4|jfx7+7yuhRvAW<860!o9FMs#Dg&k7u8?q8UM18d z<8Wr8apEa$IiskUAaOZXxRUEhoioYoF}iYAd2y_mtJMM5Db<-kykYubF|G+FqvhGf z$&hMlRFB_Qe|ePdM2QBkP;e0AZ;Yy^x8vYymqz3VBSQc&QXumsc=cRO+k=Zus8odr z1m^om6{Og$T%x&#m7@o#D~aK6(_{7)%xc?~kQwW6A-tSSW7)LB;Ez%Q zBcOc02_^Uo(qVPDMXF{ptkAD2K4{BF2rG3Ic_;jdVi;iFxsExyuiVyCykl=5IXJvL zZ8eU+*T@T}-$`2Sfv#37(_%#p4nSCP;zZ3ncn@*&KGgM}21h(e zAU?CcUI4c(*DxY0kN1a{QR0s%(=JeFnXn0&|JFFdBE;G`-~U%6&l!R)YGmba6Kj4PF`s z{P2Qeait1Nb-hze5l+XoIsjMem`zv_bg804zb8+7T?$;&Gt8-oy1~l<{FXbFp|_l* z7`+Gc4pcm+M_i6OYX=+cv6)$gbM}y6BCUx{Mh0H#UYOc__uIXDntU{Si4!v4yJ=}x zHok7)a|1i%{!sN1-Q_9@*4$Tjx8~JQ&cpj~Gcwgv2tm|5Hr7GRGwFdgOC3#d2o@_h zNsYh(G`4f#Zge@1^qS%uhip$gf=%o}B>vlAmJThX#q!%fE7tc%T)@|>ht@AO zPiiEcbz-S^^#%mPd)lkG=VCoZ)pPgOGFgF9{u(SNdSd{~c1{q016786sERtcaZQEP z`Lpn!_!T;gGM$0yDb*qr^ps5dc`EorA6)Yk z(&pv%Z?hJ#?4eQOKDB)w3s1d+t)fQ(kvdorhQeHR)uPaR=ITT{e;)@6Ib@Xj0zXda z%1o35Xe=1c@S~+SO~DmaRlhJxY7&aJ{aCTF8`ur@19AWRC&BoEW7zY*M_`2Z3)NP| zP*Odo2MScylHo3$lEEUH%2D?ruNh7m&A&HyZ$gA?r41`(#AOwEQxW6mh=)dtb^3ai zA5%@&SoJY&R#ti?JK)lN^0=st=c~Xh44Yt+G9t(Nbzc*#wrWdLmMraz(sgiad`=P! zB)>AJIELg0~m2iC5U z6rQS6-1Q-M@8YvxYuD}3tvH_ib_;RUFl&Er4MEC9Wndv5Cv z?d#2zJU_x#lpVjf2WCBbY%eD5o!-wi)N!6yfi3$9Q}Z?H@jlp)Z17M7A1`6Mtcxl$ z(uN{={NUMy5H>8#13@YnflhBa&3hMW|6O9hHPZ_$eL~0{dl&s~0q!=F6u~NdXn#J& zHhMPG?nY4t-qk!gym;Ove7KBmMV~Hr-`c(*W9Z8pXz7%sPDsZ=A zAe1EOARZxJ%1(KzBeK4~b4Enx2j^XRt-F|fFEsZGv4c1csi-B2xbi<;YT&j_XLx}d z`48O^KhZ(s)m?m#w21Uf<*{$oxC(@5701NAcr-so)ZMM?!+ZImhlBQhpx#ZHdhiG! zQ(7;tP43++sJ6g!b+tSe0VHi4=b#)EEa}GrnREzrrTXV- zs`=;XYe-|wzs45is$0|Rb;4sy2*lut(B3YZZMjRfK%7^wm;*cwS%ArNyxiV)b!U>oexp+{G73BdfDeX?;*b&Qykx zTH#oRDwUCfJ7i2>7$a(XsInB+pd|gOTVgHJl-YB*J{Xqe-@A+9*nK;Rte{-7GLHeN zb;of$)qJj)*7hgpE6(#&^1dpUudI?u98efGMT&Bt>&YrOG6fwX3FlcET47>|oX!D- z&`iqt_#Y2P_5pQZ8iwv)g9SMK4`~?kU>XKESXp2ihR-KYu%|M~4QfBsSqDyala^r3 z(-D1@Hc3SXKs_^1wEp0thBHM>e#D3T-e!qJ7ED}Rt7H6d| zLscLhFlTlD9uR6MoUFO@%!9!>3vbE0(u?vSu<}k;UwIqczLq$2Qk+jQ72%$zxNSSg zFtrnMuwpL$wo5&2ElbNpm053ooo%Fr%_PEqoy=2b1y*i}XknU;=-_0gFL+XaLZHa(4U?i5HL!>ia9Ob&SdLA~lo2(WB z#f!2CG&u7XpvvH9ny*Mi;Z2VD6b$!JY{MS|)hqQyS z#(sT4u^#HAp!OJ*h;>nS-#q9_KtlKTftM}y^1t=^%8%d!g&HDDRl8JL`??Ipj}w8O z?Tz&PHVf4s3}C%-v94FF@9be_85eA<+NZxAyr%P}9sauJjttP-r90&JX>LR5AS#4* zXsF~FJJ(V-J@D-k(KxBu3%s82eA4a|)MAZ@a7aE3Gj}(;RqZcpwR1AB)&`S-KQADy zJNS^N7kZa-GL(LP=jEJ_gAVWjX!rO(t|No4RxP&?;^1cdGF$wk0m+5vn!e&XLA1`)2047oL{vuL^qnu)9{N zM_%6hnY&hn(HUQ5SQIm%-?Om6_TKEo)0KB7N<9<9^nGbNxh!gL1^Jw5G#&lR(aW*j z9XC%y_m}^em{ALq1D1d>_zY%$cm~SDqq4zPu*rg}D&s^CFUQ*;<{^##>(v}OBRe;0 z1}x;)_tqWZE#9NKxL+lE#RbFSg1GH*z#G^GE3MyiE-&&}s)z zzI6%$r#um@rFFYygCNH-(K1If~Nm(M5CR<$s>h}D5=sYzU68&rZ#zToTE)8e;Q-TLAO zD67-&BGzGrZ>v-;w(gl)MTwD`Aobj^;^wnlSdQP+!Xx9Rn$0KnLlg+wsuiI?N@au` zooxB*4aKgzW(?lW(Hq3JTBmg?6EB-i_9(;C18mwKNUvahuB-h1rp0Oh9|M=s?r-k) z6+d;q8O%s}QhMx3gz=-8_icUQFx2)$eX`;OFm-l=~q&D zX+#8(Q&K;|Z>$>Fu-Bh^v=Z-oA$f<@Y!IOTv1rkAEIa^+cDY&Q_MyE$kcR$qL*-tg z!d1-zy1UVr@F!V;@<+?M1Cv}w4{g&ksK!^k8F!3>U5C|u*zu_SXXL*K->)#2Z>^;u z>QMUub;Q>gc_UN|f~ni3z)Flhbbfl2M9xAV_t6%^w)eQKK-MpC#C=W{6lCpW6o@+f zkv6W0XkgH#>Svp?HIu^8n=VusXO zHTRM+pFaTE!om7TI(VS!uu~gtf*JsHLv+u~tVAN!vY{$6Cx#joMH^!=?9>`{_if6! z+77gVWM#z()P(ySEJXA00o>zu7tEC41icOm*0`a1t!y5}9@(Fu(JLp7HD*R>JVS_% z#~x)4sz+c&8L>gy-Pan`L_6lde2u`tFpUyOU-H%QMtzY%>@bVbAE7D=jZJ3~P>szJ zm{QBv3u6YD!2p#ifzcir>Tm@zoj+tGF{p4xHu8q>AxT9w8~zZCv>ZXpFZhuYtqqdoDjYzHmX4_ql=i_zEZpBg1;W#KpZB-7-!vl%ON65nNd zxC}y~Il5Mw%7v~%FSfzNqB5^ETaH@YvNsIqRkhyV#+hg|FhQeKcrCU@q|quc*;MMS zQjQR*r&v&fR4Q;H?9MxIM?iA83dkkS@b3EXg)qwQN1n=UL=m$8%IiD8lwQ|{mv`Mo z^U(XjyA-hjL8lSDYoaa_!vtlxUP9D5Qa!H>EVRBb8pCWtn<GT?~83IzxBHJIR;rWgWf3Ve4tR-j&un z4szG0Hb>kN;$jxq`{G?UyhPdF3ELn4!L1xMd&TbHyyJ$iNXVS0i4qac-f&7MOxpzt zZSQyM0`_>o&osev_g{qEhOt?f;0p8{?M1*;_fWu~f@{Utoea}w17y1KkEhw)KqP33 zIo}si0nkLpzmPzt*jEU_U8Pqu-YNFykj=qBjd}3%2ko4jX51h_yrQ1+YvMY(6aWWgn2XE#0^)d^<_E0e#Sn!bHWeZJ^3p6=7;qI%)ED zyVo^2O42uPhkW&zqqLc;VN@CrGUAlbKl)#^84Ldmwo~-xb(|(>zJm-1eCJXHk74ZN;P4 z9=f6}M&39QN%ysfmXXw zN`G9oSB3&>%Wv=BSuA>VyVIFKYnu?AuD|2NHXGS(&sNU6>Iy;k+$-IQvZnjPpS~y^ zrA4b{innbyDjN;+`#{!a>()D_vom-54nxoqu{sVDV(Dj$(Xmjc*HcQQ#;c*L5bW4` z#E3Y3kzOOVH$ZPKsalwOqr@BCy6{3bvlH@_wgK5YY=^rXVg?%=NNW zTg!sR9S!(wba{P{-I?tqQk#aN_BZI+&;}&tR7rS6i>P<)4vlBfA`f0|xBPXAj|_dP z*A{Kmx^P(R+KUt6zYG_4lg(AoRBQFQVQ4Q_Y5bID?eER6`!j$fGoECJsTeZQU zm{t5jFdADmX^7iX^^HHO*sPg?(`e?4k3}3O`tXFsdB=&smZ&n!{<0`1Iku{eTy8iL z&zSV@I$t}9LRr{U645Wp33LmnSP;P^_gChw$IJ*Kqy#>WS`2|Hn5e$=YbcevPiLiU zPBf~iQ26n9=AU4LM~yD~K5BzvNeKi;9jy^$jI}L+4G{vYb%m(sGR8PXlKKKY1a^Y= z%ohY3sTRyhizz-a_fXIH#M~gVMA0qazRN;cJ;T+VNEoF9%Ki=^Ta~v1&&Q~ZBMXj_O z50pW@E~q8Cr0S=#x0&Ivz>crP6DZUUE9Y)Q()$-zl=X5gzHyH}hB>9&e(w80mi-p` z8!b|F)Q&wicSrA1-d2Bh_gsUXsZbZt5?@@>gzRy{Wj!|Ats@HD<4aBs z+7pO@!}r;flD8zq6Bh&aNUNurf;k9m#BjX_&-v#=>R&>V(si?s*Z$pqcX{n}1iS=f zfLF20)$aiP!*{yzpYV*5x$V5GIT|alQN*W%y51`G*&+_AZb+E8Mv3r(Z&t5Zsz8fIF-B`kGp3VK(dJsyJy;Nr%1#O-u~T`&=V*BMDgo<=Jd%b z!rJ7ojF+wLc_y1}pzqovYNU2+DPKQF%w@nnm0cN{3=v*9;k@+_P5=(bgdUHKjXdNt1Ttir+}>m!OCJHLk29)6XcbO71FXx)5^X9rl;C zv3Xaf=0D;h&2}sOLWjbpM+T9lE^dX!zEHv$jZL?0d+ZhwzOf z3P_tXOC|BN-uiD-!g^*L-AT@OCi4tGmQQD3si|e-9G8}dQSjNJQu?ai_^d=YKyV6usm(!!3&GfoH`>EE1%(=RmhqP1uIAhSw`^lY z*AYiLRn`)V`p8+EMy%-4L@Bcmm&8r;b8eLpQzuPB1dXF>$f=~bIex*fP}sAkWF>Bt z|Mm1EDK>BJpFsa*jh6Q}|D9{}_#dOFT@e1)%#6kH3|D!$7K9@ED>FkqY&Ja|`gdl= z4MEfWE>yfqosd#+=!1Kfi!%>mZ=VRrOkOy0Y~?tPF&&UxZMN8bswgcp53lUy)$V=! z1=GQ_aiiJbROXS5q>$ZgpR4Qv1>p!(TzhsGpcdyv{UB;gpoJYhPhJjE@x&S&+QUk=;xU-o}YWi zuk2Mt(q`U%@d1Yb=1Ar@e7&ELQl{kVTEyxnZYf>#YbJ?lBoHv4ca?jUUt z_UCgixhE6lb}zt&(RHtn`-5>A#G0*3W`n=+yV>aFF2`kvT$arScj9&`eE0Jy&}`IC zW!ivdBb#P$#vzBkY&N7#V<9kp)OOAt&}`(>N<+xv)o7=%WwTMJ`3*E1?u}jS5{=4E zQmMKNXf^_t%*Kn|fnqQ&gB$_IWpv3ZVPIT_ZtQYg#{a78Ui_iV_c(yh&D>2h48|n) z%ebu>*~M8- z8mG50l0&d*lk={KY0A9amis!h@iqnl9J!8hgowxY%rX($_}wCS?V>{qtde@ep5D>v z#O9^I>i60tvR<5TQ=QzoTls%xLkNxq2ONywbdMYms6u0crStM@@61LLeF7Vq&62XcM!R2i%Jc+w;Th4&r0(zP@{QXg{e4`ze&muAC} zi0Ct4R6(!wo(Hnii3q>!AR;dyn?V$!vsK9q3H)d1HLQu{5jIPtN*lK-G>0vnErfsg zw(zG)W2=vo7Pap8P7F>~^GM=vN<$q~QuJPFl*mj7A1DouLBu0%*Tx`ej3^(mtKLxDREo7zGvDY*VA4+HO1`8w+k+78w^qB-S$mu zJ?n)l=%!n@UdeSOzS>uOHILFeL()8ZuqU_0Rw=8a>D@rtZu{lc$->9mnk?)Md|a=e8;oTXED%%4!T|wi(0B^WdqiC78U!nevopV7TW;bc~Hz(THs=NWaYP* z{mEg8sM&7p4pwVT2{6tK1g5f^v?e6A+j=hG@gmUhI2S-x(Eb5<8 z8a(QA%cZI7t>t|BCk~gQ2d1jU3Nn$Gm-%L5JzSOhZO*d?Hs|;o4I;3^Ke95*S}|B( zv|tT_lT5<5@{Tes*J2yE7F-BS#5yV@qostE8aX%grhYF!N4#nEw&l}Vt`2FWO)wiv ztWf*b7j)cV>a(`#0F6%GUZ*8wVurx-v;RqrnNpM($^)KbI<89)3^3ZvB52{j{KuF) z9D-qO2cZ%?ilwSCbRO1;fEo0SiqiDU5*khI%ahvr8;gH^w*NKDz`+tOib)n87#%zV zi{(QPrU{GQSI$6Vlj`dMkSIoC73qz9@DKwlOZ5B!@DS7gWE4p078x*dY5hS_kIW4W zY%EQqaM7CcB%e$cjVUq>rTGA4NiuRwm|^g#x*WUP0)i))XDrF4S}oC@z1?^I@sV#h zl`uqGzS%a(=OZacxax(keNFI$sYo&rD)@}MX4iy+zyzs>&bp3sm$btv`0MPKT?s~~ z_v5V@v2WZ?-Bn`lGFWyiUxy=ajsJ49mOJ<0a1HqiY@$uhr)3x&%ua%K>ouLcw8oK0 zmcKoV4et6S9o0>`+WGm_Tj7i4tLHbPvwXgYitG+}`cqZWxkE`n7$0R_SGp9G3$a{$ z^`2np!EL?r%wSmvb?P+6wwRAOd1or*0GrYyqR%pGjm?@BH=*QkgZSWLcH*d*mIBn0 zT)vbdfSxd5+LFN+!XQ#x$rRF?-%EmgBTYfM0ug>DV3J4IZvrkMlt%4%>@PDWd9ta| z_KF5(W|~-Hfw*No2dHS8Jd99zc#f&+b)2up_Al7i!0us~A5Nt%d-vD17m!|4wIjIF z07SN-O$(v=`e-CCN@<0v4qvaEN{OT#WgSEKW`tKZSnZj^h!}-9_+lbmpi4m>;Kpjx zcw>KbPk37cdzP*C;zER^Pm0hU?T5N$TR{?8mBbLp{A##yXRqkISH(f#i2a#M9IKDdc8VNHc1WrMPKI%0gz#Pp?$ zI(@-JKu?PM&u}zW2srr9Q^=!xuUwx-_N^j#%46BGQVcauPcpW^oP`$rCbaeu|50<#1&G?SPhf8;%Iml{_(qt z3t>a8XDz^nf1$6KVZtV03t@`I6%-Ii6wWkyioGR7L>!Y?q!`fZ0ioCn9oU1J7Y9bq zA;i{13+4T+$QszRPFVO%w}b}TJ4rx}amXbkml!2r5_&!IoQB($)s+#k4^R-J)Xwwq+28rACO9xeFy1KGC@}U-im$5U>5GB&U2ok7sr~pr zxqJTrEL;+Hvu(l}e+^lKz`|W=Wnb3&uG`{uw_2`y+LdI7qvwrr;0y0p})i7ZuFYuN#U^bT4up zXX=k%vOH=xYBj~h$0RT9nBYBbQSMke-ClaV*s3Sd=D72{CYuvZ3zT|*vzSpO<@rY}>u_euyJhsqZi+sR#uqZK3^RJ2V3uarV-;Z+yygDzy)2p$| MnB-br!Nq6)1#SF!b^rhX diff --git a/session/assets/qr.html b/session/assets/qr.html deleted file mode 100644 index 4b235b1e..00000000 --- a/session/assets/qr.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - Whatsbot - - -

Scan the QR.

-
- QrCode -
-

- If you scaned it successfully, please go back on your terminal and copy the - JSON -

- -

- WhatsBot -

- - - - - diff --git a/session/genToken.js b/session/genToken.js index c0f6e185..999bfc15 100644 --- a/session/genToken.js +++ b/session/genToken.js @@ -1,10 +1,11 @@ -const { Client, LegacySessionAuth } = require("whatsapp-web.js"); +const { Client, LocalAuth } = require("whatsapp-web.js"); const qrcode = require("qrcode-terminal"); -const logger = require("../logger"); +const { write, clean } = require("./manage"); +clean(); const client = new Client({ puppeteer: { headless: true, args: ["--no-sandbox"] }, - authStrategy: new LegacySessionAuth(), + authStrategy: new LocalAuth({ clientId: "whatsbot" }), }); client.initialize(); @@ -13,26 +14,13 @@ client.on("qr", (qr) => { qrcode.generate(qr, { small: true }); }); -var token = ""; - -client.on("authenticated", (session) => { - token = session; -}); - -client.on("ready", async () => { - // console.log(JSON.stringify(token)); - - await logger( - client, - `Here is your session token. Please keep is as a secret. You can delete the file if you don't need it.\n\n*Generated at:* ${new Date()}` - ); - await logger(client, JSON.stringify(token)); - - console.log( - "\n\nPlease open your Whatsapp and see your chat. Your session token will be saved there." - ); - - setTimeout(() => { +client.on("ready", () => { + client.destroy(); + console.log("Please wait..."); + // wait because filesystem is busy + setTimeout(async () => { + console.log("Session has been created"); + await write(); process.exit(); - }, 5000); + }, 3000); }); diff --git a/session/genTokenLite.js b/session/genTokenLite.js deleted file mode 100644 index 433301d5..00000000 --- a/session/genTokenLite.js +++ /dev/null @@ -1,60 +0,0 @@ -const { Client, LegacySessionAuth } = require("whatsapp-web.js"); -var QRCode = require("qrcode-svg"); -const fs = require("fs"); -const app = require("express")(); -const logger = require("../logger"); - -const client = new Client({ - puppeteer: { headless: true, args: ["--no-sandbox"] }, - authStrategy: new LegacySessionAuth(), -}); -client.initialize(); - -app.get("/", (req, res) => { - res.sendFile(`${__dirname}/assets/qr.html`); -}); - -app.get("/qr.svg", (req, res) => { - res.setHeader("Cache-Control", "no-store, max-age=0"); - try { - fs.readFileSync(`${__dirname}/assets/qr.svg`, "utf8"); - res.sendFile(`${__dirname}/assets/qr.svg`); - } catch (error) { - res.sendFile(`${__dirname}/assets/loading.gif`); - } -}); - -var token = ""; - -app.listen(8000, () => { - console.log( - "Please make your Port 8000 public and open that in your browser" - ); - client.on("qr", (qr) => { - console.log("QR Refreshed"); - var svg = new QRCode(qr).svg(); - fs.writeFileSync(`${__dirname}/assets/qr.svg`, svg); - }); - - client.on("authenticated", (session) => { - token = session; - }); - - client.on("ready", async () => { - // console.log(JSON.stringify(token)); - - await logger( - client, - `Here is your session token. Please keep is as a secret. You can delete the file if you don't need it.\n\n*Generated at:* ${new Date()}` - ); - await logger(client, JSON.stringify(token)); - - console.log( - "\n\nPlease open your Whatsapp and see your chat. Your session token will be saved there." - ); - - setTimeout(() => { - process.exit(); - }, 5000); - }); -}); diff --git a/session/manage.js b/session/manage.js new file mode 100644 index 00000000..426f9db3 --- /dev/null +++ b/session/manage.js @@ -0,0 +1,46 @@ +const fs = require("fs"); +const AdmZip = require("adm-zip"); + +let base = `${__dirname}/../.wwebjs_auth/`; + +let excludedDir = [ + "session-whatsbot/Default/Cache", + "session-whatsbot/Default/Code Cache", + "session-whatsbot/Default/Code Storage", + "session-whatsbot/Default/blob_storage", + "session-whatsbot/Default/Service Worker", +]; + +module.exports = { + clean: function clean() { + try { + // delete dir if exists + if (fs.existsSync(`${__dirname}/../.wwebjs_auth`)) { + fs.rmSync(`${__dirname}/../.wwebjs_auth`, { recursive: true }); + console.log("Session directory cleaned"); + } + } catch (_) {} + }, + write: async function write() { + excludedDir.forEach((dir) => { + try { + fs.rmSync(`${base}${dir}/`, { recursive: true }); + } catch (_) {} + }); + const zip = new AdmZip(); + zip.addLocalFolder(base); + await zip.writeZipPromise(`${__dirname}/../session.zip`); + }, + replicate: function replicate() { + try { + let zipped = fs.readFileSync(`${__dirname}/../session.zip`); + let unzip = new AdmZip(zipped); + unzip.extractAllToAsync(base, true); + console.log("Session files replicated"); + } catch (error) { + throw new Error( + `Session file not found or corrupted. ${error.toString()}` + ); + } + }, +}; diff --git a/startProcess.js b/startProcess.js new file mode 100644 index 00000000..c61032a6 --- /dev/null +++ b/startProcess.js @@ -0,0 +1,11 @@ +const { replicate, clean } = require("./session/manage"); + +try { + clean(); + replicate(); + setTimeout(() => { + require("./main"); + }, 2000); +} catch (error) { + console.error(error?.message); +} From 7a1da3af9adf95c1a2647c702ab511ce854a8c44 Mon Sep 17 00:00:00 2001 From: tuhinpal Date: Sun, 8 May 2022 23:23:41 +0530 Subject: [PATCH 2/3] Secure session --- .gitignore | 8 ++++- README.md | 4 +-- app.json | 8 +++++ config.js | 1 + example.env | 1 + examples/example.env.md | 9 ++++-- package.json | 3 +- session/genToken.js | 23 ++++++++++++-- session/manage.js | 67 +++++++++++++++++++++++++++++++++++++---- startProcess.js | 22 ++++++++------ 10 files changed, 122 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 31ddb5ed..264a2623 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,10 @@ public/* !public/readme.txt session/assets/qr.svg .wwebjs_auth/* -session.zip \ No newline at end of file +.wwebjs_auth +session.zip +session.txt +session-output/* +session-output +session +session.secure \ No newline at end of file diff --git a/README.md b/README.md index 98e4a327..20d8fbb1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@

- Version
Wiki @@ -64,7 +64,7 @@ ### Deploy : [![Deploy with Heroku](https://www.herokucdn.com/deploy/button.svg "Deploy with Heroku")](https://heroku.com/deploy?template=https://github.com/tuhinpal/WhatsBot "Deploy with Heroku")
-[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2Ftuhinpal%2FWhatsBot&plugins=mongodb&envs=SESSION%2CPMPERMIT_ENABLED%2CDEFAULT_TR_LANG%2CENABLE_DELETE_ALERT%2COCR_SPACE_API_KEY&optionalEnvs=OCR_SPACE_API_KEY&SESSIONDesc=Puppeteer+Session.+Ge+it+by+running+genToken.js&PMPERMIT_ENABLEDDesc=Enable+Pmpermit+write+true+or+false+only&DEFAULT_TR_LANGDesc=Default+Translation+Language&ENABLE_DELETE_ALERTDesc=If+true+and+if+someone+delete+message+in+PM%2C+Bot+will+send+the+deleted+message+in+that+chat+%28Exclude+Media%29&OCR_SPACE_API_KEYDesc=Get+it+from+https%3A%2F%2Focr.space%2FOCRAPI&PMPERMIT_ENABLEDDefault=true&DEFAULT_TR_LANGDefault=en&referralCode=tuhin) +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/RTyLts?referralCode=tuhin) ### Commands : diff --git a/app.json b/app.json index 1ade1bbf..47af7aff 100644 --- a/app.json +++ b/app.json @@ -6,6 +6,14 @@ "keywords": ["whatsbot", "whatsapp-bot", "whatsapp"], "stack": "container", "env": { + "SESSION_KEY": { + "description": "Session encryption password", + "value": "" + }, + "SESSION_URL": { + "description": "session.secure public url (It is safe because it is encrypted, But still if you want maybe you can create some sort of authorization stuff)", + "value": "" + }, "PMPERMIT_ENABLED": { "description": "Enable Pmpermit write true or false only", "value": "true" diff --git a/config.js b/config.js index 5ef826da..0ee72c3f 100644 --- a/config.js +++ b/config.js @@ -3,6 +3,7 @@ const fs = require("fs"); require("dotenv").config(); module.exports = { + session_key: process.env.SESSION_KEY, pmpermit_enabled: process.env.PMPERMIT_ENABLED || "true", mongodb_url: process.env.MONGODB_URL || process.env.MONGO_URL || "", default_tr_lang: process.env.DEFAULT_TR_LANG || "en", diff --git a/example.env b/example.env index ffe1c0bd..2a58c29d 100644 --- a/example.env +++ b/example.env @@ -1,3 +1,4 @@ +SESSION_KEY="tuhin" PMPERMIT_ENABLED = 'true' MONGODB_URL = '' DEFAULT_TR_LANG = 'en' diff --git a/examples/example.env.md b/examples/example.env.md index 503b8f01..c7b3f1d3 100644 --- a/examples/example.env.md +++ b/examples/example.env.md @@ -5,7 +5,8 @@ The `.env` file is used to initialize all enviroment variables in the developmen Create the `.env` file in the root of your app and add your variables and values to it. These are all the variables that are needed by WhatsBot. Description about these can be found in [app.json](./app.json). ```env -SESSION = "" +SESSION_KEY="" +SESSION_URL="" PMPERMIT_ENABLED = "" MONGODB_URL = "" YT_DATA_API_KEY = "" @@ -19,13 +20,15 @@ It is not mandatory to add all the variables in the `.env` file. Most of these h At the bare minimum, you need to initialize atleast the following variables to make it work in your local environment. ```env -SESSION = "" +SESSION_KEY = "" MONGODB_URL = "" YT_DATA_API_KEY = "" OCR_SPACE_API_KEY = "" ``` -- SESSION : Puppeteer Session. Get it by running genToken.js. As getToken.js creates a session.json file, this might not be necessary in a local environment as this variable has a fallback to the session.json file. It is mentioned here as it is the most inportant information needed by the bot to work. +- SESSION_KEY : Your `session.secure` encryption key. + +- SESSION_URL : You can retrieve your session from an public hosted endpoint, This is just a file and this is secured with `SESSION_KEY`. Don't put it if you are using VPS or your Local machine. - YT_DATA_API_KEY : Youtube DATA API key, grab it from /cloud.google.com>. diff --git a/package.json b/package.json index 614d0ff5..c5b23096 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "whatsbot", - "version": "2.1.1", + "version": "3.0.0", "description": "Plugable U***b*t for WhatsApp", "main": "main.js", "scripts": { @@ -23,6 +23,7 @@ "dependencies": { "@iamtraction/google-translate": "^1.1.2", "adm-zip": "^0.5.9", + "aes-encrypt-stream": "^0.2.0", "axios": "^0.21.0", "child_process": "^1.0.2", "dotenv": "^10.0.0", diff --git a/session/genToken.js b/session/genToken.js index 999bfc15..4e86241c 100644 --- a/session/genToken.js +++ b/session/genToken.js @@ -1,13 +1,32 @@ const { Client, LocalAuth } = require("whatsapp-web.js"); const qrcode = require("qrcode-terminal"); const { write, clean } = require("./manage"); +const readline = require("readline"); clean(); + const client = new Client({ puppeteer: { headless: true, args: ["--no-sandbox"] }, authStrategy: new LocalAuth({ clientId: "whatsbot" }), }); -client.initialize(); + +let password = null; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +rl.question( + "Enter password to encrypt session (You need to put this in ENV): ", + (answer) => { + password = answer; + console.log("Password set to:", password); + console.log("Generating QR Code..."); + rl.close(); + client.initialize(); + } +); client.on("qr", (qr) => { console.log(`Scan this QR Code and copy the JSON\n`); @@ -20,7 +39,7 @@ client.on("ready", () => { // wait because filesystem is busy setTimeout(async () => { console.log("Session has been created"); - await write(); + await write(password); process.exit(); }, 3000); }); diff --git a/session/manage.js b/session/manage.js index 426f9db3..0bfd0f7e 100644 --- a/session/manage.js +++ b/session/manage.js @@ -1,5 +1,14 @@ const fs = require("fs"); const AdmZip = require("adm-zip"); +const { + createEncryptStream, + setPassword, + createDecryptStream, +} = require("aes-encrypt-stream"); +const crypto = require("crypto"); +const config = require("../config"); +const axios = require("axios"); +require("dotenv").config(); let base = `${__dirname}/../.wwebjs_auth/`; @@ -21,7 +30,7 @@ module.exports = { } } catch (_) {} }, - write: async function write() { + write: async function write(password) { excludedDir.forEach((dir) => { try { fs.rmSync(`${base}${dir}/`, { recursive: true }); @@ -29,18 +38,64 @@ module.exports = { }); const zip = new AdmZip(); zip.addLocalFolder(base); - await zip.writeZipPromise(`${__dirname}/../session.zip`); + await zip.writeZipPromise(`${__dirname}/temp.zip`); + setPassword(getCipherKey(password)); + await new Promise((resolve) => { + createEncryptStream(fs.createReadStream(`${__dirname}/temp.zip`)) + .pipe(fs.createWriteStream(`${__dirname}/../session.secure`)) + .on("finish", () => { + resolve(); + }); + }); + fs.unlinkSync(`${__dirname}/temp.zip`); }, - replicate: function replicate() { + replicate: async function replicate() { try { - let zipped = fs.readFileSync(`${__dirname}/../session.zip`); - let unzip = new AdmZip(zipped); + setPassword(getCipherKey(config.session_key)); + await new Promise((resolve) => { + fs.createReadStream(`${__dirname}/../session.secure`) + .pipe( + createDecryptStream(fs.createWriteStream(`${__dirname}/temp.zip`)) + ) + .on("finish", () => { + resolve(); + }); + }); + + let unzip = new AdmZip(fs.readFileSync(`${__dirname}/temp.zip`)); unzip.extractAllToAsync(base, true); console.log("Session files replicated"); } catch (error) { throw new Error( - `Session file not found or corrupted. ${error.toString()}` + `Session file not found, corrupted or password not matched. ${error.toString()}` + ); + } finally { + try { + fs.unlinkSync(`${__dirname}/temp.zip`); + } catch (_) {} + } + }, + fetchSession: async function fetchSession() { + try { + if (process.env.SESSION_URL) { + let response = await axios.get(process.env.SESSION_URL, { + responseType: "arraybuffer", + }); + fs.writeFileSync(`${__dirname}/../session.secure`, response.data, { + encoding: "binary", + }); + console.log("Session file fetched from", process.env.SESSION_URL); + } else { + console.log("Using local session"); + } + } catch (error) { + throw new Error( + `Session fetching failed. If you are using Local machine or VPS please remove 'SESSION_URL' from Enviroment Variable. ${error.toString()}` ); } }, }; + +function getCipherKey(password) { + return crypto.createHash("sha256").update(password).digest(); +} diff --git a/startProcess.js b/startProcess.js index c61032a6..261830a2 100644 --- a/startProcess.js +++ b/startProcess.js @@ -1,11 +1,15 @@ -const { replicate, clean } = require("./session/manage"); +const { replicate, clean, fetchSession } = require("./session/manage"); -try { - clean(); - replicate(); - setTimeout(() => { - require("./main"); - }, 2000); -} catch (error) { - console.error(error?.message); +async function main() { + try { + clean(); + await fetchSession(); + await replicate(); + setTimeout(() => { + require("./main"); + }, 2000); + } catch (error) { + console.error(error?.message); + } } +main(); From 66b5ea7d2f003eb6c568fcb73f490b0e2cdd7ed1 Mon Sep 17 00:00:00 2001 From: tuhinpal Date: Mon, 9 May 2022 00:10:43 +0530 Subject: [PATCH 3/3] genTokenWithDownload --- .gitignore | 2 -- package.json | 3 +- session/genTokenWithDownload.js | 54 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 session/genTokenWithDownload.js diff --git a/.gitignore b/.gitignore index 264a2623..6d8f29bf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,12 +16,10 @@ cache/* !cache/readme.txt public/* !public/readme.txt -session/assets/qr.svg .wwebjs_auth/* .wwebjs_auth session.zip session.txt session-output/* session-output -session session.secure \ No newline at end of file diff --git a/package.json b/package.json index c5b23096..c83c8950 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "main.js", "scripts": { "start": "node startProcess.js", - "gentoken": "node session/genToken.js" + "gentoken": "node session/genToken.js", + "gentokenwithdownload": "node session/genTokenWithDownload.js" }, "repository": { "type": "git", diff --git a/session/genTokenWithDownload.js b/session/genTokenWithDownload.js new file mode 100644 index 00000000..03c4a408 --- /dev/null +++ b/session/genTokenWithDownload.js @@ -0,0 +1,54 @@ +const { Client, LocalAuth } = require("whatsapp-web.js"); +const qrcode = require("qrcode-terminal"); +const { write, clean } = require("./manage"); +const readline = require("readline"); +const app = require("express")(); + +clean(); + +const client = new Client({ + puppeteer: { headless: true, args: ["--no-sandbox"] }, + authStrategy: new LocalAuth({ clientId: "whatsbot" }), +}); + +let password = null; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +rl.question( + "Enter password to encrypt session (You need to put this in ENV): ", + (answer) => { + password = answer; + console.log("Password set to:", password); + console.log("Generating QR Code..."); + rl.close(); + client.initialize(); + } +); + +client.on("qr", (qr) => { + console.log(`Scan this QR Code and copy the JSON\n`); + qrcode.generate(qr, { small: true }); +}); + +client.on("ready", () => { + client.destroy(); + console.log("Please wait..."); + // wait because filesystem is busy + setTimeout(async () => { + console.log("Session has been created"); + await write(password); + app.listen(8080, () => { + console.log( + "Go to http://{app_url}/session.secure to download the session" + ); + }); + }, 3000); +}); + +app.get("/session.secure", (req, res) => { + res.download("./session.secure"); +});