mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-12-31 04:33:09 +08:00
180 lines
4.6 KiB
JavaScript
180 lines
4.6 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const config = require('config');
|
||
|
const restify = require('restify');
|
||
|
const log = require('npmlog');
|
||
|
const mongodb = require('mongodb');
|
||
|
const MongoClient = mongodb.MongoClient;
|
||
|
const Joi = require('joi');
|
||
|
const bcrypt = require('bcryptjs');
|
||
|
const punycode = require('punycode');
|
||
|
|
||
|
let database;
|
||
|
|
||
|
const server = restify.createServer();
|
||
|
|
||
|
server.use(restify.bodyParser({
|
||
|
maxBodySize: 0,
|
||
|
mapParams: true,
|
||
|
mapFiles: false,
|
||
|
overrideParams: false
|
||
|
}));
|
||
|
|
||
|
server.post('/user/create', (req, res, next) => {
|
||
|
const schema = Joi.object().keys({
|
||
|
username: Joi.string().email().required(),
|
||
|
password: Joi.string().min(3).max(100).required()
|
||
|
});
|
||
|
|
||
|
const result = Joi.validate(req.params, schema, {
|
||
|
abortEarly: false,
|
||
|
convert: true,
|
||
|
allowUnknown: true
|
||
|
});
|
||
|
|
||
|
if (result.error) {
|
||
|
res.json({
|
||
|
error: result.error.message
|
||
|
});
|
||
|
return next();
|
||
|
}
|
||
|
|
||
|
let username = normalizeAddress(result.value.username);
|
||
|
let password = result.value.password;
|
||
|
|
||
|
database.collection('users').findOne({
|
||
|
username
|
||
|
}, (err, user) => {
|
||
|
if (err) {
|
||
|
return res.json({
|
||
|
error: 'MongoDB Error: ' + err.message,
|
||
|
username
|
||
|
});
|
||
|
}
|
||
|
if (user) {
|
||
|
return res.json({
|
||
|
error: 'This username already exists',
|
||
|
username
|
||
|
});
|
||
|
}
|
||
|
|
||
|
let hash = bcrypt.hashSync(password, 8);
|
||
|
database.collection('users').insertOne({
|
||
|
username,
|
||
|
password: hash
|
||
|
}, (err, result) => {
|
||
|
if (err) {
|
||
|
return res.json({
|
||
|
error: 'MongoDB Error: ' + err.message,
|
||
|
username
|
||
|
});
|
||
|
}
|
||
|
|
||
|
let uidValidity = Math.floor(Date.now() / 1000);
|
||
|
|
||
|
database.collection('mailboxes').insertMany([{
|
||
|
username,
|
||
|
path: 'INBOX',
|
||
|
uidValidity,
|
||
|
uidNext: 1,
|
||
|
modifyIndex: 0,
|
||
|
subscribed: true
|
||
|
}, {
|
||
|
username,
|
||
|
path: 'Sent Mail',
|
||
|
specialUse: '\\Sent',
|
||
|
uidValidity,
|
||
|
uidNext: 1,
|
||
|
modifyIndex: 0,
|
||
|
subscribed: true
|
||
|
}, {
|
||
|
username,
|
||
|
path: 'Trash',
|
||
|
specialUse: '\\Trash',
|
||
|
uidValidity,
|
||
|
uidNext: 1,
|
||
|
modifyIndex: 0,
|
||
|
subscribed: true
|
||
|
}, {
|
||
|
username,
|
||
|
path: 'Junk',
|
||
|
specialUse: '\\Junk',
|
||
|
uidValidity,
|
||
|
uidNext: 1,
|
||
|
modifyIndex: 0,
|
||
|
subscribed: true
|
||
|
}], {
|
||
|
w: 1,
|
||
|
ordered: false
|
||
|
}, err => {
|
||
|
if (err) {
|
||
|
return res.json({
|
||
|
error: 'MongoDB Error: ' + err.message,
|
||
|
username
|
||
|
});
|
||
|
}
|
||
|
|
||
|
res.json({
|
||
|
success: true,
|
||
|
id: result.insertedId,
|
||
|
username
|
||
|
});
|
||
|
|
||
|
return next();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function normalizeAddress(address, withNames) {
|
||
|
if (typeof address === 'string') {
|
||
|
address = {
|
||
|
address
|
||
|
};
|
||
|
}
|
||
|
if (!address || !address.address) {
|
||
|
return '';
|
||
|
}
|
||
|
let user = address.address.substr(0, address.address.lastIndexOf('@'));
|
||
|
let domain = address.address.substr(address.address.lastIndexOf('@') + 1);
|
||
|
let addr = user.trim() + '@' + punycode.toASCII(domain.toLowerCase().trim());
|
||
|
|
||
|
if (withNames) {
|
||
|
return {
|
||
|
name: address.name || '',
|
||
|
address: addr
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return addr;
|
||
|
}
|
||
|
|
||
|
module.exports = (imap, done) => {
|
||
|
MongoClient.connect(config.mongo, (err, mongo) => {
|
||
|
if (err) {
|
||
|
log.error('LMTP', 'Could not initialize MongoDB: %s', err.message);
|
||
|
return;
|
||
|
}
|
||
|
database = mongo;
|
||
|
|
||
|
let started = false;
|
||
|
|
||
|
server.on('error', err => {
|
||
|
if (!started) {
|
||
|
started = true;
|
||
|
return done(err);
|
||
|
}
|
||
|
log.error('API', err);
|
||
|
});
|
||
|
|
||
|
server.listen(config.api.port, config.api.host, () => {
|
||
|
if (started) {
|
||
|
return server.close();
|
||
|
}
|
||
|
started = true;
|
||
|
log.info('API', 'Server listening on %s:%s', config.api.host || '0.0.0.0', config.api.port);
|
||
|
done(null, server);
|
||
|
});
|
||
|
});
|
||
|
};
|