From 123c8f7823c199d5c28753c6ca33a2304904f141 Mon Sep 17 00:00:00 2001 From: zefie Date: Thu, 10 Feb 2022 20:49:48 -0500 Subject: [PATCH] even more mail stuff --- .../wtv-mail/ROMCache/FileImage.gif | Bin 0 -> 843 bytes .../wtv-mail/ROMCache/FileMovie.gif | Bin 0 -> 967 bytes .../wtv-mail/ROMCache/FilePackage.gif | Bin 0 -> 1090 bytes .../wtv-mail/ROMCache/FileSound.gif | Bin 0 -> 1520 bytes .../wtv-mail/ROMCache/FileText.gif | Bin 0 -> 763 bytes .../wtv-mail/ROMCache/PanelEdge.gif | Bin 0 -> 66 bytes .../wtv-mail/ROMCache/PaperTop.gif | Bin 1104 -> 1872 bytes .../wtv-mail/ROMCache/PaperTopFlat.gif | Bin 0 -> 185 bytes .../wtv-mail/ROMCache/RemoveButton.gif | Bin 0 -> 484 bytes .../wtv-mail/content/images/RemoveButton.gif | Bin 0 -> 484 bytes .../ServiceVault/wtv-mail/get-attachment.js | 22 + .../ServiceVault/wtv-mail/get-signature.js | 19 + .../ServiceVault/wtv-mail/readmail.js | 30 +- .../ServiceVault/wtv-mail/sendmail.js | 824 ++++++++++-------- zefie_wtvp_minisrv/WTVClientSessionData.js | 26 +- zefie_wtvp_minisrv/WTVMail.js | 19 +- zefie_wtvp_minisrv/WTVShared.js | 46 + zefie_wtvp_minisrv/app.js | 24 +- zefie_wtvp_minisrv/package-lock.json | 4 +- zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj | 6 + 20 files changed, 601 insertions(+), 419 deletions(-) create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileImage.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileMovie.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FilePackage.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileSound.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileText.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PanelEdge.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTopFlat.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/RemoveButton.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/content/images/RemoveButton.gif create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-attachment.js create mode 100644 zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-signature.js diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileImage.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileImage.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff804edb08965db6a029079e3ae72b7e0b805258 GIT binary patch literal 843 zcmZ?wbhEHb)MGGVSjqqbxeXm|vPrT$n(6{(LhRz@of9W7TDg4Vw!V2wYWk*nXvTA~ z@QH9qOG-*+*0lD_UD7ps5ep-Wp@_@0C95jCrf0_#>^G#rY~D__3G938S}xmQJGNu$->CMz{j8iG8g102ey9>?FAk>QvD~M z7%Dp{I9$juaakI`cjIu{;g>~1oE$1nax;xt7khZ|MsAK;C$6LBerE2T^#4CKL>RKd zBN>F-+B-VCI+fVi#3nSlDiw1w@XVMwYxbPkO5%(Q87H|Yr7Bm-R?F4abBT)fO%M~` zx?myy&YhBbB$s#{IC$vrk)ul${DTy7^CP3<;uDjXuUx&~N$HFT1Jm7m_a8jGFQHVw zf$ch3>JYVJX&(6G= zAw$Az%ZiJO-CXBXPw`h}UHE@x ztx|HY>L;$tS~~mGk>?kTxBM!eG?QiSje{R+o(B6CGDw)T$m{R3`T6n7w$=%r`AnEUGx>kOQN5 zTF1jSsjRXSiIIx}JlGjTJslo(sx9ky)TQaA(4@is^z&`+s}DpkBz{*}7GbBNDlX&j zns>@#NA{PGx}~;jrYBFRzR9$BVy~=aXMc~G^d86Lme<>YB5 Tp&e~EXXR{rnU>o`$9~Y;W z8Lb$u8Lycbm7NI)38<&4AEXNxrZm7Gt*sRq$H%P>0T==h5E2p^od^gY0K%uf1^^ER z;N1WP1r+841m*=36BQNA0?*RZpx)u)+@=8g{O0HW>)O2w5D(fsYY6o5+m~-)zkll3 zxr6sC+BAd-9WtaLP9wT>5d|_MXiyr)j2iwM@)P$_-MS6$;Fa`r(jh*M`)~qiNg-fN zg7OX`w2)C}zHi|)DqXq|o4up}R5G1Pb*a>a2pdR)20=go2NgCvnK%n3$C{o2kp|^?z&volqQC$^jRs_TRg5u{X7HCY-Z0vzFRFNO zil?4Fx`_aoR9eg|7@z{`2Oeqk=+0Q literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FilePackage.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FilePackage.gif new file mode 100644 index 0000000000000000000000000000000000000000..55e1d1fd375fde0d9457759e863c39b90019af97 GIT binary patch literal 1090 zcmV-I1ikx5Nk%w1VJ-kP0E7Sll6qPm78AOmgtD1@U`{+eEg*|=Qd>$oP(Uv=B^wkE z4jCC4O*<<%C>=>RCny~kLo+1Eu96B03Baa`riWv0T0>b!HB&(^7Znw)k#M-3ew=|{ zRYWtGd{-D47y<$UA^8LW000XBEC2ui04@MD000I4;3AG>X`X1Ru59bRaC~~SC*NX? z?HK;r9^Rq=;S>TpUy6r$a1MY>Mj*&+3<;!C#AG}Ho53V9j#LK&D<`0ZF(C*809~$6 zsOWS$185+7OBfyr5Dap36J=y%cX$GMXc>Eb0SbU5K@f)n0*VozjEQ%RkfnQ950xey z2B5B>ilU^Cd6JTxkyZw&3JW#}02LdruCk7}wR=*_c~=fuA`Sxp0CL2OiB#IOk;+nH z83YUk2?-7gHXODa)c~)JjojSKVgLsT4GlyLYCLCK|^=q z9Xfb_e!;+z&FGaA+XWZwg_L#gG5#PQ1_4+Q!A7O&M}dAD5a575w*}AuJ`gy-Pk{wm z@PvCb$>%`;3{22nclm9Qp8?~PQ%-6gUcdl>mLX+9O9=|bAOsPts9#hr<`)$MGseb% z12*1hnQkMxRKaJyoLGR0#AP(3kwy~G)nqk#aY2qFx`&#Ne+9`RgO-i9v*Ea-fo2v^0}TO45I_NP^~q(RfmYDfLzo`ASDjKm(8H?>NFXal zZQ`1rNpOPMD+dUOXyA1R!YuH?qQ6xlfdUBxdTUN=ed!^lmK8Yd0R;#v!3VyTaH6qj z6^U!EmBv IEkXzYI}UoWF8}}l literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileSound.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileSound.gif new file mode 100644 index 0000000000000000000000000000000000000000..199fcd98a9fab354d946d6f60766df7108409710 GIT binary patch literal 1520 zcmVrjG#R_Qj{k?6B8H<5*ivE zA~Q>D4;CRIGedAEMY&gRVH7EHhMB}hTofKG2@MpKo1jc9EE+$G(P}k1I-kW=WTxW;BoYXUP%059 zB?U?3M2{%0}TxztE(WduNeXd4r?7LLn|KyKRPA;bU;2UJ}Wf_a4uFoGzd1Tew~BoIIXQnz#< zVGa{!09#vcy%2y@JpSom04)u0)yWYAsKCPsD5j_)iaE^U06-`3HNGDX^f91$`~U3=GfAatA{u z*k(jGI_$7Q4<7Jy7hZa`!=+yuNI(w<3v7eW3e)Uhp$8A>U=BKQ!cg7=S!Bb(1$ve? zLI{ZAnF9t#+N8myJz($x4lOMzV`)#kV8W1*5{ZMEpc+Kg6jV&a1|+G%F#-*r^&^^S zIGE66tRI|Kg%uDXil_v_*3hX_sNR;44hyKJffguaAj7o8%_4yZEe*6B9175&P#u)X z@Y_fmw9tYX{^DS}28ssd;H?fWT#La5(*ai>bO3_jIh=r> z&fUEo)l@Xx;J`dFbVa}i5L6J+2nw7+01qIX(141ar)VMKt9C9I6_ug3uJ&~Fm7F>ix9oA z0GpD=A9IWj7JvzjG(v`UWZN7xD#Qyah!6k^2K+VU0t9#uKn`6N@Z~e*IKZZ0=@Z!y zUeJpj%wjfnfzvwNk-snLfK5G6l)sL!f?k9`95qNFq4dJQz65|x2QY!ul2wEpxS$`5 z@qk?hm5w+uV@@@QM-N1pzKA^`2R}f}pK9Nk%w1VJ-kP0E7Sl0001)r>!h8G$}7Jb%&3jt+G>IV}FpCYI=aSz{F>E zeU_!G85tRho1%u7o{*rYj-I73HaIRcHezsgc#4vgqpFgjsQ>@}f|Hwjjg)hRjF+aY zZ-a|#e}{2?g8%>kA^8LW000aCEC2ui04@MD06+!)AR~@sX`X1RGFK72@Vm`RT`hrk zCBW)mf!Su^(GWaH&jG1H8g_+5VLA=;e4ibpmOZKzkmY^9!$8fiVKJnD_)#90SAKlfVgnsPh!AWeowUM zckq@%3j!Nvp4rbbE1RKbMH$U6NDwt?z)XOxW;ykZMS-&lVumQ6Qk6JuJLc z5ka;DWiki`CPX(tz4};NtG0X*5SyHVGXo5m5ij76o9nDv70r1E7*F$oGN4!Q96<(U z&6Yi*W|snbW8QIO5l7*T$A&qS_cb2=Empjet-&q7iSw1>{Ps8D{30Xr>tg06PLeM;!nF literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PanelEdge.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PanelEdge.gif new file mode 100644 index 0000000000000000000000000000000000000000..61f11bee149112ee35fe0b40014cc2f2984331ad GIT binary patch literal 66 zcmZ?wbh9u|OijG&Hy~ ziE4>#NO;h2l9@wDCE!5N!KP{Y@!RHjZeDhFwng!)J0~}%pX+vL=92Z=vf|=mcV>;) zQ(H7!my1l{yYl1WVvk8`!Rx-9+`9Vu`UFvqKMvd0+}xaTc~$J`ZEJ6DFL-=vuJ`tJ zcXwCZ7rWuT?Uj3PgE5yxK!D~IPGJTWwgo>j8&*oM4LeZfu=Lc18OGUS+6wERpI_kI zE$6#yOXemqk9T)x&sxIBEant;)x&_H^@vcBcgKP1?fIMx3%GvV*mbD!y870DCgM})A(?prrXSB=Zz1#bpq2{A2gG?<4 zquCwzXOh#UyiOU4FYsqpd-15-;F!kZxO-PECRM13{tGpc9)44s~&w(7;Ao>Na{XQs@Wxj0NmcR~Xr z%L4HwZTVu7_uIW~uRhP+{&eQ@yqz;wJzudcP$6RKKNb;zpd$OyYcJOBcy>x-$sV&6 zv3(k`+ZdQ_i(DA1oy&G5&Ji>*(^~2GY37Y22d4H{c~_&l(+jrqh9C6pc%}7j$CG_G zvdcH@G)oQW||9PRssqkR#eXt+#(y zTXL$7p@QK?t`G-_>d#eC>-YAWioHGlC(7D^nJ=WKp<$canop;6W|!$5J|Vg*Xt%KO zh6Ywen!cft6l8^5o!*c5b2iV1P_Ex>#VE+Ek!9A;1 zCoeV0KD+&$hw%gDssqBFMUQqX&);*T-#-7}&yAa(y*?bBsrT{T&gAtwm}UkQR6Rfb zeBCdmGmGE<|KDX5zU!RH=2x-&)gHU&KR>eE=HF7D27w-hb<3v7G6m%qe{@#(w&NS) z-_)~>LOcsO)OQ$ohPp*aJc)V!XgdR2-G+MQo`pPuD!V^)w7YNfet0cPV*jy&1#N~7 zJc|x#+?XZ(DTDFq=9xc^u{$YReeBd*weU+;`Bpx)_pSUbi^R5jEI2jugNojkNC#jI F3IJvj7Y_gc delta 1025 zcmV+c1pfQb4$ue-M@dFFH({m$8UTcm3txW#001li0001{0U7`R1^%EQj$~<`XsWJk z>%MR-&vb3uL!J`@;S-fg!D2WV4~RrU!Bi}o&u4Q=ty-_xtai)oW^drIcuX#v&*y-8 z&2CfP6!l2=^9hN@%r~s*N0dqTc6?g|qN`beyxqYfNwTELlk)zUZCZxUf;l3y@*p@+ z@ZhzE4j(*(7~$JQ6raTXC|C{|l631pdJ&1Tsne%WqdMBxuWG;}MiL}ZfS@J-2@D}T z82fNr&r}DiojL_4jvN85MD*w}&M1Pr9+fs>Dz&fQzko?9Q|9cdR$B?6jRJr0aI9m8 z+)}wJ#r93ARjbxoo8UICC{cBw6*!Xj58uG3Q>$Jbso&tig|X^kvLJy00tdn7bW9ea z&oys2TeF54b2e)2Pn-p(=~RwT9-FyP9A!a}jUbwZB7 zO8D@$n^CFy`t7(j`t>h^vnGG8!j;q61t{QvPI1T2GtJ2UwugA*9e`T^=cT8fZ{MWC zR%P&AIA22cDby1MMOa`3fCQFk;)(SPR+VebTty2L48%B|0u_w1kc7QaSRpH{z~|$J z^$pN~12i5GQgtXMspOKy7`Wm&q%Faqj0`Mb!2lEBq?3eUadXy=?=gQDM=PxeaDf93 zG(h8#Ot$Ifo51ih#4|2#wZN1OFwj5)Rt{iZLtCa-Rz%qp*OnX%pot~}{!u|9oRCH; zDI#*tS!Z}v#<=I67cAf)1==*mTUiWsxMKl|qS-(NF-oz^q_D;+s}L&saY?8I&bJbQ(*i5Ns0~cW1D+37>04h%CjS9g4 z#yY@gws}6m?6d5)YvOhZW<{H|oAzq2xm_Iu?pQ;ndcnEb#`vnc1Q!hLGTphjhpyN1 zdT*Kv;6{P5+g5;WvJ0$h@WvdcW*~xwNlCA^_V!w?y$e*(>z-{@YTWV5F#jc|v{BA0 zqr)Ya%%{cZwv1%VKnJazim}mx>8|yz+-u4!r|YuNP)BW2v@Pbb;K-Y%tZl1LOYQa7 v^iX{(Ue!`rrOGS&4EEY=7dUgg;6b5v&l&&R_T6}o^jg(eq0RCFApih7E-vuc diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTopFlat.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTopFlat.gif new file mode 100644 index 0000000000000000000000000000000000000000..81b44abd920ba0959b108142d282568e5fc9baf2 GIT binary patch literal 185 zcmZ?wbhEHbT*k=8u$h5@gM&jrKtMu5LQzrC(9rNdUZA3)qWF`Ak%57qL5BedKxQzo zq)j;Cxq7d~>$AK6CusDgWX{W2weAfY$A$~%N^V!Z literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/RemoveButton.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/RemoveButton.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b5d864053970882b35bf8d7ddd69de75b434f04 GIT binary patch literal 484 zcmZ?wbhEHblw^=(Sjqqbm6esbxw+Zd*_oM{iHV8f;o+g7p@D&c-rnBM&d&Ds_O`aR z*4Ea>#>R$*hWh&Yy1KfWnwqMrs>;gBii(Pol9J-$;-aFW!otFWf`YufybTQvQBhGr zK|ww~K3-m49v&WUZf;IaP8JpxW@cu3dU{$~S{fP}Dk>@p3JP*^axyY95)u+(Vqzj9 zB7A&&JUl!c92_hxEMV6WAQXSHFfuS`GU$NRf&9e4_V2)y0uLRj{u4`zEVOtm<~TNP zRGBresV{wthXT)}SM9Afy&^WF)6cqS#qu%W{vpuk(iq*5y3j7RvAmVGf#1r9YZ9uS(8bpFxV*&GjA vCvl6++xTL6qT6vTt(Xl5w&@;bV=&SQ^Sr3k#=~Hc%rfWXW_70X3Jlf&ZUu;_ literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/content/images/RemoveButton.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/content/images/RemoveButton.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b5d864053970882b35bf8d7ddd69de75b434f04 GIT binary patch literal 484 zcmZ?wbhEHblw^=(Sjqqbm6esbxw+Zd*_oM{iHV8f;o+g7p@D&c-rnBM&d&Ds_O`aR z*4Ea>#>R$*hWh&Yy1KfWnwqMrs>;gBii(Pol9J-$;-aFW!otFWf`YufybTQvQBhGr zK|ww~K3-m49v&WUZf;IaP8JpxW@cu3dU{$~S{fP}Dk>@p3JP*^axyY95)u+(Vqzj9 zB7A&&JUl!c92_hxEMV6WAQXSHFfuS`GU$NRf&9e4_V2)y0uLRj{u4`zEVOtm<~TNP zRGBresV{wthXT)}SM9Afy&^WF)6cqS#qu%W{vpuk(iq*5y3j7RvAmVGf#1r9YZ9uS(8bpFxV*&GjA vCvl6++xTL6qT6vTt(Xl5w&@;bV=&SQ^Sr3k#=~Hc%rfWXW_70X3Jlf&ZUu;_ literal 0 HcmV?d00001 diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-attachment.js b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-attachment.js new file mode 100644 index 00000000..2e70cde6 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-attachment.js @@ -0,0 +1,22 @@ +var minisrv_service_file = true; + +var errpage = null; + +var messageid = request_headers.query.message_id; +var attachment_id = request_headers.query.attachment_id; +if (!attachment_id && attachment_id != 0) errpage = wtvshared.doErrorPage(400, "Attachment ID required."); +else { + var message = ssid_sessions[socket.ssid].mailstore.getMessageByID(messageid); + if (!message) errpage = wtvshared.doErrorPage(400, "Invalid Message ID"); + else { + if (!message.attachments) message.attachments = []; // backwards compat + if (attachment_id > message.attachments.length) errpage = wtvshared.doErrorPage(400, "Invalid Attachment ID"); + } +} + +if (!errpage) { + headers = `200 OK +Content-Type: ${message.attachments[attachment_id]['Content-Type']}`; + data = new Buffer.from(message.attachments[attachment_id]['data'], 'base64'); + fs.writeFileSync("D:\\test.jpg", data); +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-signature.js b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-signature.js new file mode 100644 index 00000000..b10d5c69 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/get-signature.js @@ -0,0 +1,19 @@ +var minisrv_service_file = true; + +var errpage = null; + +var messageid = request_headers.query.message_id || null; +if (!messageid) { + // get user signature + data = ssid_sessions[socket.ssid].getSessionData("subscriber_signature"); +} else { + // get message signature + var message = ssid_sessions[socket.ssid].mailstore.getMessageByID(messageid); + if (!message) errpage = wtvshared.doErrorPage(400, "Invalid Message ID"); + data = message.signature +} +if (!errpage) { + headers = `200 OK +wtv-trusted: false +Content-Type: text/html` +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/readmail.js b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/readmail.js index 10460775..96dab2e3 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/readmail.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/readmail.js @@ -53,7 +53,7 @@ xnocancel> -${message.subject} +${html_entities.encode((message.subject) ? message.subject : '(No subject)')} Subject: -${html_entities.encode(message.subject)} +${html_entities.encode((message.subject) ? message.subject : '(No subject)')} @@ -267,8 +267,32 @@ ${html_entities.encode(message.subject)}

+`; + if (message.attachments) { + message.attachments.forEach((v, k) => { + if (v) { + console.log("*****************",v['Content-Type']); + switch (v['Content-Type']) { + case "image/jpeg": + data += ``; + break; + case "audio/wav": + data += ` +
+  Recording + + +
+`; + break; + } + } + }); + } + data += ` ${html_entities.encode(message.body).replace("\n", "
")} -${(message.signature) ? '' : ''}

diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/sendmail.js b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/sendmail.js index 8b9eb079..96c3a35f 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/sendmail.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/sendmail.js @@ -1,4 +1,6 @@ var minisrv_service_file = true; +var message_snapshot_data = null; +var message_voicemail_data = null; var intro_seen = ssid_sessions[socket.ssid].mailstore.checkMailIntroSeen(); if (!intro_seen && !request_headers.query.intro_seen) { @@ -21,64 +23,117 @@ if (!intro_seen && !request_headers.query.intro_seen) { var msg_subject = request_headers.query.message_subject || null; var msg_body = request_headers.query.message_body || null; var to_name = request_headers.query.whatever_webtv_sends_this_as || null; - var no_signature = request_headers.query.no_signature || false; + var no_signature = (request_headers.query.togglesign == "true") ? false : true; // opposite webtv var mail_draft_data = ssid_sessions[socket.ssid].getSessionData("mail_draft"); + var mail_draft_attachments = ssid_sessions[socket.ssid].getSessionData("mail_draft_attachments"); if (mail_draft_data) { - ssid_sessions[socket.ssid].deleteSessionData("mail_draft") + ssid_sessions[socket.ssid].deleteSessionData("mail_draft"); to_addr = mail_draft_data.to_addr; msg_subject = mail_draft_data.msg_subject; msg_body = mail_draft_data.msg_body; no_signature = mail_draft_data.no_signature; } + if (mail_draft_attachments) { + if (mail_draft_attachments.message_snapshot_data) message_snapshot_data = mail_draft_attachments.message_snapshot_data; + else if (request_headers.query.message_snapshot_data) message_snapshot_data = request_headers.query.message_snapshot_data; + if (mail_draft_attachments.message_voicemail_data) message_voicemail_data = mail_draft_attachments.message_voicemail_data; + else if (request_headers.query.message_voicemail_data) message_voicemail_data = request_headers.query.message_voicemail_data; + } - - var username = ssid_sessions[socket.ssid].getSessionData("subscriber_username"); - var userdisplayname = html_entities.encode(ssid_sessions[socket.ssid].getSessionData("subscriber_name")); - var address = username + "@" + minisrv_config.config.service_name - var notImplementedAlert = new clientShowAlert({ - 'image': minisrv_config.config.service_logo, - 'message': "This feature is not available.", - 'buttonlabel1': "Okay", - 'buttonaction1': "client:donothing", - 'noback': true, - }).getURL(); - - if (request_headers.query.sendoff == "Send" || request_headers.query.saveoff) { - var from_addr = address; - var signature = ssid_sessions[socket.ssid].getSessionData("subscriber_signature") || null; - if (request_headers.query.sendoff == "Send") { - var messagereturn = ssid_sessions[socket.ssid].mailstore.sendMessageToAddr(from_addr, to_addr, msg_body, msg_subject, userdisplayname, to_name, signature); - if (messagereturn !== true) { - var errpage = wtvshared.doErrorPage(400, messagereturn); - headers = errpage[0]; - data = errpage[1]; - } else { - headers = `300 OK - wtv-expire: wtv-mail:/listmail - Location: wtv-mail:/listmail`; - } - } else { - var mail_draft_data = { - to_addr: to_addr, - msg_subject: msg_subject, - msg_body: msg_body, - no_signature: no_signature - } - ssid_sessions[socket.ssid].setSessionData("mail_draft", mail_draft_data); - headers = `200 OK -Content-type text/html -wtv-expire: wtv-mail:/sendmail`; - } + if (message_snapshot_data && request_headers.query.get_snap) { + headers = `200 OK +Content-Type: image/jpeg`; + data = message_snapshot_data; + } else if (message_voicemail_data && request_headers.query.get_snap) { + headers = `200 OK +Content-Type: audio/wav`; + data = message_voicemail_data; } else { - headers = `200 OK -Content-type text/html`; + var username = ssid_sessions[socket.ssid].getSessionData("subscriber_username"); + var userdisplayname = html_entities.encode(ssid_sessions[socket.ssid].getSessionData("subscriber_name")); + var address = username + "@" + minisrv_config.config.service_name + var notImplementedAlert = new clientShowAlert({ + 'image': minisrv_config.config.service_logo, + 'message': "This feature is not available.", + 'buttonlabel1': "Okay", + 'buttonaction1': "client:donothing", + 'noback': true, + }).getURL(); - data = ` + if (request_headers.query.sendoff == "Send" || request_headers.query.saveoff || request_headers.query.get_snap || request_headers.query.get_gab) { + var from_addr = address; + var signature = ssid_sessions[socket.ssid].getSessionData("subscriber_signature") || null; + if (request_headers.query.sendoff == "Send") { + var attachments = []; + + + if (typeof message_snapshot_data == "object") { + attachments.push({ 'Content-Type': 'image/jpeg', data: new Buffer.from(message_snapshot_data).toString('base64') }); + } else { + attachments.push({ 'Content-Type': 'image/jpeg', data: message_snapshot_data }); + } + + if (typeof message_snapshot_data == "object") { + attachments.push({ 'Content-Type': 'audio/wav', data: new Buffer.from(message_snapshot_data).toString('base64') }); + } else { + attachments.push({ 'Content-Type': 'audio/wav', data: new message_snapshot_data }); + } + + var messagereturn = ssid_sessions[socket.ssid].mailstore.sendMessageToAddr(from_addr, to_addr, msg_body, msg_subject, userdisplayname, to_name, signature, attachments); + if (messagereturn !== true) { + var errpage = wtvshared.doErrorPage(400, messagereturn); + headers = errpage[0]; + data = errpage[1]; + } else { + ssid_sessions[socket.ssid].deleteSessionData("mail_draft"); + ssid_sessions[socket.ssid].deleteSessionData("mail_draft_attachments"); + headers = `300 OK +wtv-expire: wtv-mail:/listmail +wtv-expire: wtv-mail:/sendmail +Location: wtv-mail:/listmail`; + } + + } else if (request_headers.query.saveoff) { + var mail_draft_data = { + to_addr: to_addr, + msg_subject: msg_subject, + msg_body: msg_body, + no_signature: no_signature + } + ssid_sessions[socket.ssid].setSessionData("mail_draft", mail_draft_data); + headers = `200 OK +Content-type: text/html +wtv-expire: wtv-mail:/sendmail`; + } + } else { + + headers = `200 OK +Content-type: text/html`; + if (request_headers.query.snapping == "false") headers += "\nwtv-expire: cache:snapshot.jpg"; + if (request_headers.query.gabbing == "false") headers += "\nwtv-expire: cache:voicemail.wav"; + var mail_draft_data = ssid_sessions[socket.ssid].getSessionData("mail_draft_attachments") || {}; + if (request_headers.query.message_snapshot_data) { + mail_draft_data.message_snapshot_data = request_headers.query.message_snapshot_data + ssid_sessions[socket.ssid].setSessionData("mail_draft_attachments", mail_draft_data); + } + + if (request_headers.query.message_voicemail_data) { + mail_draft_data.message_voicemail_data = request_headers.query.message_voicemail_data + ssid_sessions[socket.ssid].setSessionData("mail_draft_attachments", mail_draft_data); + } + data = ` + + - - -Write a message +Write an e-mail message - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - -
- - - -
-
-
- -
- -
- -
- - - -
- - - - -
-
Mail list -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Address -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Photo -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Recording -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Erase -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Spelling -
-
-
-
- -
- -
- -
- - - -
- - - - -
-
Help -
-
-
-
- -
- -
- -
-
-
-
- - - - -
-
- - - - - -Write a message - - - -
+

- + +
-
- - - + + - - +
- - - - - - - - - - - - - - -
- -From:  - - -${address} -(${userdisplayname}) + + +
+ + + + + +
+ + + + + + + + +
+
+ + + + +
+
Mail list +
+
+
+
+ + + + +
+
Address +
+
+
+
+ + + + +
+
Photo +
+
+
+
+ + + + + +
+
Recording +
+
+
+
+ + + + +
+
Erase +
+
+
+
+ +
+
+
+ + + + + + -
+ +
+ +
+ + +
+ + + + + +
- -
- + - -
- -
- -To:  - + + + +
+ + + +Write an e-mail message + + + + +
+
+
+ + +
+ + +
+ + + + + +
+
+ + +
+ + + + + + - - - - - - - - - -
+From:  + + + +
+${address} +
+(${userdisplayname}) +
+ +
+To:  +
- -
- + +
- -
- -Subject:  - + +Subject:  +
- -
- + +
- -
- -
+ - -
- +autohiragana +growable +nextdown="Send">${(msg_body) ? msg_body : ''}
- - - -
- - - -
- -
`; - if (!ssid_sessions[socket.ssid].getSessionData("subscriber_signature") || ssid_sessions[socket.ssid].getSessionData("subscriber_signature") == "") { - data += `
`; - } else { - data += ` Disable Signature`; - } - data += ` +`; + if (ssid_sessions[socket.ssid].getSessionData("subscriber_signature") && ssid_sessions[socket.ssid].getSessionData("subscriber_signature") != "" && !no_signature) { + data += ``; + } + data += `
@@ -493,7 +406,19 @@ width=422 height=6>
-
+`; + if (!ssid_sessions[socket.ssid].getSessionData("subscriber_signature") || ssid_sessions[socket.ssid].getSessionData("subscriber_signature") == "") { + data += ` `; + } else if (no_signature) { + data += ` + Add signature  +
`; + } else { + data += ` + Remove signature  +
`; + } + data += `
+`; + + if ((request_headers.query.snapping && request_headers.query.snapping !== 'false') || message_snapshot_data) { + data += `
+ +
+ + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + +
`; + if (!message_snapshot_data) { + data += ` +`; + } + + data += ` +
+ +
+
+ +
+ + + Detach  +
+
+ +
+ + + +`; + } + + if (request_headers.query.gabbing && request_headers.query.gabbing !== 'false') { + data += ` +
+ + + +
+ +
+ +
+ + + + + + +
+ + + +
+ + + + + + + + + + + + + + +
+ +${(message_voicemail_data) ? '' : ''} +
+ +
+  Recording + + + Detach  +
+ +
+ + + +`; + } + + data += ` +
+ + + +
+ +
`; + } } } \ No newline at end of file diff --git a/zefie_wtvp_minisrv/WTVClientSessionData.js b/zefie_wtvp_minisrv/WTVClientSessionData.js index d9d855ab..339990fe 100644 --- a/zefie_wtvp_minisrv/WTVClientSessionData.js +++ b/zefie_wtvp_minisrv/WTVClientSessionData.js @@ -2,6 +2,8 @@ const { lib } = require('crypto-js'); const CryptoJS = require('crypto-js'); const WTVMail = require('./WTVMail.js') const WTVSec = require('./WTVSec.js'); + + class WTVClientSessionData { fs = require('fs'); @@ -53,7 +55,6 @@ class WTVClientSessionData { this.loginWhitelist.push("wtv-head-waiter:/password"); } - assignMailStore() { this.mailstore = new WTVMail(this.minisrv_config, this) } @@ -352,7 +353,7 @@ class WTVClientSessionData { try { if (this.fs.lstatSync(this.getUserStoreDirectory() + "user" + this.user_id + ".json")) { var json_data = this.fs.readFileSync(this.getUserStoreDirectory() + "user" + this.user_id + ".json", 'Utf8') - if (raw_data) return json_data; + if (raw_data) return JSON.parse(json_data); var session_data = JSON.parse(json_data); this.session_store = session_data; @@ -400,13 +401,14 @@ class WTVClientSessionData { return (password_valid); } - saveSessionData(force_write = false) { + saveSessionData(force_write = false, skip_merge = false) { if (this.isRegistered()) { - // load data from disk and merge new data - var temp_store = this.session_store; - if (this.loadSessionData()) this.session_store = Object.assign(this.session_store, temp_store); - else this.session_store = temp_store; - temp_store = null; + if (!skip_merge) { + // load data from disk and merge new data + var temp_data = this.loadSessionData(true); + if (temp_data) this.session_store = Object.assign(temp_data, this.session_store); + temp_data = null; + } } else { // do not write file if user is not registered, return true because this is not an error // force write needed to set the initial reg @@ -439,8 +441,8 @@ class WTVClientSessionData { return this.saveSessionData(force_write); } - SaveIfRegistered() { - if (this.isRegistered()) return this.saveSessionData(); + SaveIfRegistered(skip_merge = false) { + if (this.isRegistered()) return this.saveSessionData(false, skip_merge); return false; } @@ -531,7 +533,7 @@ class WTVClientSessionData { deleteSessionData(key) { if (key === null) throw ("ClientSessionData.delete(): invalid key provided"); delete this.session_store[key]; - this.SaveIfRegistered(); + this.SaveIfRegistered(true); } @@ -552,7 +554,7 @@ class WTVClientSessionData { delete(key) { if (key === null) throw ("ClientSessionData.delete(): invalid key provided"); delete this.data_store[key]; - this.SaveIfRegistered(); + this.SaveIfRegistered(true); } getBoxName() { diff --git a/zefie_wtvp_minisrv/WTVMail.js b/zefie_wtvp_minisrv/WTVMail.js index 049cbf9b..e3a46119 100644 --- a/zefie_wtvp_minisrv/WTVMail.js +++ b/zefie_wtvp_minisrv/WTVMail.js @@ -125,7 +125,7 @@ class WTVMail { } - createMessage(mailboxid, from_addr, to_addr, msgbody, subject = null, from_name = null, to_name = null, signature = null, date = null, known_sender = false) { + createMessage(mailboxid, from_addr, to_addr, msgbody, subject = null, from_name = null, to_name = null, signature = null, date = null, known_sender = false, attachments = []) { if (this.createMailbox(mailboxid)) { if (!date) date = Math.floor(Date.now() / 1000); @@ -143,7 +143,8 @@ class WTVMail { "body": msgbody, "known_sender": known_sender, "signature": signature, - "unread": true + "unread": true, + "attachments": attachments } try { if (this.fs.existsSync(message_file_out)) { @@ -194,6 +195,9 @@ class WTVMail { message_data.message_file = message_file; if (message_data) { message_data.id = messageid; + // backwards compat + if (!message_data.attachments) message_data.attachments = []; + return message_data; } else console.error(" # MailErr: could not parse json in ", message_file_in); @@ -333,8 +337,8 @@ class WTVMail { return false; } - sendMessageToAddr(from_addr, to_addr, msgbody, subject = null, from_name = null, to_name = null, signature = null) { - if (!to_addr) return "You must type a destination address for your message."; + sendMessageToAddr(from_addr, to_addr, msgbody, subject = null, from_name = null, to_name = null, signature = null, attachments = []) { + if (!to_addr) return "Your message could not be sent.

You must specify an addressee in the To: area."; if (to_addr.indexOf('@') === -1) to_addr += "@"+this.minisrv_config.config.service_name; @@ -365,7 +369,7 @@ class WTVMail { if (mailbox_exists) dest_user_mailstore.createWelcomeMessage(); } // if the mailbox exists, deliver the message - if (dest_user_mailstore.mailboxExists(0)) this.createMessage(0, from_addr, to_addr, msgbody, subject, from_name, to_name, signature); + if (dest_user_mailstore.mailboxExists(0)) this.createMessage(0, from_addr, to_addr, msgbody, subject, from_name, to_name, signature, null, this.isInUserAddressBook(to_addr, from_addr), attachments); else return "There was an internal error sending the message to " + to_addr + ". Please try again later"; // clean up @@ -375,6 +379,11 @@ class WTVMail { return "Unknown error"; } + isInUserAddressBook(address_to_check, address_to_look_for) { + // unimplemented + return false; + } + getMessageMailboxName(messageid) { // returns the mailbox id of which the message was found for the current user var self = this; diff --git a/zefie_wtvp_minisrv/WTVShared.js b/zefie_wtvp_minisrv/WTVShared.js index 04f42ad2..c4ddfc2a 100644 --- a/zefie_wtvp_minisrv/WTVShared.js +++ b/zefie_wtvp_minisrv/WTVShared.js @@ -2,6 +2,7 @@ * Shared functions across all classes and apps */ + class WTVShared { path = require('path'); @@ -22,6 +23,13 @@ class WTVShared { } } + isASCII(str) { + for (var i = 0, strLen = str.length; i < strLen; ++i) { + if (str.charCodeAt(i) > 127) return false; + } + return true; + } + returnAbsolutePath(check_path) { if (check_path.substring(0, 1) != this.path.sep && check_path.substring(1, 1) != ":") { // non-absolute path, so use current directory as base @@ -123,11 +131,44 @@ class WTVShared { return new Date((new Date).getTime() + offset).toUTCString(); } + urlEncodeBytes = (buf) => { + let encoded = '' + for (let i = 0; i < buf.length; i++) { + const charBuf = Buffer.from('00', 'hex') + charBuf.writeUInt8(buf[i]) + const char = charBuf.toString() + // if the character is safe, then just print it, otherwise encode + if (isUrlSafe(char)) { + encoded += char + } else { + encoded += `%${charBuf.toString('hex').toUpperCase()}` + } + } + return encoded + } + + urlDecodeBytes = (encoded) => { + let decoded = Buffer.from('') + for (let i = 0; i < encoded.length; i++) { + if (encoded[i] === '%') { + const charBuf = Buffer.from(`${encoded[i + 1]}${encoded[i + 2]}`, 'hex') + decoded = Buffer.concat([decoded, charBuf]) + i += 2 + } else { + const charBuf = Buffer.from(encoded[i]) + decoded = Buffer.concat([decoded, charBuf]) + } + + } + return decoded + } + /** * Returns a censored SSID * @param {string|Array} obj SSID String or Headers Object */ filterSSID(obj) { + var outobj = null; if (this.minisrv_config.config.hide_ssid_in_logs === true) { if (typeof (obj) == "string") { if (obj.substr(0, 8) == "MSTVSIMU") { @@ -159,6 +200,11 @@ class WTVShared { if (obj.post_data) { obj.post_data = obj.post_data.toString(); } + if (obj.query) { + obj.query = Object.assign({}, obj.query); + if (obj.query.message_snapshot_data) obj.query.message_snapshot_data = '(binary POST filtered, see post_data hex dump)' + if (obj.query.message_voicemail_data) obj.query.message_snapshot_data = '(binary POST filtered, see post_data hex dump)' + } return obj; } diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 0ed09c0b..1a4e5e1c 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -315,10 +315,10 @@ async function processURL(socket, request_headers) { if (request_headers['wtv-request-type']) socket_sessions[socket.id].wtv_request_type = request_headers['wtv-request-type']; if (request_headers.post_data) { - var post_data_string = ''; + var post_data_string = null; try { - post_data_string = request_headers.post_data.toString(CryptoJS.enc.Utf8).replace("\0", ""); // if not text this will probably throw an exception - if (isUnencryptedString(post_data_string)) { + post_data_string = request_headers.post_data.toString(CryptoJS.enc.Utf8); // if not text this will probably throw an exception + if (post_data_string) { if (post_data_string.indexOf('=')) { if (post_data_string.indexOf('&')) { var qraw = post_data_string.split('&'); @@ -327,7 +327,9 @@ async function processURL(socket, request_headers) { var qraw_split = qraw[i].split("="); if (qraw_split.length == 2) { var k = qraw_split[0]; - request_headers.query[k] = unescape(qraw[i].split("=")[1].replace(/\+/g, "%20")); + var data = unescape(qraw[i].split("=")[1].replace(/\+/g, "%20")); + if (wtvshared.isASCII(data)) request_headers.query[k] = data; + else request_headers.query[k] = wtvshared.urlDecodeBytes(qraw[i].split("=")[1].replace(/\+/g, "%20")); } } } @@ -335,13 +337,15 @@ async function processURL(socket, request_headers) { var qraw_split = post_data_string.split("="); if (qraw_split.length == 2) { var k = qraw_split[0]; - request_headers.query[k] = unescape(qraw_split[1].replace(/\+/g, "%20")); + var data = unescape(qraw_split[1].replace(/\+/g, "%20")); + if (wtvshared.isASCII(data)) request_headers.query[k] = data; + else request_headers.query[k] = wtvshared.urlDecodeBytes(qraw_split[1].replace(/\+/g, "%20")); } } } } } catch (e) { - // do nothing + console.log("error:",e) } } @@ -424,7 +428,7 @@ Location: " + minisrv_config.config.unauthorized_url`; // assume webtv since there is a :/ in the GET var service_name = shortURL.split(':/')[0]; var urlToPath = wtvshared.fixPathSlashes(service_name + path.sep + shortURL.split(':/')[1]); - if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(await wtvshared.filterSSID(request_headers)))); + if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterSSID(Object.assign({}, request_headers))))); socket_sessions[socket.id].request_headers = request_headers; processPath(socket, urlToPath, request_headers, service_name); } else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) { @@ -442,7 +446,7 @@ Location: " + minisrv_config.config.unauthorized_url`; async function doHTTPProxy(socket, request_headers) { var request_type = (request_headers.request_url.substring(0, 5) == "https") ? "https" : "http"; - if (minisrv_config.config.debug_flags.show_headers) console.log(request_type.toUpperCase() + " Proxy: Client Request Headers on socket ID", socket.id, (await wtvshared.decodePostData(await wtvshared.filterSSID(request_headers)))); + if (minisrv_config.config.debug_flags.show_headers) console.log(request_type.toUpperCase() + " Proxy: Client Request Headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterSSID(Object.assign({}, request_headers))))); switch (request_type) { case "https": var proxy_agent = https; @@ -946,7 +950,7 @@ function moveObjectElement(currentKey, afterKey, obj) { } -function isUnencryptedString(string, verbose = false) { +function isUnencryptedString(string) { // a generic "isAscii" check is not sufficient, as the test will see the binary // compressed / encrypted data as ASCII. This function checks for characters expected // in unencrypted headers, and returns true only if every character in the string matches @@ -1017,7 +1021,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq } } } - } + } if (!headers) return; diff --git a/zefie_wtvp_minisrv/package-lock.json b/zefie_wtvp_minisrv/package-lock.json index d682acee..85982305 100644 --- a/zefie_wtvp_minisrv/package-lock.json +++ b/zefie_wtvp_minisrv/package-lock.json @@ -1,12 +1,12 @@ { "name": "zefie_wtvp_minisrv", - "version": "0.9.24", + "version": "0.9.25", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "zefie_wtvp_minisrv", - "version": "0.9.24", + "version": "0.9.25", "license": "GPL3", "dependencies": { "crypto-js": "^4.1.1", diff --git a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj index 5796fabd..0322f6f7 100644 --- a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj +++ b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj @@ -97,6 +97,12 @@ + + Code + + + Code + Code