mirror of
https://github.com/axllent/mailpit.git
synced 2025-01-22 03:39:59 +02:00
Merge branch 'release/v1.6.20'
This commit is contained in:
commit
3431f18a3f
@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
Notable changes to Mailpit will be documented in this file.
|
Notable changes to Mailpit will be documented in this file.
|
||||||
|
|
||||||
|
## [v1.6.20]
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
- Convert links into clickable hyperlinks in plain text message content
|
||||||
|
|
||||||
|
### Libs
|
||||||
|
- Update node modules
|
||||||
|
|
||||||
|
|
||||||
## [v1.6.19]
|
## [v1.6.19]
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
67
package-lock.json
generated
67
package-lock.json
generated
@ -36,9 +36,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.22.4",
|
"version": "7.22.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz",
|
||||||
"integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==",
|
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
},
|
},
|
||||||
@ -47,9 +47,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime-corejs3": {
|
"node_modules/@babel/runtime-corejs3": {
|
||||||
"version": "7.22.3",
|
"version": "7.22.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.22.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.22.5.tgz",
|
||||||
"integrity": "sha512-6bdmknScYKmt8I9VjsJuKKGr+TwUb555FTf6tT1P/ANlCjTHCiYLhiQ4X/O7J731w5NOqu8c1aYHEVuOwPz7jA==",
|
"integrity": "sha512-TNPDN6aBFaUox2Lu+H/Y1dKKQgr4ucz/FGyCz67RVYLsBpVpUFf1dDngzg+Od8aqbrqwyztkaZjtWCZEUOT8zA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js-pure": "^3.30.2",
|
"core-js-pure": "^3.30.2",
|
||||||
"regenerator-runtime": "^0.13.11"
|
"regenerator-runtime": "^0.13.11"
|
||||||
@ -421,9 +421,9 @@
|
|||||||
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
|
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@lit/reactive-element": {
|
"node_modules/@lit/reactive-element": {
|
||||||
"version": "1.6.1",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz",
|
||||||
"integrity": "sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==",
|
"integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lit-labs/ssr-dom-shim": "^1.0.0"
|
"@lit-labs/ssr-dom-shim": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -1063,9 +1063,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/bootstrap5-tags": {
|
"node_modules/bootstrap5-tags": {
|
||||||
"version": "1.5.22",
|
"version": "1.5.24",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.5.22.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.5.24.tgz",
|
||||||
"integrity": "sha512-wRpPtBBql6FvXKdSKUgFBkmmkGgsZJCzZ0bC9DvfHKylnQ4gS2pHpXB2UkIEWa/c+vENbBIyUDMSAvcZ4ujyQg=="
|
"integrity": "sha512-+mH9WfNnz81CFoyui8G166YLe0ASEiSPb17DMdejCVdIOu7YGuSmYFfCAz/oqdD09vKege9yU6/YyXPOlGURGQ=="
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@ -1201,9 +1201,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/core-js-pure": {
|
"node_modules/core-js-pure": {
|
||||||
"version": "3.30.2",
|
"version": "3.31.0",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.0.tgz",
|
||||||
"integrity": "sha512-p/npFUJXXBkCCTIlEGBdghofn00jWG6ZOtdoIXSJmAu2QBvN0IqpZXWweOytcwE6cfx8ZvVUy1vw8zxhe4Y2vg==",
|
"integrity": "sha512-/AnE9Y4OsJZicCzIe97JP5XoPKQJfTuEG43aEVLFJGOJpyqELod+pE6LEl63DfG1Mp8wX97LDaDpy1GmLEUxlg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -1683,9 +1683,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lit": {
|
"node_modules/lit": {
|
||||||
"version": "2.7.4",
|
"version": "2.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz",
|
||||||
"integrity": "sha512-cgD7xrZoYr21mbrkZIuIrj98YTMw/snJPg52deWVV4A8icLyNHI3bF70xsJeAgwTuiq5Kkd+ZR8gybSJDCPB7g==",
|
"integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lit/reactive-element": "^1.6.0",
|
"@lit/reactive-element": "^1.6.0",
|
||||||
"lit-element": "^3.3.0",
|
"lit-element": "^3.3.0",
|
||||||
@ -2062,9 +2062,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "1.3.2",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
"integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
|
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.11.2",
|
"version": "6.11.2",
|
||||||
@ -2080,15 +2080,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/querystring": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
|
||||||
"integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
|
|
||||||
"deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ramda": {
|
"node_modules/ramda": {
|
||||||
"version": "0.29.0",
|
"version": "0.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
|
||||||
@ -2209,9 +2200,9 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.62.1",
|
"version": "1.63.4",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz",
|
||||||
"integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==",
|
"integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
@ -2526,12 +2517,12 @@
|
|||||||
"integrity": "sha512-tdOvLfRzHolwYcHS6HIX860MkK9LQ4+oLuNwFYL7bpgTEO64PZrcQxkisgwJYCfF8sKiWLwwu1c83DvMkbefIQ=="
|
"integrity": "sha512-tdOvLfRzHolwYcHS6HIX860MkK9LQ4+oLuNwFYL7bpgTEO64PZrcQxkisgwJYCfF8sKiWLwwu1c83DvMkbefIQ=="
|
||||||
},
|
},
|
||||||
"node_modules/url": {
|
"node_modules/url": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz",
|
||||||
"integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
|
"integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"punycode": "1.3.2",
|
"punycode": "^1.4.1",
|
||||||
"querystring": "0.2.0"
|
"qs": "^6.11.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
|
@ -163,6 +163,27 @@ export default {
|
|||||||
self.scrollInPlace = true;
|
self.scrollInPlace = true;
|
||||||
self.$emit('loadMessages');
|
self.$emit('loadMessages');
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Convert plain text to HTML including anchor links
|
||||||
|
textToHTML: function (s) {
|
||||||
|
// escape to HTML
|
||||||
|
let html = s
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
|
||||||
|
// full links with http(s)
|
||||||
|
let re = /(\b(https?|ftp):\/\/[\-\w@:%_\+.~#?,&\/\/=;]+)\b/gim
|
||||||
|
html = html.replace(re, '<a href="$&" target="_blank" rel="noopener">$&</a>')
|
||||||
|
|
||||||
|
// plain www links without https?:// prefix
|
||||||
|
let re2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim
|
||||||
|
html = html.replace(re2, '$1<a href="http://$2" target="_blank" rel="noopener">$2</a>')
|
||||||
|
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,28 +293,28 @@ export default {
|
|||||||
role="tab" aria-controls="nav-html" aria-selected="true" v-if="message.HTML"
|
role="tab" aria-controls="nav-html" aria-selected="true" v-if="message.HTML"
|
||||||
v-on:click="showMobileBtns = true; resizeIframes()">HTML</button>
|
v-on:click="showMobileBtns = true; resizeIframes()">HTML</button>
|
||||||
<button class="nav-link" id="nav-html-source-tab" data-bs-toggle="tab" data-bs-target="#nav-html-source"
|
<button class="nav-link" id="nav-html-source-tab" data-bs-toggle="tab" data-bs-target="#nav-html-source"
|
||||||
type="button" role="tab" aria-controls="nav-html-source" aria-selected="false" v-if=" message.HTML "
|
type="button" role="tab" aria-controls="nav-html-source" aria-selected="false" v-if="message.HTML"
|
||||||
v-on:click=" showMobileBtns = false ">
|
v-on:click=" showMobileBtns = false">
|
||||||
HTML <span class="d-sm-none">Src</span><span class="d-none d-sm-inline">Source</span>
|
HTML <span class="d-sm-none">Src</span><span class="d-none d-sm-inline">Source</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="nav-link" id="nav-plain-text-tab" data-bs-toggle="tab" data-bs-target="#nav-plain-text"
|
<button class="nav-link" id="nav-plain-text-tab" data-bs-toggle="tab" data-bs-target="#nav-plain-text"
|
||||||
type="button" role="tab" aria-controls="nav-plain-text" aria-selected="false"
|
type="button" role="tab" aria-controls="nav-plain-text" aria-selected="false"
|
||||||
:class=" message.HTML == '' ? 'show' : '' " v-on:click=" showMobileBtns = false ">Text</button>
|
:class="message.HTML == '' ? 'show' : ''" v-on:click=" showMobileBtns = false">Text</button>
|
||||||
<button class="nav-link" id="nav-headers-tab" data-bs-toggle="tab" data-bs-target="#nav-headers"
|
<button class="nav-link" id="nav-headers-tab" data-bs-toggle="tab" data-bs-target="#nav-headers"
|
||||||
type="button" role="tab" aria-controls="nav-headers" aria-selected="false"
|
type="button" role="tab" aria-controls="nav-headers" aria-selected="false"
|
||||||
v-on:click=" showMobileBtns = false ">
|
v-on:click=" showMobileBtns = false">
|
||||||
<span class="d-sm-none">Hdrs</span><span class="d-none d-sm-inline">Headers</span>
|
<span class="d-sm-none">Hdrs</span><span class="d-none d-sm-inline">Headers</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="nav-link" id="nav-raw-tab" data-bs-toggle="tab" data-bs-target="#nav-raw" type="button"
|
<button class="nav-link" id="nav-raw-tab" data-bs-toggle="tab" data-bs-target="#nav-raw" type="button"
|
||||||
role="tab" aria-controls="nav-raw" aria-selected="false"
|
role="tab" aria-controls="nav-raw" aria-selected="false"
|
||||||
v-on:click=" showMobileBtns = false ">Raw</button>
|
v-on:click=" showMobileBtns = false">Raw</button>
|
||||||
|
|
||||||
<div class="d-none d-lg-block ms-auto me-2" v-if=" showMobileBtns ">
|
<div class="d-none d-lg-block ms-auto me-2" v-if="showMobileBtns">
|
||||||
<template v-for=" vals, key in responsiveSizes ">
|
<template v-for=" vals, key in responsiveSizes ">
|
||||||
<button class="btn" :class=" scaleHTMLPreview == key ? 'btn-outline-primary' : '' "
|
<button class="btn" :class="scaleHTMLPreview == key ? 'btn-outline-primary' : ''"
|
||||||
:disabled=" scaleHTMLPreview == key " :title=" 'Switch to ' + key + ' view' "
|
:disabled="scaleHTMLPreview == key" :title="'Switch to ' + key + ' view'"
|
||||||
v-on:click=" scaleHTMLPreview = key ">
|
v-on:click=" scaleHTMLPreview = key">
|
||||||
<i class="bi" :class=" 'bi-' + key "></i>
|
<i class="bi" :class="'bi-' + key"></i>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -301,31 +322,31 @@ export default {
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="tab-content mb-5" id="nav-tabContent">
|
<div class="tab-content mb-5" id="nav-tabContent">
|
||||||
<div v-if=" message.HTML != '' " class="tab-pane fade show" id="nav-html" role="tabpanel"
|
<div v-if="message.HTML != ''" class="tab-pane fade show" id="nav-html" role="tabpanel"
|
||||||
aria-labelledby="nav-html-tab" tabindex="0">
|
aria-labelledby="nav-html-tab" tabindex="0">
|
||||||
<div id="responsive-view" :class=" scaleHTMLPreview " :style=" responsiveSizes[scaleHTMLPreview] ">
|
<div id="responsive-view" :class="scaleHTMLPreview" :style="responsiveSizes[scaleHTMLPreview]">
|
||||||
<iframe target-blank="" class="tab-pane d-block" id="preview-html" :srcdoc=" message.HTML "
|
<iframe target-blank="" class="tab-pane d-block" id="preview-html" :srcdoc="message.HTML"
|
||||||
v-on:load=" resizeIframe " seamless frameborder="0" style="width: 100%; height: 100%;">
|
v-on:load="resizeIframe" seamless frameborder="0" style="width: 100%; height: 100%;">
|
||||||
</iframe>
|
</iframe>
|
||||||
</div>
|
</div>
|
||||||
<Attachments v-if=" allAttachments(message).length " :message=" message "
|
<Attachments v-if="allAttachments(message).length" :message="message"
|
||||||
:attachments=" allAttachments(message) "></Attachments>
|
:attachments="allAttachments(message)"></Attachments>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-html-source" role="tabpanel" aria-labelledby="nav-html-source-tab"
|
<div class="tab-pane fade" id="nav-html-source" role="tabpanel" aria-labelledby="nav-html-source-tab"
|
||||||
tabindex="0" v-if=" message.HTML ">
|
tabindex="0" v-if="message.HTML">
|
||||||
<pre><code class="language-html">{{ message.HTML }}</code></pre>
|
<pre><code class="language-html">{{ message.HTML }}</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-plain-text" role="tabpanel" aria-labelledby="nav-plain-text-tab" tabindex="0"
|
<div class="tab-pane fade" id="nav-plain-text" role="tabpanel" aria-labelledby="nav-plain-text-tab" tabindex="0"
|
||||||
:class=" message.HTML == '' ? 'show' : '' ">
|
:class="message.HTML == '' ? 'show' : ''">
|
||||||
<div class="text-view">{{ message.Text }}</div>
|
<div class="text-view" v-html="textToHTML(message.Text)"></div>
|
||||||
<Attachments v-if=" allAttachments(message).length " :message=" message "
|
<Attachments v-if="allAttachments(message).length" :message="message"
|
||||||
:attachments=" allAttachments(message) "></Attachments>
|
:attachments="allAttachments(message)"></Attachments>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-headers" role="tabpanel" aria-labelledby="nav-headers-tab" tabindex="0">
|
<div class="tab-pane fade" id="nav-headers" role="tabpanel" aria-labelledby="nav-headers-tab" tabindex="0">
|
||||||
<Headers v-if=" loadHeaders " :message=" message "></Headers>
|
<Headers v-if="loadHeaders" :message="message"></Headers>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-raw" role="tabpanel" aria-labelledby="nav-raw-tab" tabindex="0">
|
<div class="tab-pane fade" id="nav-raw" role="tabpanel" aria-labelledby="nav-raw-tab" tabindex="0">
|
||||||
<iframe v-if=" srcURI " :src=" srcURI " v-on:load=" resizeIframe " seamless frameborder="0"
|
<iframe v-if="srcURI" :src="srcURI" v-on:load="resizeIframe" seamless frameborder="0"
|
||||||
style="width: 100%; height: 300px;" id="message-src"></iframe>
|
style="width: 100%; height: 300px;" id="message-src"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user