mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-10-06 03:46:41 +08:00
update
This commit is contained in:
parent
c811e9bd9f
commit
0bc00fcbc7
5 changed files with 174 additions and 173 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
define({
"name": "wildduck",
"version": "1.0.0",
"description": "WildDuck API docs",
"title": "WildDuck API",
"url": "https://api.wildduck.email",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-09-07T07:55:56.519Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
});
|
||||
define({
"name": "wildduck",
"version": "1.0.0",
"description": "WildDuck API docs",
"title": "WildDuck API",
"url": "https://api.wildduck.email",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-09-10T07:46:13.698Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
});
|
||||
|
|
|
@ -1 +1 @@
|
|||
{
"name": "wildduck",
"version": "1.0.0",
"description": "WildDuck API docs",
"title": "WildDuck API",
"url": "https://api.wildduck.email",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-09-07T07:55:56.519Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
}
|
||||
{
"name": "wildduck",
"version": "1.0.0",
"description": "WildDuck API docs",
"title": "WildDuck API",
"url": "https://api.wildduck.email",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2018-09-10T07:46:13.698Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
}
|
||||
|
|
|
@ -50,6 +50,171 @@ module.exports = (db, server, messageHandler) => {
|
|||
});
|
||||
});
|
||||
|
||||
const putMessageHandler = async (req, res, next) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24)
|
||||
.required(),
|
||||
mailbox: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24)
|
||||
.required(),
|
||||
moveTo: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24),
|
||||
message: Joi.string()
|
||||
.regex(/^\d+(,\d+)*$|^\d+:\d+$/i)
|
||||
.required(),
|
||||
seen: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
deleted: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
flagged: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
draft: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
expires: Joi.alternatives().try(
|
||||
Joi.date(),
|
||||
Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, ''])
|
||||
.allow(false)
|
||||
),
|
||||
sess: Joi.string().max(255),
|
||||
ip: Joi.string().ip({
|
||||
version: ['ipv4', 'ipv6'],
|
||||
cidr: 'forbidden'
|
||||
})
|
||||
});
|
||||
|
||||
const result = Joi.validate(req.params, schema, {
|
||||
abortEarly: false,
|
||||
convert: true
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
res.json({
|
||||
error: result.error.message,
|
||||
code: 'InputValidationError'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
// permissions check
|
||||
if (req.user && req.user === result.value.user) {
|
||||
req.validate(roles.can(req.role).updateOwn('messages'));
|
||||
} else {
|
||||
req.validate(roles.can(req.role).updateAny('messages'));
|
||||
}
|
||||
|
||||
let user = new ObjectID(result.value.user);
|
||||
let mailbox = new ObjectID(result.value.mailbox);
|
||||
let moveTo = result.value.moveTo ? new ObjectID(result.value.moveTo) : false;
|
||||
let message = result.value.message;
|
||||
|
||||
let messageQuery;
|
||||
|
||||
if (/^\d+$/.test(message)) {
|
||||
messageQuery = Number(message);
|
||||
} else if (/^\d+(,\d+)*$/.test(message)) {
|
||||
messageQuery = {
|
||||
$in: message
|
||||
.split(',')
|
||||
.map(uid => Number(uid))
|
||||
.sort((a, b) => a - b)
|
||||
};
|
||||
} else if (/^\d+:\d+$/.test(message)) {
|
||||
let parts = message
|
||||
.split(':')
|
||||
.map(uid => Number(uid))
|
||||
.sort((a, b) => a - b);
|
||||
if (parts[0] === parts[1]) {
|
||||
messageQuery = parts[0];
|
||||
} else {
|
||||
messageQuery = {
|
||||
$gte: parts[0],
|
||||
$lte: parts[1]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
res.json({
|
||||
error: 'Invalid message identifier',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (moveTo) {
|
||||
let info;
|
||||
try {
|
||||
let data = await moveMessage({
|
||||
user,
|
||||
source: { user, mailbox },
|
||||
destination: { user, mailbox: moveTo },
|
||||
updates: result.value,
|
||||
messageQuery
|
||||
});
|
||||
info = data.info;
|
||||
} catch (err) {
|
||||
res.json({
|
||||
error: err.message,
|
||||
code: err.code
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!info || !info.destinationUid || !info.destinationUid.length) {
|
||||
res.json({
|
||||
error: 'Could not move message, check if message exists',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
mailbox: moveTo,
|
||||
id: info && info.sourceUid && info.sourceUid.map((uid, i) => [uid, info.destinationUid && info.destinationUid[i]])
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
let updated;
|
||||
try {
|
||||
updated = await updateMessage(user, mailbox, messageQuery, result.value);
|
||||
} catch (err) {
|
||||
res.json({
|
||||
error: err.message,
|
||||
code: err.code
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
res.json({
|
||||
error: 'No message matched query',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
updated
|
||||
});
|
||||
return next();
|
||||
};
|
||||
|
||||
/**
|
||||
* @api {get} /users/:user/mailboxes/:mailbox/messages List messages in a Mailbox
|
||||
* @apiName GetMessages
|
||||
|
@ -1679,7 +1844,7 @@ module.exports = (db, server, messageHandler) => {
|
|||
);
|
||||
|
||||
/**
|
||||
* @api {put} /users/:user/mailboxes/:mailbox/messages/:message Update Message information
|
||||
* @api {put} /users/:user/mailboxes/:mailbox/messages Update Message information
|
||||
* @apiName PutMessage
|
||||
* @apiGroup Messages
|
||||
* @apiDescription This method updates message flags and also allows to move messages to a different mailbox
|
||||
|
@ -1705,9 +1870,10 @@ module.exports = (db, server, messageHandler) => {
|
|||
* @apiError error Description of the error
|
||||
*
|
||||
* @apiExample {curl} Mark messages as unseen:
|
||||
* curl -i -XPUT "http://localhost:8080/users/59fc66a03e54454869460e45/mailboxes/59fc66a03e54454869460e46/messages/1,2,3" \
|
||||
* curl -i -XPUT "http://localhost:8080/users/59fc66a03e54454869460e45/mailboxes/59fc66a03e54454869460e46/messages" \
|
||||
* -H 'Content-type: application/json' \
|
||||
* -d '{
|
||||
* "message": "1,2,3",
|
||||
* "seen": false
|
||||
* }'
|
||||
*
|
||||
|
@ -1735,173 +1901,8 @@ module.exports = (db, server, messageHandler) => {
|
|||
* "error": "Database error"
|
||||
* }
|
||||
*/
|
||||
server.put(
|
||||
'/users/:user/mailboxes/:mailbox/messages/:message',
|
||||
tools.asyncifyJson(async (req, res, next) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24)
|
||||
.required(),
|
||||
mailbox: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24)
|
||||
.required(),
|
||||
moveTo: Joi.string()
|
||||
.hex()
|
||||
.lowercase()
|
||||
.length(24),
|
||||
message: Joi.string()
|
||||
.regex(/^\d+(,\d+)*$|^\d+:\d+$/i)
|
||||
.required(),
|
||||
seen: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
deleted: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
flagged: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
draft: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, '']),
|
||||
expires: Joi.alternatives().try(
|
||||
Joi.date(),
|
||||
Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 'on', 1])
|
||||
.falsy(['N', 'false', 'no', 'off', 0, ''])
|
||||
.allow(false)
|
||||
),
|
||||
sess: Joi.string().max(255),
|
||||
ip: Joi.string().ip({
|
||||
version: ['ipv4', 'ipv6'],
|
||||
cidr: 'forbidden'
|
||||
})
|
||||
});
|
||||
|
||||
const result = Joi.validate(req.params, schema, {
|
||||
abortEarly: false,
|
||||
convert: true
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
res.json({
|
||||
error: result.error.message,
|
||||
code: 'InputValidationError'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
// permissions check
|
||||
if (req.user && req.user === result.value.user) {
|
||||
req.validate(roles.can(req.role).updateOwn('messages'));
|
||||
} else {
|
||||
req.validate(roles.can(req.role).updateAny('messages'));
|
||||
}
|
||||
|
||||
let user = new ObjectID(result.value.user);
|
||||
let mailbox = new ObjectID(result.value.mailbox);
|
||||
let moveTo = result.value.moveTo ? new ObjectID(result.value.moveTo) : false;
|
||||
let message = result.value.message;
|
||||
|
||||
let messageQuery;
|
||||
|
||||
if (/^\d+$/.test(message)) {
|
||||
messageQuery = Number(message);
|
||||
} else if (/^\d+(,\d+)*$/.test(message)) {
|
||||
messageQuery = {
|
||||
$in: message
|
||||
.split(',')
|
||||
.map(uid => Number(uid))
|
||||
.sort((a, b) => a - b)
|
||||
};
|
||||
} else if (/^\d+:\d+$/.test(message)) {
|
||||
let parts = message
|
||||
.split(':')
|
||||
.map(uid => Number(uid))
|
||||
.sort((a, b) => a - b);
|
||||
if (parts[0] === parts[1]) {
|
||||
messageQuery = parts[0];
|
||||
} else {
|
||||
messageQuery = {
|
||||
$gte: parts[0],
|
||||
$lte: parts[1]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
res.json({
|
||||
error: 'Invalid message identifier',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (moveTo) {
|
||||
let info;
|
||||
try {
|
||||
let data = await moveMessage({
|
||||
user,
|
||||
source: { user, mailbox },
|
||||
destination: { user, mailbox: moveTo },
|
||||
updates: result.value,
|
||||
messageQuery
|
||||
});
|
||||
info = data.info;
|
||||
} catch (err) {
|
||||
res.json({
|
||||
error: err.message,
|
||||
code: err.code
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!info || !info.destinationUid || !info.destinationUid.length) {
|
||||
res.json({
|
||||
error: 'Could not move message, check if message exists',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
mailbox: moveTo,
|
||||
id: info && info.sourceUid && info.sourceUid.map((uid, i) => [uid, info.destinationUid && info.destinationUid[i]])
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
let updated;
|
||||
try {
|
||||
updated = await updateMessage(user, mailbox, messageQuery, result.value);
|
||||
} catch (err) {
|
||||
res.json({
|
||||
error: err.message,
|
||||
code: err.code
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
res.json({
|
||||
error: 'No message matched query',
|
||||
code: 'NoSuchMessage'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
updated
|
||||
});
|
||||
return next();
|
||||
})
|
||||
);
|
||||
server.put('/users/:user/mailboxes/:mailbox/messages/:message', tools.asyncifyJson(putMessageHandler));
|
||||
server.put('/users/:user/mailboxes/:mailbox/messages', tools.asyncifyJson(putMessageHandler));
|
||||
|
||||
/**
|
||||
* @api {delete} /users/:user/mailboxes/:mailbox/messages/:message Delete a Message
|
||||
|
|
Loading…
Add table
Reference in a new issue