New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

maildev

Package Overview
Dependencies
Maintainers
3
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

maildev - npm Package Compare versions

Comparing version

to
2.0.3

docker/package-lock.json

227

app/scripts/controllers/item.js

@@ -7,32 +7,48 @@ /* global angular, app, prompt */

app.controller('ItemCtrl', [
'$scope', '$rootScope', '$routeParams', '$location', 'Email', '$http', '$cookies',
function ($scope, $rootScope, $routeParams, $location, Email, $http, $cookies) {
const iframe = null
app.controller("ItemCtrl", [
"$scope",
"$rootScope",
"$routeParams",
"$location",
"Email",
"$http",
"$cookies",
function (
$scope,
$rootScope,
$routeParams,
$location,
Email,
$http,
$cookies
) {
// Get the item data by route parameter
const getItem = function () {
Email.get({ id: $routeParams.itemId }, function (email) {
$scope.item = new Email(email)
Email.get(
{ id: $routeParams.itemId },
function (email) {
$scope.item = new Email(email);
if ($scope.item.html) {
$scope.item.iframeUrl = 'email/' + $scope.item.id + '/html'
prepIframe()
$scope.panelVisibility = 'html'
} else {
$scope.htmlView = 'disabled'
$scope.panelVisibility = 'plain'
if ($scope.item.html) {
$scope.item.iframeUrl = "email/" + $scope.item.id + "/html";
prepIframe();
$scope.panelVisibility = "html";
} else {
$scope.htmlView = "disabled";
$scope.panelVisibility = "plain";
}
},
function () {
console.error("404: Email not found");
$location.path("/");
}
}, function () {
console.error('404: Email not found')
$location.path('/')
})
}
);
};
// Get email source
const getSource = function () {
if (typeof $scope.rawEmail === 'undefined') {
$scope.rawEmail = 'email/' + $scope.item.id + '/source'
if (typeof $scope.rawEmail === "undefined") {
$scope.rawEmail = "email/" + $scope.item.id + "/source";
}
}
};

@@ -43,38 +59,46 @@ // Prepares the iframe for interaction

setTimeout(function () {
const [iframe] = document.getElementsByTagName('iframe')
const [head] = iframe.contentDocument.getElementsByTagName('head')
const baseEl = iframe.contentDocument.createElement('base')
const [iframe] = document.getElementsByTagName("iframe");
const [head] = iframe.contentDocument.getElementsByTagName("head");
const baseEl = iframe.contentDocument.createElement("base");
// Append <base target="_blank" /> to <head> in the iframe so all links open in new window
baseEl.setAttribute('target', '_blank')
baseEl.setAttribute("target", "_blank");
if (head) head.appendChild(baseEl)
if (head) head.appendChild(baseEl);
replaceMediaQueries()
fixIframeHeight()
replaceMediaQueries(iframe);
fixIframeHeight(iframe);
addHideDropdownHandler(iframe.contentDocument.getElementsByTagName('body')[0])
}, 500)
}
addHideDropdownHandler(
iframe.contentDocument.getElementsByTagName("body")[0]
);
}, 500);
};
// Updates the iframe height so it matches it's content
// This prevents the iframe from having scrollbars
const fixIframeHeight = function () {
const body = iframe.contentDocument.getElementsByTagName('body')[0]
const newHeight = body.scrollHeight
const fixIframeHeight = function (iframe) {
const body = iframe.contentDocument.getElementsByTagName("body")[0];
const newHeight = body.scrollHeight;
iframe.height = newHeight
}
iframe.height = newHeight;
};
// Updates all media query rules to use 'width' instead of device width
const replaceMediaQueries = function () {
angular.forEach(iframe.contentDocument.styleSheets, function (styleSheet) {
angular.forEach(styleSheet.cssRules, function (rule) {
if (rule.media && rule.media.mediaText) {
// TODO -- Add future warning if email doesn't use '[max|min]-device-width' media queries
rule.media.mediaText = rule.media.mediaText.replace('device-width', 'width')
}
})
})
}
const replaceMediaQueries = function (iframe) {
angular.forEach(
iframe.contentDocument.styleSheets,
function (styleSheet) {
angular.forEach(styleSheet.cssRules, function (rule) {
if (rule.media && rule.media.mediaText) {
// TODO -- Add future warning if email doesn't use '[max|min]-device-width' media queries
rule.media.mediaText = rule.media.mediaText.replace(
"device-width",
"width"
);
}
});
}
);
};

@@ -84,23 +108,26 @@ // NOTE: This is kind of a hack to get these dropdowns working. Should be revisited in the future

$scope.toggleDropdown = function ($event, dropdownName) {
$event.stopPropagation()
$scope.dropdownOpen = dropdownName === $scope.dropdownOpen ? '' : dropdownName
}
$event.stopPropagation();
$scope.dropdownOpen =
dropdownName === $scope.dropdownOpen ? "" : dropdownName;
};
function hideDropdown (e) {
function hideDropdown(e) {
$scope.$apply(function () {
$scope.dropdownOpen = ''
})
$scope.dropdownOpen = "";
});
}
function addHideDropdownHandler (element) {
angular.element(element)
.off('click', hideDropdown)
.on('click', hideDropdown)
function addHideDropdownHandler(element) {
angular
.element(element)
.off("click", hideDropdown)
.on("click", hideDropdown);
}
addHideDropdownHandler(window)
addHideDropdownHandler(window);
function validateEmail (email) {
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return re.test(email)
function validateEmail(email) {
const re =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}

@@ -110,35 +137,40 @@

$scope.show = function (type) {
if ((type === 'html' || type === 'attachments') && !$scope.item[type]) return
if (type === 'source') getSource()
if ((type === "html" || type === "attachments") && !$scope.item[type])
return;
if (type === "source") getSource();
$scope.panelVisibility = type
}
$scope.panelVisibility = type;
};
// Sends a DELETE request to the server
$scope.delete = function (item) {
Email.delete({ id: item.id })
}
Email.delete({ id: item.id });
};
// Updates iframe to have a width of newSize, i.e. '320px'
$scope.resize = function (newSize) {
iframe.style.width = newSize || '100%'
fixIframeHeight()
$scope.iframeSize = newSize
}
const [iframe] = document.getElementsByTagName("iframe");
iframe.style.width = newSize || "100%";
fixIframeHeight();
$scope.iframeSize = newSize;
};
// Relay email to
$scope.relayTo = function (item) {
const lastRelayTo = $cookies.relayTo
const lastRelayTo = $cookies.relayTo;
const relayTo = prompt('Please enter email address to relay', lastRelayTo)
const relayTo = prompt(
"Please enter email address to relay",
lastRelayTo
);
if (relayTo) {
if (validateEmail(relayTo)) {
$scope.relay(item, relayTo)
$cookies.relayTo = relayTo
$scope.relay(item, relayTo);
$cookies.relayTo = relayTo;
} else {
window.alert('The specified email address is not correct.')
window.alert("The specified email address is not correct.");
}
}
}
};

@@ -149,6 +181,6 @@ // Relay email

window.alert(
'Relay feature has not been configured.\n' +
'Run maildev --help for configuration info.'
)
return
"Relay feature has not been configured.\n" +
"Run maildev --help for configuration info."
);
return;
}

@@ -158,24 +190,31 @@

window.confirm(
'Are you sure you want to REALLY SEND email to ' +
(relayTo || item.to.map(function (to) { return to.address }).join()) + ' through ' +
$rootScope.config.outgoingHost + '?'
"Are you sure you want to REALLY SEND email to " +
(relayTo ||
item.to
.map(function (to) {
return to.address;
})
.join()) +
" through " +
$rootScope.config.outgoingHost +
"?"
)
) {
$http({
method: 'POST',
url: 'email/' + item.id + '/relay' + (relayTo ? '/' + relayTo : '')
method: "POST",
url: "email/" + item.id + "/relay" + (relayTo ? "/" + relayTo : ""),
})
.success(function (data, status) {
console.log('Relay result: ', data, status)
window.alert('Relay successful')
console.log("Relay result: ", data, status);
window.alert("Relay successful");
})
.error(function (data) {
window.alert('Relay failed: ' + data.error)
})
window.alert("Relay failed: " + data.error);
});
}
}
};
// Initialize the view by getting the email
getItem()
}
])
getItem();
},
]);

@@ -19,4 +19,4 @@ 'use strict'

const outgoing = require('./outgoing')
const TurndownService = require('turndown')
const marked = require('marked')
const createDOMPurify = require('dompurify')
const { JSDOM } = require('jsdom')

@@ -272,4 +272,10 @@ const store = []

if (email.html) {
const turndownService = new TurndownService()
email.html = marked.parse(turndownService.turndown(email.html))
// sanitize html
const window = new JSDOM('').window
const DOMPurify = createDOMPurify(window)
email.html = DOMPurify.sanitize(email.html, {
WHOLE_DOCUMENT: true, // preserve html,head,body elements
SANITIZE_DOM: false, // ignore DOM cloberring to preserve form id/name attributes
ADD_TAGS: ['link'] // allow link element to preserve external style sheets
})
}

@@ -276,0 +282,0 @@ done(null, email)

{
"name": "maildev",
"description": "SMTP Server and Web Interface for reading and testing emails during development",
"version": "2.0.2",
"private": false,
"version": "2.0.3",
"keywords": [

@@ -48,5 +47,5 @@ "email",

"css-watch": "node-sass -wr --output-style compressed -o app/styles assets/styles/style.scss",
"docker-build": "docker build -t soulteary/maildev:$npm_package_version . && docker tag soulteary/maildev:$npm_package_version soulteary/maildev:latest",
"docker-run": "docker run --rm -p 1080:1080 -p 1025:1025 soulteary/maildev:$npm_package_version",
"docker-push": "docker push soulteary/maildev:$npm_package_version && docker push soulteary/maildev:latest",
"docker-build": "./scripts/dockerBuild.sh",
"docker-run": "docker run --rm -p 1080:1080 -p 1025:1025 maildev/maildev:$npm_package_version",
"docker-push": "./scripts/dockerPush.sh",
"update-readme": "node ./scripts/updateUsageREADME.js"

@@ -65,5 +64,5 @@ },

"cors": "^2.8.5",
"dompurify": "^2.3.6",
"express": "^4.17.3",
"iconv-lite": "0.5.0",
"marked": "^4.0.12",
"mime": "2.4.4",

@@ -74,3 +73,2 @@ "nodemailer": "^6.7.2",

"socket.io": "4.4.1",
"turndown": "^7.1.1",
"uue": "3.1.2"

@@ -77,0 +75,0 @@ },

@@ -5,3 +5,3 @@ # MailDev

**MailDev** is a simple way to test your project's generated emails during development with an easy to use web interface that runs on your machine. Built on top of [Node.js](http://www.nodejs.org).
**MailDev** is a simple way to test your project's generated email during development, with an easy to use web interface that runs on your machine built on top of [Node.js](http://www.nodejs.org).

@@ -13,7 +13,7 @@ ![MailDev Screenshot](https://github.com/maildev/maildev/blob/gh-pages/images/screenshot-2021-01-03.png?raw=true)

If you want to use MailDev with [Docker](https://www.docker.com/), you can use the
[**soulteary/maildev** image on Docker Hub](https://hub.docker.com/r/soulteary/maildev).
[**maildev/maildev** image on Docker Hub](https://hub.docker.com/r/maildev/maildev).
For a guide for usage with Docker,
[checkout the docs](https://github.com/maildev/maildev/blob/master/docs/docker.md).
$ docker run -p 1080:1080 -p 1025:1025 soulteary/maildev
$ docker run -p 1080:1080 -p 1025:1025 maildev/maildev

@@ -28,5 +28,5 @@ ## Usage

| -------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------- |
| `-s, --smtp <port>` | `MAILDEV_SMTP_PORT` | SMTP port to catch emails |
| `-s, --smtp <port>` | `MAILDEV_SMTP_PORT` | SMTP port to catch mail |
| `-w, --web <port>` | `MAILDEV_WEB_PORT` | Port to run the Web GUI |
| `--mail-directory <path>` | `MAILDEV_MAIL_DIRECTORY` | Directory for persisting mails |
| `--mail-directory <path>` | `MAILDEV_MAIL_DIRECTORY` | Directory for persisting mail |
| `--https` | `MAILDEV_HTTPS` | Switch from http to https protocol |

@@ -36,11 +36,11 @@ | `--https-key <file>` | `MAILDEV_HTTPS_KEY` | The file path to the ssl private key |

| `--ip <ip address>` | `MAILDEV_IP` | IP Address to bind SMTP service to |
| `--outgoing-host <host>` | `MAILDEV_OUTGOING_HOST` | SMTP host for outgoing emails |
| `--outgoing-port <port>` | `MAILDEV_OUTGOING_PORT` | SMTP port for outgoing emails |
| `--outgoing-user <user>` | `MAILDEV_OUTGOING_USER` | SMTP user for outgoing emails |
| `--outgoing-pass <password>` | `MAILDEV_OUTGOING_PASS` | SMTP password for outgoing emails |
| `--outgoing-secure` | `MAILDEV_OUTGOING_SECURE` | Use SMTP SSL for outgoing emails |
| `--outgoing-host <host>` | `MAILDEV_OUTGOING_HOST` | SMTP host for outgoing mail |
| `--outgoing-port <port>` | `MAILDEV_OUTGOING_PORT` | SMTP port for outgoing mail |
| `--outgoing-user <user>` | `MAILDEV_OUTGOING_USER` | SMTP user for outgoing mail |
| `--outgoing-pass <password>` | `MAILDEV_OUTGOING_PASS` | SMTP password for outgoing mail |
| `--outgoing-secure` | `MAILDEV_OUTGOING_SECURE` | Use SMTP SSL for outgoing mail |
| `--auto-relay [email]` | `MAILDEV_AUTO_RELAY` | Use auto-relay mode. Optional relay email address |
| `--auto-relay-rules <file>` | `MAILDEV_AUTO_RELAY_RULES` | Filter rules for auto relay mode |
| `--incoming-user <user>` | `MAILDEV_INCOMING_USER` | SMTP user for incoming emails |
| `--incoming-pass <pass>` | `MAILDEV_INCOMING_PASS` | SMTP password for incoming emails |
| `--incoming-user <user>` | `MAILDEV_INCOMING_USER` | SMTP user for incoming mail |
| `--incoming-pass <pass>` | `MAILDEV_INCOMING_PASS` | SMTP password for incoming mail |
| `--web-ip <ip address>` | `MAILDEV_WEB_IP` | IP Address to bind HTTP service to, defaults to --ip |

@@ -55,3 +55,3 @@ | `--web-user <user>` | `MAILDEV_WEB_USER` | HTTP user for GUI |

| `--silent` | | |
| `--log-mail-contents` | | Log a JSON representation of each incoming mail |
| `--log-mail-contents` | | Log a JSON representation of each incoming mail |

@@ -58,0 +58,0 @@ ## API

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet