relay: remove usage of secret placeholder
This commit is contained in:
225
src/mail.js
225
src/mail.js
@@ -1,65 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports = module.exports = {
|
||||
getStatus,
|
||||
checkConfiguration,
|
||||
|
||||
listDomains,
|
||||
|
||||
getDomain,
|
||||
clearDomains,
|
||||
|
||||
removePrivateFields,
|
||||
|
||||
setDnsRecords,
|
||||
upsertDnsRecords,
|
||||
|
||||
validateName,
|
||||
validateDisplayName,
|
||||
|
||||
setMailFromValidation,
|
||||
setCatchAllAddress,
|
||||
setMailRelay,
|
||||
setMailEnabled,
|
||||
setBanner,
|
||||
|
||||
sendTestMail,
|
||||
|
||||
getMailboxCount,
|
||||
listMailboxes,
|
||||
listAllMailboxes,
|
||||
getMailbox,
|
||||
addMailbox,
|
||||
updateMailbox,
|
||||
delMailbox,
|
||||
|
||||
getAlias,
|
||||
getAliases,
|
||||
setAliases,
|
||||
searchAlias,
|
||||
|
||||
getListCount,
|
||||
getLists,
|
||||
getList,
|
||||
addList,
|
||||
updateList,
|
||||
delList,
|
||||
resolveList,
|
||||
|
||||
checkStatus,
|
||||
|
||||
OWNERTYPE_USER: 'user',
|
||||
OWNERTYPE_GROUP: 'group',
|
||||
OWNERTYPE_APP: 'app',
|
||||
|
||||
TYPE_MAILBOX: 'mailbox',
|
||||
TYPE_LIST: 'list',
|
||||
TYPE_ALIAS: 'alias',
|
||||
|
||||
_delByDomain: delByDomain,
|
||||
_updateDomain: updateDomain
|
||||
};
|
||||
|
||||
const assert = require('node:assert'),
|
||||
BoxError = require('./boxerror.js'),
|
||||
constants = require('./constants.js'),
|
||||
@@ -171,6 +111,44 @@ function validateDisplayName(name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getDomain(domain) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
|
||||
const result = await database.query(`SELECT ${MAILDB_FIELDS} FROM mail WHERE domain = ?`, [ domain ]);
|
||||
if (result.length === 0) return null;
|
||||
return postProcessDomain(result[0]);
|
||||
}
|
||||
|
||||
async function updateDomain(domain, data) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
assert.strictEqual(typeof data, 'object');
|
||||
|
||||
const args = [ ];
|
||||
const fields = [ ];
|
||||
for (const k in data) {
|
||||
if (k === 'catchAll' || k === 'banner') {
|
||||
fields.push(`${k}Json = ?`);
|
||||
args.push(JSON.stringify(data[k]));
|
||||
} else if (k === 'relay') {
|
||||
fields.push('relayJson = ?');
|
||||
args.push(JSON.stringify(data[k]));
|
||||
} else {
|
||||
fields.push(k + ' = ?');
|
||||
args.push(data[k]);
|
||||
}
|
||||
}
|
||||
args.push(domain);
|
||||
|
||||
const result = await database.query('UPDATE mail SET ' + fields.join(', ') + ' WHERE domain=?', args);
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Mail domain not found');
|
||||
}
|
||||
|
||||
async function listDomains() {
|
||||
const results = await database.query(`SELECT ${MAILDB_FIELDS} FROM mail ORDER BY domain`);
|
||||
results.forEach(function (result) { postProcessDomain(result); });
|
||||
return results;
|
||||
}
|
||||
|
||||
async function checkOutboundPort25() {
|
||||
return await new Promise((resolve) => {
|
||||
const client = new net.Socket();
|
||||
@@ -227,6 +205,15 @@ async function checkSmtpRelay(relay) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function txtToDict(txt) {
|
||||
const dict = {};
|
||||
txt.split(';').forEach(function(v) {
|
||||
const p = v.trim().split('=');
|
||||
dict[p[0]]=p[1];
|
||||
});
|
||||
return dict;
|
||||
}
|
||||
|
||||
async function checkDkim(mailDomain) {
|
||||
assert.strictEqual(typeof mailDomain, 'object');
|
||||
|
||||
@@ -337,15 +324,6 @@ async function checkMx(mailDomain, mailFqdn) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function txtToDict(txt) {
|
||||
const dict = {};
|
||||
txt.split(';').forEach(function(v) {
|
||||
const p = v.trim().split('=');
|
||||
dict[p[0]]=p[1];
|
||||
});
|
||||
return dict;
|
||||
}
|
||||
|
||||
async function checkDmarc(mailDomain) {
|
||||
assert.strictEqual(typeof mailDomain, 'object');
|
||||
|
||||
@@ -621,44 +599,6 @@ async function checkConfiguration() {
|
||||
return { status: markdownMessage === '', message: markdownMessage };
|
||||
}
|
||||
|
||||
async function getDomain(domain) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
|
||||
const result = await database.query(`SELECT ${MAILDB_FIELDS} FROM mail WHERE domain = ?`, [ domain ]);
|
||||
if (result.length === 0) return null;
|
||||
return postProcessDomain(result[0]);
|
||||
}
|
||||
|
||||
async function updateDomain(domain, data) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
assert.strictEqual(typeof data, 'object');
|
||||
|
||||
const args = [ ];
|
||||
const fields = [ ];
|
||||
for (const k in data) {
|
||||
if (k === 'catchAll' || k === 'banner') {
|
||||
fields.push(`${k}Json = ?`);
|
||||
args.push(JSON.stringify(data[k]));
|
||||
} else if (k === 'relay') {
|
||||
fields.push('relayJson = ?');
|
||||
args.push(JSON.stringify(data[k]));
|
||||
} else {
|
||||
fields.push(k + ' = ?');
|
||||
args.push(data[k]);
|
||||
}
|
||||
}
|
||||
args.push(domain);
|
||||
|
||||
const result = await database.query('UPDATE mail SET ' + fields.join(', ') + ' WHERE domain=?', args);
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Mail domain not found');
|
||||
}
|
||||
|
||||
async function listDomains() {
|
||||
const results = await database.query(`SELECT ${MAILDB_FIELDS} FROM mail ORDER BY domain`);
|
||||
results.forEach(function (result) { postProcessDomain(result); });
|
||||
return results;
|
||||
}
|
||||
|
||||
// https://agari.zendesk.com/hc/en-us/articles/202952749-How-long-can-my-SPF-record-be-
|
||||
async function txtRecordsWithSpf(domain, mailFqdn) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
@@ -738,12 +678,11 @@ async function clearDomains() {
|
||||
await database.query('DELETE FROM mail', []);
|
||||
}
|
||||
|
||||
// remove all fields that should never be sent out via REST API
|
||||
function removePrivateFields(domain) {
|
||||
const result = _.pick(domain, ['domain', 'enabled', 'mailFromValidation', 'catchAll', 'relay', 'banner']);
|
||||
if ('password' in result.relay) {
|
||||
if ('username' in result.relay && result.relay.username === result.relay.password) result.relay.username = constants.SECRET_PLACEHOLDER;
|
||||
result.relay.password = constants.SECRET_PLACEHOLDER;
|
||||
if ('username' in result.relay && result.relay.username === result.relay.password) delete result.relay.username;
|
||||
delete result.relay.password;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -788,8 +727,10 @@ async function setMailRelay(domain, relay, options) {
|
||||
if (!domain) throw new BoxError(BoxError.NOT_FOUND, 'Mail domain not found');
|
||||
|
||||
// inject current username/password
|
||||
if (relay.username === constants.SECRET_PLACEHOLDER) relay.username = result.relay.username;
|
||||
if (relay.password === constants.SECRET_PLACEHOLDER) relay.password = result.relay.password;
|
||||
if ('password' in result.relay) {
|
||||
if (!Object.hasOwn(relay, 'username')) relay.username = result.relay.username;
|
||||
if (!Object.hasOwn(relay, 'password')) relay.password = result.relay.password;
|
||||
}
|
||||
|
||||
if (!options.skipVerify) {
|
||||
const result = await checkSmtpRelay(relay);
|
||||
@@ -1235,3 +1176,63 @@ async function checkStatus() {
|
||||
await notifications.pin(notifications.TYPE_MAIL_STATUS, 'Email is not configured properly', result.message, {});
|
||||
}
|
||||
}
|
||||
|
||||
exports = module.exports = {
|
||||
getStatus,
|
||||
checkConfiguration,
|
||||
|
||||
listDomains,
|
||||
|
||||
getDomain,
|
||||
clearDomains,
|
||||
|
||||
removePrivateFields,
|
||||
|
||||
setDnsRecords,
|
||||
upsertDnsRecords,
|
||||
|
||||
validateName,
|
||||
validateDisplayName,
|
||||
|
||||
setMailFromValidation,
|
||||
setCatchAllAddress,
|
||||
setMailRelay,
|
||||
setMailEnabled,
|
||||
setBanner,
|
||||
|
||||
sendTestMail,
|
||||
|
||||
getMailboxCount,
|
||||
listMailboxes,
|
||||
listAllMailboxes,
|
||||
getMailbox,
|
||||
addMailbox,
|
||||
updateMailbox,
|
||||
delMailbox,
|
||||
|
||||
getAlias,
|
||||
getAliases,
|
||||
setAliases,
|
||||
searchAlias,
|
||||
|
||||
getListCount,
|
||||
getLists,
|
||||
getList,
|
||||
addList,
|
||||
updateList,
|
||||
delList,
|
||||
resolveList,
|
||||
|
||||
checkStatus,
|
||||
|
||||
OWNERTYPE_USER: 'user',
|
||||
OWNERTYPE_GROUP: 'group',
|
||||
OWNERTYPE_APP: 'app',
|
||||
|
||||
TYPE_MAILBOX: 'mailbox',
|
||||
TYPE_LIST: 'list',
|
||||
TYPE_ALIAS: 'alias',
|
||||
|
||||
_delByDomain: delByDomain,
|
||||
_updateDomain: updateDomain
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user