-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b487340
commit 0fbfbe9
Showing
10 changed files
with
533 additions
and
28 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
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 |
---|---|---|
|
@@ -131,4 +131,4 @@ function runClientMockup(port, host, commands, debug, callback) { | |
} | ||
}); | ||
}); | ||
} | ||
} |
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 |
---|---|---|
|
@@ -257,4 +257,4 @@ function getCondstoreValue(attributes, name, parent, index) { | |
} | ||
|
||
return condstoreValue; | ||
} | ||
} |
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,112 @@ | ||
"use strict"; | ||
|
||
/** | ||
* MOVE: http://tools.ietf.org/html/rfc6851 | ||
* | ||
* Additional commands: | ||
* - MOVE | ||
* - UID MOVE | ||
*/ | ||
module.exports = function(server) { | ||
server.registerCapability("MOVE"); | ||
|
||
var moveHandler = function(uidMode, connection, parsed, data, callback) { | ||
function uidify(str) { | ||
if (uidMode) { | ||
return "UID " + str; | ||
} | ||
return str; | ||
} | ||
|
||
if (!parsed.attributes || | ||
parsed.attributes.length !== 2 || | ||
!parsed.attributes[0] || | ||
["ATOM", "SEQUENCE"].indexOf(parsed.attributes[0].type) < 0 || | ||
!parsed.attributes[1] || | ||
["ATOM", "STRING"].indexOf(parsed.attributes[1].type) < 0 | ||
) { | ||
connection.send({ | ||
tag: parsed.tag, | ||
command: "BAD", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: uidify("MOVE expects sequence set and a mailbox name") | ||
}] | ||
}, "INVALID COMMAND", parsed, data); | ||
return callback(); | ||
} | ||
|
||
if (["Selected"].indexOf(connection.state) < 0) { | ||
connection.send({ | ||
tag: parsed.tag, | ||
command: "BAD", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "Select mailbox first" | ||
}] | ||
}, uidify("MOVE FAILED"), parsed, data); | ||
return callback(); | ||
} | ||
|
||
var sequence = parsed.attributes[0].value, | ||
path = parsed.attributes[1].value, | ||
mailbox = connection.server.getMailbox(path), | ||
range = connection.server.getMessageRange(connection.selectedMailbox, sequence, uidMode); | ||
|
||
if (!mailbox) { | ||
connection.send({ | ||
tag: parsed.tag, | ||
command: "NO", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "Target mailbox does not exist" | ||
}] | ||
}, uidify("MOVE FAIL"), parsed, data); | ||
return callback(); | ||
} | ||
|
||
var rangeMessages = range.map(function(x) { return x[1]; }); | ||
|
||
var sourceUids = [], | ||
targetUids = []; | ||
rangeMessages.forEach(function(message) { | ||
var flags = [].concat(message.flags || []), | ||
internaldate = message.internaldate; | ||
sourceUids.push(message.uid); | ||
|
||
var appendResult = connection.server.appendMessage(mailbox, flags, internaldate, message.raw, connection); | ||
targetUids.push(appendResult.message.uid); | ||
}); | ||
|
||
// Hook for UIDPLUS to generate the untagged COPYUID response (that wants | ||
// to happen prior to the EXPUNGEs). If the UIDPLUS extension is not | ||
// active, this ill not happen. | ||
var extra = { | ||
mailbox: mailbox, | ||
sourceUids: sourceUids, | ||
targetUids: targetUids | ||
}; | ||
connection.send({ | ||
tag: "*", | ||
command: "OK", | ||
attributes: [], | ||
skipResponse: true | ||
}, uidify("MOVE COPYUID"), parsed, data, extra); | ||
|
||
// Expunge the messages from the source folder. | ||
connection.expungeSpecificMessages(connection.selectedMailbox, rangeMessages, false, true); | ||
|
||
connection.send({ | ||
tag: parsed.tag, | ||
command: "OK", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "Done" | ||
}] | ||
}, uidify("MOVE OK"), parsed, data); | ||
callback(); | ||
}; | ||
|
||
server.setCommandHandler("MOVE", moveHandler.bind(null, false)); | ||
server.setCommandHandler("UID MOVE", moveHandler.bind(null, true)); | ||
}; |
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,110 @@ | ||
"use strict"; | ||
|
||
/** | ||
* UIDPLUS: http://tools.ietf.org/html/rfc4315 | ||
* | ||
* Additional commands: | ||
* - UID EXPUNGE | ||
* | ||
* Additional response codes: | ||
* - APPENDUID | ||
* - COPYUID | ||
* - Not implemented: UIDNOTSTICKY | ||
*/ | ||
module.exports = function(server) { | ||
server.registerCapability("UIDPLUS"); | ||
|
||
server.setCommandHandler("UID EXPUNGE", function(connection, parsed, data, callback) { | ||
if (!parsed.attributes || | ||
parsed.attributes.length !== 1 || | ||
!parsed.attributes[0] || | ||
["ATOM", "SEQUENCE"].indexOf(parsed.attributes[0].type) < 0 | ||
) { | ||
connection.send({ | ||
tag: parsed.tag, | ||
command: "BAD", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "UID EXPUNGE expects uid sequence set" | ||
}] | ||
}, "INVALID COMMAND", parsed, data); | ||
return callback(); | ||
} | ||
|
||
if (["Selected"].indexOf(connection.state) < 0) { | ||
connection.send({ | ||
tag: parsed.tag, | ||
command: "BAD", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "Select mailbox first" | ||
}] | ||
}, "COPY FAILED", parsed, data); | ||
return callback(); | ||
} | ||
|
||
var sequence = parsed.attributes[0].value, | ||
range = connection.server.getMessageRange(connection.selectedMailbox, sequence, true), | ||
rangeMessages = range.map(function(x) { return x[1]; }); | ||
|
||
connection.expungeSpecificMessages(connection.selectedMailbox, rangeMessages, false, true); | ||
|
||
connection.send({ | ||
tag: parsed.tag, | ||
command: "OK", | ||
attributes: [{ | ||
type: "TEXT", | ||
value: "UID EXPUNGE completed" | ||
}] | ||
}, "UID EXPUNGE", parsed, data); | ||
callback(); | ||
}); | ||
|
||
server.outputHandlers.push(function(connection, response, description, parsed, data, extra) { | ||
if (description === "APPEND") { | ||
// The final response should be of the form: | ||
// OK [APPENDUID <target-mailbox-uidvalidity> <uid>] APPEND Completed | ||
response.attributes = [ | ||
{ | ||
type: "SECTION", | ||
section: [ | ||
{ | ||
type: "ATOM", | ||
value: "APPENDUID" | ||
}, | ||
extra.mailbox.uidvalidity, | ||
extra.message.uid | ||
] | ||
} | ||
].concat(response.attributes); | ||
return; | ||
} | ||
|
||
if (description === "COPY" || description === "UID COPY" || | ||
description === "MOVE COPYUID" || description === "UID MOVE COPYUID") { | ||
response.attributes = [ | ||
{ | ||
type: "SECTION", | ||
section: [ | ||
{ | ||
type: "ATOM", | ||
value: "COPYUID" | ||
}, | ||
extra.mailbox.uidvalidity, | ||
// The range was interpreted in ascending order so these | ||
// values are already in the right order. | ||
{ | ||
type: "SEQUENCE", | ||
value: extra.sourceUids.join(",") | ||
}, { | ||
type: "SEQUENCE", | ||
value: extra.targetUids.join(",") | ||
} | ||
] | ||
} | ||
].concat(response.attributes); | ||
response.skipResponse = false; | ||
return; | ||
} | ||
}); | ||
}; |
Oops, something went wrong.