UNPKG

postmailer

Version:

HTTP POST -> SMTP proxy, as Express middleware

385 lines (330 loc) 15.2 kB
<html> <head> <title>POST for {{name}}</title> <style> body { max-width: 800px; margin: auto; font-family: 'Open Sans', Tahoma; font-size: 11pt; color: #111; } h1 { font-size: 1.5em; margin: 0.5em 0; text-align: center; } h2 { font-size: 1.2em; margin: 1em 0em; } code { display: inline-block; padding: 0.3em 0.3em 0.1em 0.3em; background-color: #EEE; border-radius: 0.3em; font-family: Consolas, Monaco, 'Andale Mono', monospace; box-shadow: 0px 1px #DDD; } pre { margin: 0.5em 2em; padding: 0; font-size: inherit; } pre code { display: block; width: 100%; overflow: auto; } .cmd-option { color: #048; } .cmd-value { color: #800; } .cmd-value-file { color: #482; } .headers, .text, .email { width: 100%; padding: 0.5em 0em; background-color: #FFF; border: none; border-top: 1px solid #DDD; font-family: Consolas, Monaco, 'Andale Mono', monospace; box-shadow: 0px 1px #DDD; font-size: inherit; height: 5em; } .send { width: 100%; height: 2em; padding:0; color: #000; background-color: #EEE; border: 1px solid #DDD; border-radius: 0.3em; font-family: inherit; font-size: inherit; box-shadow: 0px 1px #DDD; cursor: pointer; } .send:hover { background-color: #DDD; } .log { overflow: auto; margin-top: 1em; margin-bottom: 2em; } .log-send, .log-receive, .log-event { clear: both; display: block; margin: 0.5em 0em; white-space: pre-wrap; max-width: 90%; } .log-send { float: left; background-color: #DEF; } .log-send.pending { font-style: italic; background-color: #EEE; } .log-receive, .log-event { float: right; } .success { background-color: #DDF8DD; } .error { background-color: #F8DDDD; } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: auto; width: auto; padding: 1em; text-align: center; opacity: 0.9; } /* iframe layout */ .iframe-table { position: fixed; top: 0; left: 0; width: 100%; height: 100%; border-spacing: 0; border-collapse: collapse; font-size: inherit; } .iframe-table td { padding: 0; } #email-row, .iframe .email { height: 1.5em; } #text-row { position: relative; } .iframe .text { position: absolute; top: 0; left: 0; height: 100%; resize: none; } #send-row { height: 2em; } .iframe .send { border-top-left-radius: 0; border-top-right-radius: 0; } .iframe .email, .iframe .text { padding: 0.2em 0.3em; } </style> </head> <body data-url="{{url}}" data-ws-url="{{ws-url}}" data-name="{{name}}"> <h1>POST for <span class="self-name">{{name}}</span></h1> <p>This is an HTTP POST endpoint. Any text/document you POST to this URL will be received by the user.</p> <p>You must provide a <code>From:</code> header (borrowed from SMTP), and can include other mail headers as well.</p> <h2>Use with cURL:</h2> <p>To send a plain text message:</p> <pre><code>curl <span class="cmd-option">--data-binary</span> <span class="cmd-value">"Hello, world"</span> <span class="cmd-option">--header</span> <span class="cmd-value">"Content-Type: text/plain"</span> \ <span class="cmd-option">--header</span> <span class="cmd-value">"From: Somebody &lt;somebody@example.com&gt;"</span> \ <span class="cmd-argument"><span class="self-url">{{url}}</span></span></code></pre> <p>To send an inline picture:</p> <pre><code>curl <span class="cmd-option">--data-binary</span> <span class="cmd-value-file">@small-image.png</span> <span class="cmd-option">--header</span> <span class="cmd-value">"Content-Type: image/png"</span> \ <span class="cmd-option">--header</span> <span class="cmd-value">"From: Somebody &lt;somebody@example.com&gt;"</span> \ <span class="cmd-argument"><span class="self-url">{{url}}</span></span></code></pre> <p>To send a picture (or other document) as an attachment:</p> <pre><code>curl <span class="cmd-option">--data-binary</span> <span class="cmd-value-file">@large-image.jpg</span> <span class="cmd-option">--header</span> <span class="cmd-value">"Content-Type: image/jpeg"</span> \ <span class="cmd-option">--header</span> <span class="cmd-value">"Content-Disposition: attachment; filename=\"large-image.jpg\""</span> \ <span class="cmd-option">--header</span> <span class="cmd-value">"From: Somebody &lt;somebody@example.com&gt;"</span> \ <span class="cmd-argument"><span class="self-url">{{url}}</span></span></code></pre> <script> (function () { // Wrap so that minifying is more effective function createElement(tag, textOrProps, parent, before) { var tagParts = tag.split('.'); var element = document.createElement(tagParts.shift()); element.className = tagParts.join(' '); if (typeof textOrProps === 'string') { element.appendChild(document.createTextNode(textOrProps)); } else { for (var key in textOrProps || {}) { element[key] = textOrProps[key]; } } parent = parent || document.body; if (typeof before === 'number') { before = parent.childNodes[before]; } parent.insertBefore(element, before || null); return element; } // Replace template values with JS so we can just use the template on its own var selfUrl = location.href.replace(/[?#].*/, ''); // Strip query and hash var selfUrlEscaped = selfUrl.replace(/&/g, '&amp;').replace(/</g, '&lt;'); var backupName = selfUrl.replace(/.*:\/\//, ''); var backupNameEscaped = backupName.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;'); document.title = document.title.replace(/\{\{name\}\}/g, backupName); document.body.innerHTML = document.body.innerHTML.replace(/\{\{url\}\}/g, selfUrlEscaped).replace(/\{\{name\}\}/g, backupNameEscaped); function inIframe () { try { return window.self !== window.top; } catch (e) { return true; } } function postAjaxMessage(headers, text, callback) { var request = new XMLHttpRequest(); var url = document.body.getAttribute('data-url'); if (!url || url[0] === '{') url = location.href.replace(/#.*/, ''); request.open('POST', url, true); // headerObj is map of arrays/strings var headerObj = headers; if (typeof headers === 'string') { headerObj = {}; headers = headers.split('\n'); for (var i = 0; i < headers.length; i++) { var line = headers[i] + ""; var name = line.match(/^([a-zA-Z\-]*)\:/); if (!name) continue; name = name[1]; var value = line.substring(name.length + 1).replace(/^\s*/, '').replace(/\r/g, ''); headerObj[name] = (headerObj[name] || []).concat(value); } } var headerText = ''; for (var name in headerObj) { var value = headerObj[name] + ""; try { request.setRequestHeader(name, value); headerText += name + ': ' + value + '\n'; } catch (e) { try { console.error(e); } catch (e) {} continue; } } request.onreadystatechange = function () { if (request.readyState !== 4) return; var error = null; if (request.status >= 300 || request.status < 200) { error = new Error(request.status + ' ' + request.statusText); } callback(error, request.responseText); }; request.send(text); return headerText + '\n' + text; } if (!inIframe()) { var h2 = createElement('h2', 'Use with AJAX:'); var inputHeaders = createElement('textarea.headers', {value: 'Content-Type: text/plain\nFrom: ???'}); var inputText = createElement('textarea.text', {value: 'Hello, world'}); var sendButton = createElement('input.send', {type: 'submit', value: 'send'}); var logBox = createElement('div.log'); sendButton.onclick = function () { var receiveEntry = createElement('code.log-receive', 0, logBox, 0); var sentText = postAjaxMessage(inputHeaders.value, inputText.value, function (error, text) { if (error) { receiveEntry.className += ' error'; } else { receiveEntry.className += ' success'; } if (typeof text === 'string') { receiveEntry.appendChild(document.createTextNode(text)); } }); var sendEntry = createElement('code.log-send', sentText, logBox, receiveEntry); }; } else { // Sorry, but I need this to work in IE, okay? document.body.innerHTML = '<table class="iframe-table" cellpadding=0 cellspacing=0 border=0>' + '<tr><td id="email-row">' + '<input type="text" id="email-input" class="email" placeholder="name@example.com" value="">' + '<tr><td id="text-row">' + '<textarea id="text-input" class="text" placeholder="Enter your message"></textarea>' + '<tr><td id="send-row">' + '<input type="submit" id="send-input" class="send" value="send">' + '</table>'; document.body.className = 'iframe'; var inputEmail = document.getElementById('email-input'); var inputText = document.getElementById('text-input'); var sendButton = document.getElementById('send-input'); sendButton.onclick = function () { if (!/@/.test(inputEmail.value) && !/\:\/\//.test(inputEmail.value)) { inputEmail.focus(); inputEmail.className = 'email error'; return; } else { inputEmail.className = 'email'; } if (!inputText.value) { inputText.focus(); return; }; sendButton.disabled = true; sendButton.value = 'sending...'; var sentText = postAjaxMessage({ from: inputEmail.value, subject: '(message form)' }, inputText.value, function (error, text) { sendButton.value = "send"; sendButton.disabled = false; var overlay = document.createElement('div'); overlay.className = 'overlay'; document.body.appendChild(overlay); setTimeout(function () { overlay.parentNode.removeChild(overlay); }, 5000); if (error) { overlay.className += ' error'; } else { overlay.className += ' success'; inputText.value = ''; } if (typeof text === 'string') { try { text = JSON.parse(text); } catch (e) { // } overlay.appendChild(document.createTextNode(text)); } }); }; } })(); </script> </body> </html>