Some fixes

This commit is contained in:
Tomas Bures 2019-05-25 21:18:18 +02:00
parent 640d3c2f11
commit 1270ca71f8
13 changed files with 68 additions and 73 deletions

View file

@ -987,7 +987,7 @@ const withForm = createComponentMixin([], [], (TargetClass, InnerClass) => {
let data = formStateData.map(attr => attr.get('value')).toJS();
if (self.submitFormValuesMutator) {
const newData = self.submitFormValuesMutator(data);
const newData = self.submitFormValuesMutator(data, false);
if (newData !== undefined) {
data = newData;
}
@ -1169,7 +1169,7 @@ const withForm = createComponentMixin([], [], (TargetClass, InnerClass) => {
let data = this.getFormValues();
if (this.submitFormValuesMutator) {
const newData = this.submitFormValuesMutator(data);
const newData = this.submitFormValuesMutator(data, true);
if (newData !== undefined) {
data = newData;
}

View file

@ -66,7 +66,10 @@ export default class CUD extends Component {
data.to_name = null;
}
return filterData(data, ['name', 'description', 'default_form', 'public_subscribe', 'unsubscription_mode', 'contact_email', 'homepage', 'namespace', 'to_name', 'listunsubscribe_disabled', 'send_configuration']);
return filterData(data, ['name', 'description', 'default_form', 'public_subscribe', 'unsubscription_mode',
'contact_email', 'homepage', 'namespace', 'to_name', 'listunsubscribe_disabled', 'send_configuration',
'fieldWizard'
]);
}
componentDidMount() {
@ -78,7 +81,7 @@ export default class CUD extends Component {
name: '',
description: '',
form: 'default',
default_form: null,
default_form: 'default',
public_subscribe: true,
contact_email: '',
homepage: '',

View file

@ -23,7 +23,7 @@ import {
import {withAsyncErrorHandler, withErrorHandling} from '../../lib/error-handling';
import {DeleteModalDialog} from "../../lib/modals";
import {getImportLabels} from './helpers';
import {ImportSource, inProgress, MappingType, prepInProgress} from '../../../../shared/imports';
import {ImportSource, inProgress, MappingType, prepInProgress, prepFinished} from '../../../../shared/imports';
import axios from "../../lib/axios";
import {getUrl} from "../../lib/urls";
import listStyles from "../styles.scss";
@ -113,21 +113,31 @@ export default class CUD extends Component {
data.mapping_fields_email_column = emailMapping.column || '';
}
submitFormValuesMutator(data) {
submitFormValuesMutator(data, isSubmit) {
const isEdit = !!this.props.entity;
data.source = Number.parseInt(data.source);
data.settings = {};
const formData = new FormData();
let formData, csvFileSelected = false;
if (isSubmit) {
formData = new FormData();
}
if (!isEdit) {
if (data.source === ImportSource.CSV_FILE) {
data.settings.csv = {};
// This test needs to be here because this function is also called by the form change detection mechanism
if (this.csvFile && this.csvFile.files && this.csvFile.files.length > 0) {
formData.append('csvFile', this.csvFile.files[0]);
if (isSubmit) {
formData.append('csvFile', this.csvFile.files[0]);
} else {
csvFileSelected = true;
}
}
data.settings.csv.delimiter = data.csvDelimiter.trim();
}
@ -173,12 +183,21 @@ export default class CUD extends Component {
data.mapping = mapping;
}
formData.append('entity', JSON.stringify(
filterData(data, ['name', 'description', 'source', 'settings', 'mapping_type', 'mapping'])
));
// TODO - form change detection cannot cope with FormData
if (isSubmit) {
formData.append('entity', JSON.stringify(
filterData(data, ['name', 'description', 'source', 'settings', 'mapping_type', 'mapping'])
));
return formData;
return formData;
} else {
const filteredData = filterData(data, ['name', 'description', 'source', 'settings', 'mapping_type', 'mapping']);
if (csvFileSelected) {
filteredData.csvFileSelected = true;
}
return filteredData;
}
}
initFromEntity(entity) {
@ -406,8 +425,10 @@ export default class CUD extends Component {
if (!isEdit) {
saveButtons.push(<Button key="default" type="submit" className="btn-primary" icon="check" label={t('saveAndEditSettings')}/>);
} else {
saveButtons.push(<Button key="default" type="submit" className="btn-primary" icon="check" label={t('save')}/>);
saveButtons.push(<Button key="saveAndRun" className="btn-primary" icon="check" label={t('saveAndRun')} onClickAsync={async () => await this.save(true)}/>);
if (prepFinished(status)) {
saveButtons.push(<Button key="default" type="submit" className="btn-primary" icon="check" label={t('save')}/>);
saveButtons.push(<Button key="saveAndRun" className="btn-primary" icon="check" label={t('saveAndRun')} onClickAsync={async () => await this.save(true)}/>);
}
}
return (

View file

@ -4,7 +4,7 @@
![](http://mailtrain.org/mailtrain.png)
FIXME: The info below needs to be updated !!!
# FIXME: The info below needs to be updated to v2 !!!
## Features
@ -266,7 +266,7 @@ Mailtrain uses webhooks integration to detect bounces and spam complaints. Curre
* **SendGrid** use `http://domain/webhooks/sendgrid` as the webhook URL for bounces and complaints ([instructions](https://github.com/Mailtrain-org/mailtrain/wiki/Setting-up-Webhooks-for-SendGrid))
* **Mailgun** use `http://domain/webhooks/mailgun` as the webhook URL for bounces and complaints ([instructions](https://github.com/Mailtrain-org/mailtrain/wiki/Setting-up-Webhooks-for-Mailgun))
* **ZoneMTA** use `http://domain/webhooks/zone-mta` as the webhook URL for bounces. If you install Mailtrain with the included installation script then this route gets set up automatically during the installation process
* **Postfix** This is not a webhook but a TCP server on port 5699 to listen for piped Postfix logs. Enable it with the `[postfixbounce]` config option. To use it, pipe the log to that port using *tail*: `tail -F /var/log/mail.log | nc localhost 5699 -` (if Mailtrain restarts then you need to re-establish the *tail* pipe), alternatively you could send the log with a cron job periodically `tail -n 100 | nc localhost 5699 -`.
* **Postfix** This is not a webhook but a TCP server on port 5699 to listen for piped Postfix logs. Enable it with the `[postfixBounce]` config option. To use it, pipe the log to that port using *tail*: `tail -F /var/log/mail.log | nc localhost 5699 -` (if Mailtrain restarts then you need to re-establish the *tail* pipe), alternatively you could send the log with a cron job periodically `tail -n 100 | nc localhost 5699 -`.
Additionally Mailtrain (v1.1+) is able to use VERP-based bounce handling. This would require to have a compatible SMTP relay (the services mentioned above strip out or block VERP addresses in the SMTP envelope) and you also need to set up special MX DNS name that points to your Mailtrain installation server.

View file

@ -148,7 +148,7 @@ ldap:
bindUser: name@company.net
bindPassword: mySecretPassword
postfixbounce:
postfixBounce:
# Enable to allow writing Postfix bounce log to Mailtrain listener
# If enabled, tail mail.log to Mailtrain with the following command:
# tail -f -n +0 /var/log/mail.log | nc localhost 5699 -

View file

@ -38,6 +38,16 @@ if (config.title) {
process.title = config.title;
}
/*
const cleanExit = () => process.exit();
process.on('SIGINT', cleanExit); // catch ctrl-c
process.on('SIGTERM', cleanExit); // catch kill
process.on('exit', function() {
// TODO
});
*/
async function startHTTPServer(appType, appName, port) {
const app = await appBuilder.createApp(appType);
@ -99,8 +109,8 @@ async function init() {
await privilegeHelpers.ensureMailtrainDir(reportFilesDir);
await executor.spawn();
await testServer.spawn();
await verpServer.spawn();
await testServer.start();
await verpServer.start();
await builtinZoneMta.spawn();
await startHTTPServer(AppType.TRUSTED, 'trusted', trustedPort);
@ -118,7 +128,7 @@ async function init() {
triggers.start();
gdprCleanup.start();
await postfixBounceServer.spawn();
await postfixBounceServer.start();
await reportProcessor.init();

View file

@ -49,7 +49,7 @@ function spawn(callback) {
});
executorProcess.on('close', (code, signal) => {
log.info('Executor', 'Executor process exited with code %s signal %s', code, signal);
log.error('Executor', 'Executor process exited with code %s signal %s', code, signal);
});
}

View file

@ -83,8 +83,8 @@ async function readNextChunks() {
}
}
function spawn(callback) {
if (!config.postfixbounce.enabled) {
function start(callback) {
if (!config.postfixBounce.enabled) {
return setImmediate(callback);
}
@ -95,7 +95,7 @@ function spawn(callback) {
});
server.on('error', err => {
const port = config.postfixbounce.port;
const port = config.postfixBounce.port;
const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
switch (err.code) {
@ -115,15 +115,15 @@ function spawn(callback) {
}
});
server.listen(config.postfixbounce.port, config.postfixbounce.host, () => {
server.listen(config.postfixBounce.port, config.postfixBounce.host, () => {
if (started) {
return server.close();
}
started = true;
log.info('POSTFIXBOUNCE', 'Server listening on port %s', config.postfixbounce.port);
log.info('POSTFIXBOUNCE', 'Server listening on port %s', config.postfixBounce.port);
setImmediate(callback);
});
}
module.exports.spawn = bluebird.promisify(spawn);
module.exports.start = bluebird.promisify(start);

View file

@ -166,7 +166,7 @@ mailBoxServer.on('error', err => {
log.error('Test SMTP Mailbox Server', err);
});
function spawn(callback) {
function start(callback) {
if (config.testServer.enabled) {
server.listen(config.testServer.port, config.testServer.host, () => {
log.info('Test SMTP', 'Server listening on port %s', config.testServer.port);
@ -194,4 +194,4 @@ function spawn(callback) {
}
}
module.exports.spawn = bluebird.promisify(spawn);
module.exports.start = bluebird.promisify(start);

View file

@ -48,7 +48,4 @@ function start() {
lastCheck = curUtcDate;
}
module.exports = {
start
};
module.exports.start = start;

View file

@ -86,7 +86,7 @@ const server = new SMTPServer({
onData: onData
});
function spawn(callback) {
function start(callback) {
if (!config.verp.enabled) {
return setImmediate(callback);
}
@ -145,4 +145,4 @@ function spawn(callback) {
startNextHost();
}
module.exports.spawn = bluebird.promisify(spawn);
module.exports.start = bluebird.promisify(start);

View file

@ -1,36 +0,0 @@
#!/bin/bash
# This installation script works on Ubuntu 14.04 and 16.04
# Run as root!
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
set -e
export DEBIAN_FRONTEND=noninteractive
# Setup MySQL user for Mailtrain
mysql -u root --password="$ROOT_PASS" -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
mysql -u root --password="$ROOT_PASS" -e "GRANT ALL PRIVILEGES ON '$DB_USER'.* TO '$DB_USER'@'localhost';"
mysql -u "$DB_USER" --password="$DB_PASS" -e "CREATE database $DB_USER;"
mysql -u "$DB_USER" -p"$DB_PASS" "$DB_USER" < setup/sql/mailtrain.sql
mysql -u mailtrain -p"$MYSQL_PASSWORD" mailtrain <<EOT
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('admin_email','admin@$HOSTNAME') ON DUPLICATE KEY UPDATE \`value\`='admin@$HOSTNAME';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('default_address','admin@$HOSTNAME') ON DUPLICATE KEY UPDATE \`value\`='admin@$HOSTNAME';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_hostname','localhost') ON DUPLICATE KEY UPDATE \`value\`='localhost';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_disable_auth','') ON DUPLICATE KEY UPDATE \`value\`='';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_user','mailtrain') ON DUPLICATE KEY UPDATE \`value\`='mailtrain';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_pass','$SMTP_PASS') ON DUPLICATE KEY UPDATE \`value\`='$SMTP_PASS';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_encryption','NONE') ON DUPLICATE KEY UPDATE \`value\`='NONE';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_port','2525') ON DUPLICATE KEY UPDATE \`value\`='2525';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('default_homepage','http://$HOSTNAME/') ON DUPLICATE KEY UPDATE \`value\`='http://$HOSTNAME/';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('service_url','http://$HOSTNAME/') ON DUPLICATE KEY UPDATE \`value\`='http://$HOSTNAME/';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('dkim_api_key','$DKIM_API_KEY') ON DUPLICATE KEY UPDATE \`value\`='$DKIM_API_KEY';
EOT
echo "OK"

View file

@ -1,7 +1,7 @@
'use strict';
let faker = require('faker');
let accounts = 100 * 1000;
let accounts = 1000 * 1000;
let row = 0;
let getNext = () => {