-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactored larger chunks of code into lib/*
- Loading branch information
Showing
6 changed files
with
208 additions
and
192 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
'use strict' | ||
|
||
const net = require('node:net') | ||
const url = require('node:url') | ||
|
||
class HarakaMx { | ||
constructor(obj = {}, domain) { | ||
switch (typeof obj) { | ||
case 'string': | ||
/mtp:\/\//.test(obj) ? this.fromUrl(obj) : this.fromString(obj) | ||
break | ||
case 'object': | ||
this.fromObject(obj) | ||
break | ||
} | ||
|
||
if (this.priority === undefined) this.priority = 0 | ||
if (domain && this.from_dns === undefined) { | ||
this.from_dns = domain.toLowerCase() | ||
} | ||
} | ||
|
||
fromObject(obj) { | ||
for (const prop of [ | ||
'exchange', | ||
'priority', | ||
'port', | ||
'bind', | ||
'bind_helo', | ||
'using_lmtp', | ||
'auth_user', | ||
'auth_pass', | ||
'auth_type', | ||
'from_dns', | ||
]) { | ||
if (obj[prop] !== undefined) this[prop] = obj[prop] | ||
} | ||
} | ||
|
||
fromString(str) { | ||
const matches = /^\[?(.*?)\]?(?::(24|25|465|587|\d{4,5}))?$/.exec(str) | ||
if (matches) { | ||
this.exchange = matches[1].toLowerCase() | ||
if (matches[2]) this.port = parseInt(matches[2]) | ||
} else { | ||
this.exchange = str | ||
} | ||
} | ||
|
||
fromUrl(str) { | ||
const dest = new url.URL(str) | ||
|
||
switch (dest.protocol) { | ||
case 'smtp:': | ||
if (!dest.port) dest.port = 25 | ||
break | ||
case 'lmtp:': | ||
this.using_lmtp = true | ||
if (!dest.port) dest.port = 24 | ||
break | ||
} | ||
|
||
if (dest.hostname) this.exchange = dest.hostname.toLowerCase() | ||
if (dest.port) this.port = parseInt(dest.port) | ||
if (dest.username) this.auth_user = dest.username | ||
if (dest.password) this.auth_pass = dest.password | ||
} | ||
|
||
toUrl() { | ||
const proto = this.using_lmtp ? 'lmtp://' : 'smtp://' | ||
const auth = this.auth_user ? `${this.auth_user}:****@` : '' | ||
const host = net.isIPv6(this.exchange) | ||
? `[${this.exchange}]` | ||
: this.exchange | ||
const port = this.port ? this.port : proto === 'lmtp://' ? 24 : 25 | ||
return new url.URL(`${proto}${auth}${host}:${port}`) | ||
} | ||
|
||
toString() { | ||
const from_dns = this.from_dns ? ` (from ${this.from_dns})` : '' | ||
return `MX ${this.priority} ${this.toUrl()}${from_dns}` | ||
} | ||
} | ||
|
||
exports.HarakaMx = HarakaMx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
'use strict' | ||
|
||
exports.config = require('haraka-config') | ||
|
||
exports.get_public_ip_async = async function () { | ||
if (this.public_ip !== undefined) return this.public_ip // cache | ||
|
||
// manual config override, for the cases where we can't figure it out | ||
const smtpIni = exports.config.get('smtp.ini').main | ||
if (smtpIni.public_ip) { | ||
this.public_ip = smtpIni.public_ip | ||
return this.public_ip | ||
} | ||
|
||
// Initialise cache value to null to prevent running | ||
// should we hit a timeout or the module isn't installed. | ||
this.public_ip = null | ||
|
||
try { | ||
this.stun = require('@msimerson/stun') | ||
} catch (e) { | ||
e.install = 'Please install stun: "npm install -g stun"' | ||
console.error(`${e.msg}\n${e.install}`) | ||
return | ||
} | ||
|
||
const timeout = 10 | ||
const timer = setTimeout(() => { | ||
return new Error('STUN timeout') | ||
}, timeout * 1000) | ||
|
||
// Connect to STUN Server | ||
const res = await this.stun.request(get_stun_server(), { | ||
maxTimeout: (timeout - 1) * 1000, | ||
}) | ||
this.public_ip = res.getXorAddress().address | ||
clearTimeout(timer) | ||
return this.public_ip | ||
} | ||
|
||
exports.get_public_ip = async function (cb) { | ||
if (!cb) return exports.get_public_ip_async() | ||
|
||
if (this.public_ip !== undefined) return cb(null, this.public_ip) // cache | ||
|
||
// manual config override, for the cases where we can't figure it out | ||
const smtpIni = exports.config.get('smtp.ini').main | ||
if (smtpIni.public_ip) { | ||
this.public_ip = smtpIni.public_ip | ||
return cb(null, this.public_ip) | ||
} | ||
|
||
// Initialise cache value to null to prevent running | ||
// should we hit a timeout or the module isn't installed. | ||
this.public_ip = null | ||
|
||
try { | ||
this.stun = require('@msimerson/stun') | ||
} catch (e) { | ||
e.install = 'Please install stun: "npm install -g stun"' | ||
console.error(`${e.msg}\n${e.install}`) | ||
return cb(e) | ||
} | ||
|
||
const timeout = 10 | ||
const timer = setTimeout(() => { | ||
return cb(new Error('STUN timeout')) | ||
}, timeout * 1000) | ||
|
||
// Connect to STUN Server | ||
this.stun.request( | ||
get_stun_server(), | ||
{ maxTimeout: (timeout - 1) * 1000 }, | ||
(error, res) => { | ||
if (timer) clearTimeout(timer) | ||
if (error) return cb(error) | ||
|
||
this.public_ip = res.getXorAddress().address | ||
cb(null, this.public_ip) | ||
}, | ||
) | ||
} | ||
|
||
function get_stun_server() { | ||
const servers = [ | ||
'stun.l.google.com:19302', | ||
'stun1.l.google.com:19302', | ||
'stun2.l.google.com:19302', | ||
'stun3.l.google.com:19302', | ||
'stun4.l.google.com:19302', | ||
] | ||
return servers[Math.floor(Math.random() * servers.length)] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.