diff --git a/config/api.toml b/config/api.toml new file mode 100644 index 00000000..8342b49b --- /dev/null +++ b/config/api.toml @@ -0,0 +1,41 @@ +enabled=true +port=8080 +# by default bind to localhost only +host="127.0.0.1" + +# Use `true` (HTTPS) for port 443 and `false` (HTTP) for 80 +secure=false + +# If set requires all API calls to have accessToken query argument with that value +# http://localhost:8080/users?accessToken=somesecretvalue +#accessToken="somesecretvalue" + +[tls] +# If certificate path is not defined, use global or built-in self-signed certs +#key="/path/to/server/key.pem" +#cert="/path/to/server/cert.pem" + +[mobileconfig] +# plist configuration for OSX/iOS profile files that are generated with Application Specific Passwords +# Use {email} in the description strings to replace it with account email address + +# A reverse-DNS style identifier (com.example.myprofile, for example) that identifies the profile. +# This string is used to determine whether a new profile should replace an existing one or should be added. Username is prepended to this value. +identifier="com.email.wildduck" + +# A human-readable name for the profile. This value is displayed on the Detail screen. It does not have to be unique. +displayName="Wild Duck Mail" + +# A human-readable string containing the name of the organization that provided the profile. +organization="Wild Duck Mail Services" + +# A description of the profile, shown on the Detail screen for the profile. This should be descriptive enough to help the user decide whether to install the profile. +displayDescription="Install this profile to setup {email}" + +# A user-visible description of the email account, shown in the Mail and Settings applications. +accountDescription="Wild Duck ({email})" + +[mobileconfig.tls] +# If certificate path is not defined, use global or built-in self-signed certs +#key="/path/to/server/key.pem" +#cert="/path/to/server/cert.pem" diff --git a/config/dbs.toml b/config/dbs.toml new file mode 100644 index 00000000..a1cbd7b9 --- /dev/null +++ b/config/dbs.toml @@ -0,0 +1,27 @@ +# mongodb connection string for the main database +mongo="mongodb://127.0.0.1:27017/wildduck" + +# redis connection string +redis="redis://127.0.0.1:6379/3" + +# Wild Duck allows using different kind of data in different databases +# If you do not provide a database config value, then main database connection +# is used for everything +# You can either use a database name (uses shared connection) or a configutaion +# url (creates a separate connection) for each databases + +# Optional database name or connection url for GridFS if you do not want to +# use the main db for storing attachments. Useful if you want +# to use a different mount folder or storage engine +#gridfs="wildduck" + +# Optional database name or connection url for users collection if you do not want to +# use the main db for storing user/address data. Useful if you want +# to use a different mount folder or storage engine +#users="wildduck" + +# Optional database name or connection url for ZoneMTA queue database. This is +# used to push outbound emails to the sending queue +#sender="zone-mta" + +#queued="mail" diff --git a/config/default.toml b/config/default.toml index f57c843d..1296efbd 100644 --- a/config/default.toml +++ b/config/default.toml @@ -26,31 +26,7 @@ maxForwards=2000 #emailDomain="mydomain.info" [dbs] - # mongodb connection string for the main database - mongo="mongodb://127.0.0.1:27017/wildduck" - - # redis connection string - redis="redis://127.0.0.1:6379/3" - - # Wild Duck allows using different kind of data in different databases - # If you do not provide a database config value, then main database connection - # is used for everything - # You can either use a database name (uses shared connection) or a configutaion - # url (creates a separate connection) for each databases - - # Optional database name or connection url for GridFS if you do not want to - # use the main db for storing attachments. Useful if you want - # to use a different mount folder or storage engine - #gridfs="wildduck" - - # Optional database name or connection url for users collection if you do not want to - # use the main db for storing user/address data. Useful if you want - # to use a different mount folder or storage engine - #users="wildduck" - - # Optional database name or connection url for ZoneMTA queue database. This is - # used to push outbound emails to the sending queue - #sender="zone-mta" +# @include "dbs.toml" [totp] # If enabled then encrypt TOTP seed tokens with the secret password. By default TOTP seeds @@ -75,143 +51,22 @@ maxForwards=2000 authlogExpireDays=30 [imap] - # If enabled then Wild Duck exposes an IMAP interface for listing and fetching emails - enabled=true - port=9993 - # by default bind to localhost only - host="127.0.0.1" - - # Use `true` for port 993 and `false` for 143. If connection is not secured - # on connection then Wild Duck enables STARTTLS extension - secure=true - - # Max size for messages uploaded via APPEND - maxMB=25 - - # delete messages from \Trash and \Junk after retention days - retention=30 - - # if `true` then do not autodelete expired messages - disableRetention=false - - [imap.setup] - # Public configuration for IMAP - hostname="localtest.me" - secure=true - # port defaults to imap.port - #port=9993 +# @include "imap.toml" [tls] - # Default TLS keys (can be overriden by individual services) - #key="/path/to/server/key.pem" - #ca=["/path/to/server/ca1.pem", "/path/to/server/ca2.pem"] - #cert="/path/to/server/cert.pem" - -[imap.tls] - # If certificate path is not defined, use global or built-in self-signed certs - #key="/path/to/server/key.pem" - #cert="/path/to/server/cert.pem" +# @include "tls.toml" [lmtp] - # If enabled then Wild Duck exposes a LMTP interface for pushing messages to mail store - enabled=true - port=2424 - # by default bind to localhost only - host='127.0.0.1' - - # Max accepted size for messages pushed via LMTP - maxMB=25 - - [lmtp.tls] - # If certificate path is not defined, use global or built-in self-signed certs for STARTTLS - #key="/path/to/server/key.pem" - #cert="/path/to/server/cert.pem" +# @include "lmtp.toml" [pop3] - # If enabled then Wild Duck exposes a limited POP3 interface for listing and fetching emails - enabled=true - port=9995 - # by default bind to localhost only - host="127.0.0.1" - - # Use `true` for port 995 and `false` for 110. Try to always use `true` as the included - # POP3 server is limited and does not support the STLS command - secure=true - - # How many latest messages to list for LIST and UIDL - # POP3 server never lists all messages but only a limited length list - maxMessages=250 - - [pop3.tls] - # If certificate path is not defined, use global or built-in self-signed certs - #key="/path/to/server/key.pem" - #cert="/path/to/server/cert.pem" - - [pop3.setup] - # Public configuration for POP3 - hostname="localtest.me" - secure=true - # port defaults to pop3.port - #port=9995 +# @include "pop3.toml" [api] - enabled=true - port=8080 - # by default bind to localhost only - host="127.0.0.1" - - # Use `true` (HTTPS) for port 443 and `false` (HTTP) for 80 - secure=false - - # If set requires all API calls to have accessToken query argument with that value - # http://localhost:8080/users?accessToken=somesecretvalue - #accessToken="somesecretvalue" - - [api.tls] - # If certificate path is not defined, use global or built-in self-signed certs - #key="/path/to/server/key.pem" - #cert="/path/to/server/cert.pem" - - [api.mobileconfig] - # plist configuration for OSX/iOS profile files that are generated with Application Specific Passwords - # Use {email} in the description strings to replace it with account email address - - # A reverse-DNS style identifier (com.example.myprofile, for example) that identifies the profile. - # This string is used to determine whether a new profile should replace an existing one or should be added. Username is prepended to this value. - identifier="com.email.wildduck" - - # A human-readable name for the profile. This value is displayed on the Detail screen. It does not have to be unique. - displayName="Wild Duck Mail" - - # A human-readable string containing the name of the organization that provided the profile. - organization="Wild Duck Mail Services" - - # A description of the profile, shown on the Detail screen for the profile. This should be descriptive enough to help the user decide whether to install the profile. - displayDescription="Install this profile to setup {email}" - - # A user-visible description of the email account, shown in the Mail and Settings applications. - accountDescription="Wild Duck ({email})" - - [api.mobileconfig.tls] - # If certificate path is not defined, use global or built-in self-signed certs - #key="/path/to/server/key.pem" - #cert="/path/to/server/cert.pem" +# @include "api.toml" [sender] - # Push messages to ZoneMTA queue for delivery - # if `false` then no messages are sent - enabled=true - - # which ZoneMTA queue to use by default - zone="default" - - # Collection name for GridFS storage - gfs="mail" - - # Collection name for the queue - # see [dbs].sender option for choosing correct database to use for ZoneMTA queues - # by default the main wildduck database is used - collection="zone-queue" +# @include "sender.toml" [smtp.setup] # Public configuration for SMTP MDA diff --git a/config/imap.toml b/config/imap.toml new file mode 100644 index 00000000..dff581ed --- /dev/null +++ b/config/imap.toml @@ -0,0 +1,30 @@ +# If enabled then Wild Duck exposes an IMAP interface for listing and fetching emails +enabled=true +port=9993 +# by default bind to localhost only +host="127.0.0.1" + +# Use `true` for port 993 and `false` for 143. If connection is not secured +# on connection then Wild Duck enables STARTTLS extension +secure=true + +# Max size for messages uploaded via APPEND +maxMB=25 + +# delete messages from \Trash and \Junk after retention days +retention=30 + +# if `true` then do not autodelete expired messages +disableRetention=false + +[setup] +# Public configuration for IMAP +hostname="localhost" +secure=true +# port defaults to imap.port +#port=9993 + +[tls] +# If certificate path is not defined, use global or built-in self-signed certs +#key="/path/to/server/key.pem" +#cert="/path/to/server/cert.pem" diff --git a/config/lmtp.toml b/config/lmtp.toml new file mode 100644 index 00000000..564fcb41 --- /dev/null +++ b/config/lmtp.toml @@ -0,0 +1,13 @@ +# If enabled then Wild Duck exposes a LMTP interface for pushing messages to mail store +enabled=true +port=2424 +# by default bind to localhost only +host="127.0.0.1" + +# Max accepted size for messages pushed via LMTP +maxMB=25 + +[tls] +# If certificate path is not defined, use global or built-in self-signed certs for STARTTLS +#key="/path/to/server/key.pem" +#cert="/path/to/server/cert.pem" diff --git a/config/pop3.toml b/config/pop3.toml new file mode 100644 index 00000000..2a658ed3 --- /dev/null +++ b/config/pop3.toml @@ -0,0 +1,25 @@ +# If enabled then Wild Duck exposes a limited POP3 interface for listing and fetching emails +enabled=true +port=9995 +# by default bind to localhost only +host="127.0.0.1" + +# Use `true` for port 995 and `false` for 110. Try to always use `true` as the included +# POP3 server is limited and does not support the STLS command +secure=true + +# How many latest messages to list for LIST and UIDL +# POP3 server never lists all messages but only a limited length list +maxMessages=250 + +[tls] +# If certificate path is not defined, use global or built-in self-signed certs +#key="/path/to/server/key.pem" +#cert="/path/to/server/cert.pem" + +[setup] +# Public configuration for POP3 +hostname="localhost" +secure=true +# port defaults to pop3.port +#port=9995 diff --git a/config/sender.toml b/config/sender.toml new file mode 100644 index 00000000..fe8c35b4 --- /dev/null +++ b/config/sender.toml @@ -0,0 +1,14 @@ +# Push messages to ZoneMTA queue for delivery +# if `false` then no messages are sent +enabled=true + +# which ZoneMTA queue to use by default +zone="default" + +# Collection name for GridFS storage +gfs="mail" + +# Collection name for the queue +# see [dbs].sender option for choosing correct database to use for ZoneMTA queues +# by default the main wildduck database is used +collection="zone-queue" diff --git a/config/tls.toml b/config/tls.toml new file mode 100644 index 00000000..da7906b0 --- /dev/null +++ b/config/tls.toml @@ -0,0 +1,4 @@ +# Default TLS keys (can be overriden by individual services) +#key="/path/to/server/key.pem" +#ca=["/path/to/server/ca1.pem", "/path/to/server/ca2.pem"] +#cert="/path/to/server/cert.pem" diff --git a/lib/api/messages.js b/lib/api/messages.js index a11cc2bc..bad2b891 100644 --- a/lib/api/messages.js +++ b/lib/api/messages.js @@ -52,7 +52,8 @@ module.exports = (db, server, messageHandler) => { }, { fields: { path: true, - specialUse: true + specialUse: true, + uidNext: true } }, (err, mailboxData) => { if (err) { diff --git a/lib/handlers/on-store.js b/lib/handlers/on-store.js index 9c8b33a2..6297376a 100644 --- a/lib/handlers/on-store.js +++ b/lib/handlers/on-store.js @@ -143,6 +143,14 @@ module.exports = server => (path, update, session, callback) => { draft: message.flags.includes('\\Draft') } }; + + if (!['\\Junk', '\\Trash'].includes(mailboxData.specialUse) && !message.flags.includes('\\Deleted')) { + flagsupdate.$set.searchable = true; + } else { + flagsupdate.$unset = { + searchable: '' + }; + } } break; @@ -190,6 +198,9 @@ module.exports = server => (path, update, session, callback) => { flagsupdate.$set = { undeleted: false }; + flagsupdate.$unset = { + searchable: '' + }; } if (newFlags.includes('\\Draft')) { flagsupdate.$set = { @@ -244,6 +255,9 @@ module.exports = server => (path, update, session, callback) => { flagsupdate.$set = { undeleted: true }; + if (!['\\Junk', '\\Trash'].includes(mailboxData.specialUse)) { + flagsupdate.$set.searchable = true; + } } if (oldFlags.includes('\\Draft')) { flagsupdate.$set = { diff --git a/lib/message-handler.js b/lib/message-handler.js index 139c5b4d..578f7807 100644 --- a/lib/message-handler.js +++ b/lib/message-handler.js @@ -272,7 +272,7 @@ class MessageHandler { messageData.uid = mailboxData.uidNext; messageData.modseq = mailboxData.modifyIndex + 1; - if (!['\\Junk', '\\Trash'].includes(mailboxData.specialUse)) { + if (!['\\Junk', '\\Trash'].includes(mailboxData.specialUse) && !flags.includes('\\Deleted')) { messageData.searchable = true; } @@ -668,7 +668,7 @@ class MessageHandler { let unseen = message.unseen; - if (['\\Junk', '\\Trash'].includes(target.specialUse)) { + if (['\\Junk', '\\Trash'].includes(target.specialUse) || !message.undeleted) { delete message.searchable; } else { message.searchable = true; diff --git a/package.json b/package.json index d70770fc..f8812c5e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "he": "^1.1.1", "html-to-text": "^3.3.0", "humanname": "^0.2.2", - "humanparser": "^1.4.0", + "humanparser": "^1.5.0", "iconv-lite": "^0.4.18", "joi": "^10.6.0", "js-yaml": "^3.9.1", @@ -39,7 +39,7 @@ "mailsplit": "^4.0.2", "mobileconfig": "^2.0.1", "mongo-cursor-pagination": "^5.0.0", - "mongodb": "^2.2.30", + "mongodb": "^2.2.31", "node-redis-scripty": "0.0.5", "nodemailer": "^4.0.1", "npmlog": "^4.1.2", @@ -47,13 +47,13 @@ "qrcode": "^0.9.0", "redfour": "^1.0.2", "redis": "^2.8.0", - "restify": "^5.0.1", + "restify": "^5.1.0", "seq-index": "^1.1.0", "smtp-server": "^3.0.1", "speakeasy": "^2.0.0", "utf7": "^1.0.2", "uuid": "^3.1.0", - "wild-config": "^1.0.0" + "wild-config": "^1.3.0" }, "repository": { "type": "git", diff --git a/worker.js b/worker.js index e661d57b..af13ed3d 100644 --- a/worker.js +++ b/worker.js @@ -20,7 +20,7 @@ db.connect(err => { // Start IMAP server imap(err => { if (err) { - log.error('App', 'Failed to start IMAP server'); + log.error('App', 'Failed to start IMAP server. %s', err.message); return process.exit(1); } // Start POP3 server