mirror of
https://github.com/mjl-/mox.git
synced 2024-12-27 08:53:48 +03:00
use rel=noopener noreferrer on more links
and make it easier with link() function. and get rid of some globals.
This commit is contained in:
parent
79a94a47c5
commit
045d7566d4
2 changed files with 19 additions and 23 deletions
|
@ -106,16 +106,14 @@ const prop = x => { return {_prop: x} }
|
||||||
return [dom, style, attr, prop]
|
return [dom, style, attr, prop]
|
||||||
})()
|
})()
|
||||||
|
|
||||||
const tr = dom.tr
|
const link = (href, anchorOpt) => dom.a(attr({href: href, rel: 'noopener noreferrer'}), anchorOpt || href)
|
||||||
const td = dom.td
|
|
||||||
const th = dom.th
|
|
||||||
|
|
||||||
const crumblink = (text, link) => dom.a(text, attr({href: link}))
|
const crumblink = (text, link) => dom.a(text, attr({href: link}))
|
||||||
const crumbs = (...l) => [dom.h1(l.map((e, index) => index === 0 ? e : [' / ', e])), dom.br()]
|
const crumbs = (...l) => [dom.h1(l.map((e, index) => index === 0 ? e : [' / ', e])), dom.br()]
|
||||||
|
|
||||||
const footer = dom.div(
|
const footer = dom.div(
|
||||||
style({marginTop: '6ex', opacity: 0.75}),
|
style({marginTop: '6ex', opacity: 0.75}),
|
||||||
dom.a(attr({href: 'https://github.com/mjl-/mox'}), 'mox'),
|
link('https://github.com/mjl-/mox', 'mox'),
|
||||||
' ',
|
' ',
|
||||||
api._sherpa.version,
|
api._sherpa.version,
|
||||||
)
|
)
|
||||||
|
|
|
@ -107,20 +107,18 @@ const prop = x => { return {_prop: x} }
|
||||||
return [dom, style, attr, prop]
|
return [dom, style, attr, prop]
|
||||||
})()
|
})()
|
||||||
|
|
||||||
const tr = dom.tr
|
|
||||||
const td = dom.td
|
|
||||||
const th = dom.th
|
|
||||||
|
|
||||||
const green = '#1dea20'
|
const green = '#1dea20'
|
||||||
const yellow = '#ffe400'
|
const yellow = '#ffe400'
|
||||||
const red = '#ff7443'
|
const red = '#ff7443'
|
||||||
|
|
||||||
|
const link = (href, anchorOpt) => dom.a(attr({href: href, rel: 'noopener noreferrer'}), anchorOpt || href)
|
||||||
|
|
||||||
const crumblink = (text, link) => dom.a(text, attr({href: link}))
|
const crumblink = (text, link) => dom.a(text, attr({href: link}))
|
||||||
const crumbs = (...l) => [dom.h1(l.map((e, index) => index === 0 ? e : [' / ', e])), dom.br()]
|
const crumbs = (...l) => [dom.h1(l.map((e, index) => index === 0 ? e : [' / ', e])), dom.br()]
|
||||||
|
|
||||||
const footer = dom.div(
|
const footer = dom.div(
|
||||||
style({marginTop: '6ex', opacity: 0.75}),
|
style({marginTop: '6ex', opacity: 0.75}),
|
||||||
dom.a(attr({href: 'https://github.com/mjl-/mox'}), 'mox'),
|
link('https://github.com/mjl-/mox', 'mox'),
|
||||||
' ',
|
' ',
|
||||||
api._sherpa.version,
|
api._sherpa.version,
|
||||||
)
|
)
|
||||||
|
@ -533,8 +531,8 @@ const domain = async (d) => {
|
||||||
dom.div('If autoconfig/autodiscover does not work with an email client, use the settings below for this domain. Authenticate with email address and password.'),
|
dom.div('If autoconfig/autodiscover does not work with an email client, use the settings below for this domain. Authenticate with email address and password.'),
|
||||||
dom.table(
|
dom.table(
|
||||||
dom.thead(
|
dom.thead(
|
||||||
tr(
|
dom.tr(
|
||||||
th('Protocol'), th('Host'), th('Port'), th('Listener'), th('Note'),
|
dom.th('Protocol'), dom.th('Host'), dom.th('Port'), dom.th('Listener'), dom.th('Note'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dom.tbody(
|
dom.tbody(
|
||||||
|
@ -631,7 +629,7 @@ const domain = async (d) => {
|
||||||
dom.br(),
|
dom.br(),
|
||||||
dom.h2('External checks'),
|
dom.h2('External checks'),
|
||||||
dom.ul(
|
dom.ul(
|
||||||
dom.li(dom.a('Check configuration at internet.nl', attr({href: 'https://internet.nl/mail/'+dnsdomain.ASCII+'/', rel: 'noopener noreferrer'}))),
|
dom.li(link('https://internet.nl/mail/'+dnsdomain.ASCII+'/', 'Check configuration at internet.nl')),
|
||||||
),
|
),
|
||||||
dom.br(),
|
dom.br(),
|
||||||
dom.h2('Danger'),
|
dom.h2('Danger'),
|
||||||
|
@ -726,9 +724,9 @@ const domainDNSCheck = async (d) => {
|
||||||
|
|
||||||
const detailsMX = empty(checks.MX.Records) ? [] : [
|
const detailsMX = empty(checks.MX.Records) ? [] : [
|
||||||
dom.table(
|
dom.table(
|
||||||
tr(th('Preference'), th('Host'), th('IPs')),
|
dom.tr(dom.th('Preference'), dom.th('Host'), dom.th('IPs')),
|
||||||
checks.MX.Records.map(mx =>
|
checks.MX.Records.map(mx =>
|
||||||
tr(td(''+mx.Pref), td(mx.Host), td((mx.IPs || []).join(', '))),
|
dom.tr(dom.td(''+mx.Pref), dom.td(mx.Host), dom.td((mx.IPs || []).join(', '))),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -739,9 +737,9 @@ const domainDNSCheck = async (d) => {
|
||||||
]
|
]
|
||||||
const detailsDKIM = empty(checks.DKIM.Records) ? [] : [
|
const detailsDKIM = empty(checks.DKIM.Records) ? [] : [
|
||||||
dom.table(
|
dom.table(
|
||||||
tr(th('Selector'), th('TXT record')),
|
dom.tr(dom.th('Selector'), dom.th('TXT record')),
|
||||||
checks.DKIM.Records.map(rec =>
|
checks.DKIM.Records.map(rec =>
|
||||||
tr(td(rec.Selector), td(rec.TXT)),
|
dom.tr(dom.td(rec.Selector), dom.td(rec.TXT)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -759,13 +757,13 @@ const domainDNSCheck = async (d) => {
|
||||||
]
|
]
|
||||||
const detailsSRVConf = !Object.entries(checks.SRVConf.SRVs) ? [] : [
|
const detailsSRVConf = !Object.entries(checks.SRVConf.SRVs) ? [] : [
|
||||||
dom.table(
|
dom.table(
|
||||||
tr(th('Service'), th('Priority'), th('Weight'), th('Port'), th('Host')),
|
dom.tr(dom.th('Service'), dom.th('Priority'), dom.th('Weight'), dom.th('Port'), dom.th('Host')),
|
||||||
Object.entries(checks.SRVConf.SRVs).map(t => {
|
Object.entries(checks.SRVConf.SRVs).map(t => {
|
||||||
const l = t[1]
|
const l = t[1]
|
||||||
if (!l || !l.length) {
|
if (!l || !l.length) {
|
||||||
return tr(td(t[0]), td(attr({attr: '4'}), '(none)'))
|
return dom.tr(dom.td(t[0]), dom.td(attr({attr: '4'}), '(none)'))
|
||||||
}
|
}
|
||||||
return t[1].map(r => tr([t[0], r.Priority, r.Weight, r.Port, r.Target].map(s => td(''+s))))
|
return t[1].map(r => dom.tr([t[0], r.Priority, r.Weight, r.Port, r.Target].map(s => dom.td(''+s))))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -774,9 +772,9 @@ const domainDNSCheck = async (d) => {
|
||||||
]
|
]
|
||||||
const detailsAutodiscover = !checks.Autodiscover.Records ? [] : [
|
const detailsAutodiscover = !checks.Autodiscover.Records ? [] : [
|
||||||
dom.table(
|
dom.table(
|
||||||
tr(th('Host'), th('Port'), th('Priority'), th('Weight'), th('IPs')),
|
dom.tr(dom.th('Host'), dom.th('Port'), dom.th('Priority'), dom.th('Weight'), dom.th('IPs')),
|
||||||
checks.Autodiscover.Records.map(r =>
|
checks.Autodiscover.Records.map(r =>
|
||||||
tr([r.Target, r.Port, r.Priority, r.Weight, (r.IPs || []).join(', ')].map(s => td(''+s)))
|
dom.tr([r.Target, r.Port, r.Priority, r.Weight, (r.IPs || []).join(', ')].map(s => dom.td(''+s)))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -1230,7 +1228,7 @@ const mtasts = async () => {
|
||||||
crumblink('Mox Admin', '#'),
|
crumblink('Mox Admin', '#'),
|
||||||
'MTA-STS policies',
|
'MTA-STS policies',
|
||||||
),
|
),
|
||||||
dom.p("MTA-STS is a mechanism allowing email domains to publish a policy for using SMTP STARTTLS and TLS verification. See ", dom.a(attr({rel: 'noopener noreferrer', href: 'https://www.rfc-editor.org/rfc/rfc8461.html'}), 'RFC 8461'), '.'),
|
dom.p("MTA-STS is a mechanism allowing email domains to publish a policy for using SMTP STARTTLS and TLS verification. See ", link('https://www.rfc-editor.org/rfc/rfc8461.html', 'RFC 8461'), '.'),
|
||||||
dom.p("The SMTP protocol is unencrypted by default, though the SMTP STARTTLS command is typically used to enable TLS on a connection. However, MTA's using STARTTLS typically do not validate the TLS certificate. An MTA-STS policy can specify that validation of host name, non-expiration and webpki trust is required."),
|
dom.p("The SMTP protocol is unencrypted by default, though the SMTP STARTTLS command is typically used to enable TLS on a connection. However, MTA's using STARTTLS typically do not validate the TLS certificate. An MTA-STS policy can specify that validation of host name, non-expiration and webpki trust is required."),
|
||||||
makeMTASTSTable(policies),
|
makeMTASTSTable(policies),
|
||||||
)
|
)
|
||||||
|
@ -1313,7 +1311,7 @@ const dnsbl = async () => {
|
||||||
Object.entries(ipZoneResults).sort().map(ipZones => {
|
Object.entries(ipZoneResults).sort().map(ipZones => {
|
||||||
const [ip, zoneResults] = ipZones
|
const [ip, zoneResults] = ipZones
|
||||||
return dom.li(
|
return dom.li(
|
||||||
dom.a(ip, attr({href: url(ip), target: '_blank', rel: 'noopener noreferrer'})),
|
link(url(ip), ip),
|
||||||
!ipZones.length ? [] : dom.ul(
|
!ipZones.length ? [] : dom.ul(
|
||||||
Object.entries(zoneResults).sort().map(zoneResult =>
|
Object.entries(zoneResults).sort().map(zoneResult =>
|
||||||
dom.li(
|
dom.li(
|
||||||
|
|
Loading…
Reference in a new issue