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 00000000..ff804edb Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileImage.gif differ diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileMovie.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileMovie.gif new file mode 100644 index 00000000..7f31b5d2 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileMovie.gif differ 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 00000000..55e1d1fd Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FilePackage.gif differ 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 00000000..199fcd98 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileSound.gif differ diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileText.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileText.gif new file mode 100644 index 00000000..3c5f762e Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/FileText.gif differ 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 00000000..61f11bee Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PanelEdge.gif differ diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTop.gif b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTop.gif index 2e22e0de..38334866 100644 Binary files a/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTop.gif and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTop.gif differ 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 00000000..81b44abd Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/PaperTopFlat.gif differ 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 00000000..7b5d8640 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/ROMCache/RemoveButton.gif differ 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 00000000..7b5d8640 Binary files /dev/null and b/zefie_wtvp_minisrv/ServiceVault/wtv-mail/content/images/RemoveButton.gif differ 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