Added example certififcates

This commit is contained in:
Andris Reinman 2017-07-25 15:50:16 +03:00
parent eed456b745
commit c42ab1519f
6 changed files with 292 additions and 50 deletions

119
api.js
View file

@ -7,13 +7,14 @@ const Joi = require('joi');
const crypto = require('crypto');
const tools = require('./lib/tools');
const consts = require('./lib/consts');
const mobileconfig = require('mobileconfig');
const UserHandler = require('./lib/user-handler');
const MailboxHandler = require('./lib/mailbox-handler');
const MessageHandler = require('./lib/message-handler');
const ImapNotifier = require('./lib/imap-notifier');
const db = require('./lib/db');
const MongoPaging = require('mongo-cursor-pagination');
const certs = require('./lib/certs').get('api');
const certs = require('./lib/certs');
const ObjectID = require('mongodb').ObjectID;
const imapTools = require('./imap-core/lib/imap-tools');
const libmime = require('libmime');
@ -23,6 +24,8 @@ const GridFSBucket = require('mongodb').GridFSBucket;
const libbase64 = require('libbase64');
const libqp = require('libqp');
const urllib = require('url');
const apiCerts = certs.get('api');
const mobileconfigCerts = certs.get('api.mobileconfig');
const serverOptions = {
name: 'Wild Duck API',
@ -36,12 +39,12 @@ const serverOptions = {
}
};
if (certs && config.api.secure) {
serverOptions.key = certs.key;
if (certs.ca) {
serverOptions.ca = certs.ca;
if (apiCerts && config.api.secure) {
serverOptions.key = apiCerts.key;
if (apiCerts.ca) {
serverOptions.ca = apiCerts.ca;
}
serverOptions.certificate = certs.cert;
serverOptions.certificate = apiCerts.cert;
}
const server = restify.createServer(serverOptions);
@ -78,6 +81,20 @@ server.get(
})
);
server.use((req, res, next) => {
if (config.api.accessToken && req.query.accessToken !== config.api.accessToken) {
res.status(403);
res.charSet('utf-8');
return res.json({
error: 'Invalid accessToken value'
});
}
if (req.query.accessToken) {
delete req.query.accessToken;
}
next();
});
server.get({ name: 'users', path: '/users' }, (req, res, next) => {
res.charSet('utf-8');
@ -662,6 +679,7 @@ server.put('/users/:user/addresses/:address', (req, res, next) => {
}
if (!addressData || addressData.user.toString() !== user.toString()) {
res.status(404);
res.json({
error: 'Invalid or unknown email address identifier'
});
@ -755,6 +773,7 @@ server.del('/users/:user/addresses/:address', (req, res, next) => {
}
if (!addressData || addressData.user.toString() !== user.toString()) {
res.status(404);
res.json({
error: 'Invalid or unknown email address identifier'
});
@ -1128,6 +1147,7 @@ server.get('/users/:user/addresses/:address', (req, res, next) => {
return next();
}
if (!addressData) {
res.status(404);
res.json({
error: 'Invalid or unknown address'
});
@ -2340,6 +2360,7 @@ server.del('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next)
}
if (!messageData || messageData.user.toString() !== user.toString()) {
res.status(404);
res.json({
error: 'Message was not found'
});
@ -2596,6 +2617,7 @@ server.del('/users/:user/filters/:filter', (req, res, next) => {
}
if (!r.deletedCount) {
res.status(404);
res.json({
error: 'Filter was not found'
});
@ -2953,6 +2975,7 @@ server.put('/users/:user/filters/:filter', (req, res, next) => {
}
if (!r || !r.value || !r.value._id) {
res.status(404);
res.json({
error: 'Filter was not found'
});
@ -3049,6 +3072,7 @@ server.post('/users/:user/asps', (req, res, next) => {
user: Joi.string().hex().lowercase().length(24).required(),
description: Joi.string().trim().max(255).required(),
scopes: Joi.array().items(Joi.string().valid('imap', 'pop3', 'smtp', '*').required()).unique(),
generateMobileconfig: Joi.boolean().truthy(['Y', 'true', 'yes', 1]).default(false),
ip: Joi.string().ip({
version: ['ipv4', 'ipv6'],
cidr: 'forbidden'
@ -3072,20 +3096,89 @@ server.post('/users/:user/asps', (req, res, next) => {
}
let user = new ObjectID(result.value.user);
let generateMobileconfig = result.value.generateMobileconfig;
userHandler.generateASP(user, result.value, (err, result) => {
db.users.collection('users').findOne({
_id: user
}, {
fields: {
username: true,
address: true
}
}, (err, userData) => {
if (err) {
res.json({
error: err.message
error: 'MongoDB Error: ' + err.message
});
return next();
}
res.json({
success: true,
id: result.id,
password: result.password
if (!userData) {
res.json({
error: 'This user does not exist'
});
return next();
}
userHandler.generateASP(user, result.value, (err, result) => {
if (err) {
res.json({
error: err.message
});
return next();
}
if (!generateMobileconfig) {
res.json({
success: true,
id: result.id,
password: result.password
});
return next();
}
let options = {
displayName: config.name,
displayDescription: 'Install this profile to auto configure your email account',
emailAddress: userData.address,
identifier: config.api.mobileconfig.identifier,
imap: {
hostname: config.imap.setup.hostname,
port: config.imap.setup.port || config.imap.port,
secure: config.imap.setup.secure,
username: userData.username,
password: result.password
},
smtp: {
hostname: config.smtp.setup.hostname,
port: config.smtp.setup.port || config.smtp.port,
secure: true, //config.setup.smtp.secure,
username: userData.username,
password: false // use the same password as for IMAP
},
keys: mobileconfigCerts
};
mobileconfig.getSignedEmailConfig(options, (err, data) => {
if (err) {
res.json({
error: err.message
});
return next();
}
//res.set('Content-Description', 'Mail App Configuration Profile');
//res.set('Content-Type', 'application/x-apple-aspen-config');
//res.set('Content-Disposition', util.format('attachment; filename="%s.mobileconfig"', req.user.username));
res.json({
success: true,
id: result.id,
password: result.password,
mobileconfig: data.toString('base64')
});
return next();
});
});
return next();
});
});

19
certs/example.cert Normal file
View file

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIJAKtIcb4EW93NMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV
BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNzA3MjUxMjI4MDNaFw0yNzA3MjMxMjI4
MDNaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMDEaQZGMZ6mZsaELGKroi+q8USSH4UpkpSz6jVxNecC
pTjf+UlAOKLaISj1ZIP0vTMFPrwuhhvmsBTSALfrOVCAOF963BzdHIuR173PS/wb
ehLgftvqGme/8FYW61eSPeYmH9IXyPEfpN0SWU1n2Blh1KDX4UuCpwnkXuKYm6uN
9qfyvV7HVwXSVlvBcruScTytbjuBYld6007Bf0ofxZipYB7hH2yo2Kivih9j3EGx
9whzjub3Yh5rwxQiUBtAekIAFgWL+n69pnH/3VDB7+ha3eXmZF3LXlR6QQHz2Q9c
6ZkDqfpyQ/aPWKD0gNMHzzf91/7Ag6B62LVJIjdpwUcCAwEAAaNQME4wHQYDVR0O
BBYEFN64rpadgDmLHi3wAva7mjUNS49XMB8GA1UdIwQYMBaAFN64rpadgDmLHi3w
Ava7mjUNS49XMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAszJ8h8
uDz9SpNDB2jeOLsuo/uhag2JxaK+WBH/hksHHRWm/b7YgmPO7tuzDB0poJ9Mgfai
gGKkpStccZjyESOKZSfLGe2+fuAuLJ8eKYiQqZNwrD1rykjT9FGQzh4GODHHbnjc
UsyXJRa1P0J+7kybOhULuOmks3HODoSCarD8ns3/D+aemtfrr2dLptuC+uzk54Kb
TYis6JZimhwMQX8Sfms9ehLvh/oGcxAONF2lYLkwqjNQahvNAHQQZx5CnzDlk2Wb
g+/CZisGQimIiwrY+QCL+dJKA4yLO00yrB/1N5zt7+Y068EVUNx8ZrA5kOHZXmuC
0k20kdIqlumBXtk=
-----END CERTIFICATE-----

27
certs/example.key Normal file
View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwMRpBkYxnqZmxoQsYquiL6rxRJIfhSmSlLPqNXE15wKlON/5
SUA4otohKPVkg/S9MwU+vC6GG+awFNIAt+s5UIA4X3rcHN0ci5HXvc9L/Bt6EuB+
2+oaZ7/wVhbrV5I95iYf0hfI8R+k3RJZTWfYGWHUoNfhS4KnCeRe4pibq432p/K9
XsdXBdJWW8Fyu5JxPK1uO4FiV3rTTsF/Sh/FmKlgHuEfbKjYqK+KH2PcQbH3CHOO
5vdiHmvDFCJQG0B6QgAWBYv6fr2mcf/dUMHv6Frd5eZkXcteVHpBAfPZD1zpmQOp
+nJD9o9YoPSA0wfPN/3X/sCDoHrYtUkiN2nBRwIDAQABAoIBAAJHkFJhrB6LKzX3
xCqaiv1zUQ0ViUfi2PfnNMLTBucncdq9U05ZcxIB8FhypnClCUO8MSS6jB1yWey1
GwsRvgjEq2X9pvK0bqz72YhGFkjx7jyg6P8iwpMtguMRvFC5yv+YvdGXNGodjK6M
k//FVZnfPUt1ohVpgx4r1C9rzJN3wgyl0Wfi9tclu5t4+tRGarjImVl0RvyTlNG1
+grKLhBVvfx19S9Dop57X1JfSW1VCq3wzf+ztnZa+nSKUz/nJmMZ/WPAs0xQC6Jg
eHwl+dhw6hOq7K1NXZfodHUD538Oyn//r2HCSth37pavxfqUJQM4uoqMSMY8JNQF
Uv/NtoECgYEA4sq0pLZPRKCEcVhi6vyt0CgqINL5YhMgJgyrfJfI8Fb0BgoMoD66
cChUcXE9Ep3oittu3b3H7/ou0Vb9Qy1ZjXPLFLFmy0U9xDNWX6dM/alsy2aGaRzX
uYEuWjY0HkO9bEd6MLTRI5tKTOIBkdOtgpUu/iSsSijCvbMZa8UcLkECgYEA2Zfr
KuxkrEoHSV0F53R9PUGpPttGyCkUhIguiTcONd8BjOJPKeIEP4CwYm01Ds2VOk2P
cpACzEwPwK4FvT8Hh/la1H1n5JFAerbdZaybmJc0lxhQV6tNMhzxRcYDm21i2zMW
EL5OBAccZbg5Eo5XdiK6cwe4nl/2g/8pwqBQHYcCgYAybTf1V8QQUlCgkzKLZVuQ
aR3U5pQkxnPjgfWvYmB/cBYaManVB52UyqLcBn254fqOxXPFQilupoY6bckqYq8C
0LhbBYcBs4ekVHXkFuL7k+xo3YcNYChnSt3vmRXFlPJNXSdCJTJLZIAE0EvhDNwL
qPgl8imM47tJSsVgPRejAQKBgCXptX0OIWBvqaNbxPqWLngs56tfE48usTeCbvFT
mXNDfwaoK/j1O55A8vrDYnpI0daNyw/ADezA2AHPkIpv4AUOKohZrW+C64Q2No9P
qvDEb9Jf1yffXhz8NAHfRaOgRJhC53ZVYkyLXKRQnAkiqhSYano+fymBOPe4zvLt
cegjAoGBANBY+cOuX4k8msGkyRpDQR2e2yjUZ6MvDRmlEi7xzokAoM4OvYhmX2CP
wkagMotxYHn0kpe/xRqGb/rkpsjDWPhVyBHOF3/ZAFAeyt4Y2OuvWQ2K0YyBWiED
/wRp7I3V3oHB/i/gnokEo7u4ty/yPB8qsTwe4zcYoDn78C1q/IGl
-----END RSA PRIVATE KEY-----

View file

@ -6,6 +6,8 @@
# process title and syslog ident
ident="wildduck"
name="Wild Duck Mail"
# how many processes to start
processes=1
@ -77,6 +79,13 @@ maxForwards=2000
# 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
[tls]
# Default TLS keys (can be overriden by individual services)
#key="/path/to/server/key.pem"
@ -123,6 +132,13 @@ maxForwards=2000
#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
[api]
enabled=true
port=8080
@ -130,13 +146,25 @@ maxForwards=2000
host="127.0.0.1"
# Use `true` (HTTPS) for port 443 and `false` (HTTP) for 80
secure=true
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]
identifier="com.email.wildduck"
[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"
[sender]
# Push messages to ZoneMTA queue for delivery
# if `false` then no messages are sent
@ -152,3 +180,9 @@ maxForwards=2000
# see [dbs].sender option for choosing correct database to use for ZoneMTA queues
# by default the main wildduck database is used
collection="zone-queue"
[smtp.setup]
# Public configuration for SMTP MDA
hostname="localtest.me"
secure=false
port=2587

View file

@ -2,89 +2,111 @@
Wild Duck Mail Server is a scalable IMAP / POP3 server that natively exposes internal data through an HTTP API.
This API is not meant to be used by end users but your application.
- [API Usage Info](#api-usage-info)
* [Responses](#responses)
* [Paging](#paging)
- [Users](#users)
* [Search and list users](#search-and-list-users)
+ [GET /users](#get--users)
+ [GET /users](#get-users)
* [Get one user](#get-one-user)
+ [GET /users/{user}](#get--users--user-)
+ [GET /users/{user}](#get-users-user-)
* [Add a new user](#add-a-new-user)
+ [POST /users](#post--users)
+ [POST /users](#post-users)
* [Update user details](#update-user-details)
+ [PUT /users/{user}](#put--users--user-)
- [Authentication](#authentication)
* [Authenticate an user](#authenticate-an-user)
+ [POST /authenticate](#post--authenticate)
+ [POST /authenticate](#post-authenticate)
* [List the authentication log](#list-the-authentication-log)
+ [GET /users/{user}/authlog](#get--users--user--authlog)
+ [GET /users/{user}/authlog](#get-users-user-authlog)
- [2FA](#2fa)
* [Setup 2FA](#setup-2fa)
+ [POST /users/{user}/2fa](#post--users--user--2fa)
+ [POST /users/{user}/2fa](#post-users-user-2fa)
* [Verify 2FA](#verify-2fa)
+ [PUT /users/{user}/2fa](#put--users--user--2fa)
+ [PUT /users/{user}/2fa](#put-users-user-2fa)
* [Disable 2FA](#disable-2fa)
+ [DELETE /users/{user}/2fa](#delete--users--user--2fa)
+ [DELETE /users/{user}/2fa](#delete-users-user-2fa)
* [Check 2FA](#check-2fa)
+ [GET /users/{user}/2fa](#get--users--user--2fa)
+ [GET /users/{user}/2fa](#get-users-user-2fa)
- [Application Specific Passwords](#application-specific-passwords)
* [List existing passwords](#list-existing-passwords)
+ [GET /user/{user}/asps](#get--user--user--asps)
+ [GET /user/{user}/asps](#get-user-user-asps)
* [Add a new Application Specific Password](#add-a-new-application-specific-password)
+ [POST /users/{user}/asps](#post--users--user--asps)
+ [POST /users/{user}/asps](#post-users-user-asps)
* [Delete an Application Specific Password](#delete-an-application-specific-password)
+ [DELETE /users/{user}/asps/{asp}](#delete--users--user--asps--asp-)
+ [DELETE /users/{user}/asps/{asp}](#delete-users-user-asps-asp-)
- [Addresses](#addresses)
* [Search and list addresses](#search-and-list-addresses)
+ [GET /addresses](#get--addresses)
+ [GET /addresses](#get-addresses)
* [List user addresses](#list-user-addresses)
+ [GET /users/{user}/addresses](#get--users--user--addresses)
+ [GET /users/{user}/addresses](#get-users-user-addresses)
* [Get one address](#get-one-address)
+ [GET /users/{user}/addresses/{address}](#get--users--user--addresses--address-)
+ [GET /users/{user}/addresses/{address}](#get-users-user-addresses-address-)
* [Add a new address](#add-a-new-address)
+ [POST /users/{user}/addresses](#post--users--user--addresses)
+ [POST /users/{user}/addresses](#post-users-user-addresses)
* [Update address details](#update-address-details)
+ [PUT /users/{user}/addresses/{address}](#put--users--user--addresses--address-)
+ [PUT /users/{user}/addresses/{address}](#put-users-user-addresses-address-)
* [Delete an alias address](#delete-an-alias-address)
+ [DELETE /users/{user}/addresses/{address}](#delete--users--user--addresses--address-)
+ [DELETE /users/{user}/addresses/{address}](#delete-users-user-addresses-address-)
- [Mailboxes](#mailboxes)
* [List existing mailboxes](#list-existing-mailboxes)
+ [GET /user/{user}/mailboxes](#get--user--user--mailboxes)
+ [GET /user/{user}/mailboxes](#get-user-user-mailboxes)
* [Get one mailbox](#get-one-mailbox)
+ [GET /users/{user}/mailboxes/{mailbox}](#get--users--user--mailboxes--mailbox-)
+ [GET /users/{user}/mailboxes/{mailbox}](#get-users-user-mailboxes-mailbox-)
* [Add a new mailbox](#add-a-new-mailbox)
+ [POST /users/{user}/mailboxes](#post--users--user--mailboxes)
+ [POST /users/{user}/mailboxes](#post-users-user-mailboxes)
* [Update mailbox details](#update-mailbox-details)
+ [PUT /users/{user}/mailboxes/{mailbox}](#put--users--user--mailboxes--mailbox-)
+ [PUT /users/{user}/mailboxes/{mailbox}](#put-users-user-mailboxes-mailbox-)
* [Delete a mailbox](#delete-a-mailbox)
+ [DELETE /users/{user}/mailboxes/{mailbox}](#delete--users--user--mailboxes--mailbox-)
+ [DELETE /users/{user}/mailboxes/{mailbox}](#delete-users-user-mailboxes-mailbox-)
- [Messages](#messages)
* [List existing messages](#list-existing-messages)
+ [GET /user/{user}/mailboxes/{mailbox}/messages](#get--user--user--mailboxes--mailbox--messages)
+ [GET /user/{user}/mailboxes/{mailbox}/messages](#get-user-user-mailboxes-mailbox-messages)
* [Search for messages](#search-for-messages)
+ [GET /user/{user}/search](#get--user--user--search)
+ [GET /user/{user}/search](#get-user-user-search)
* [Get message details](#get-message-details)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}](#get--users--user--mailboxes--mailbox--messages--message-)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}](#get-users-user-mailboxes-mailbox-messages-message-)
* [Update message details](#update-message-details)
+ [PUT /users/{user}/mailboxes/{mailbox}/messages/{message}](#put--users--user--mailboxes--mailbox--messages--message-)
+ [PUT /users/{user}/mailboxes/{mailbox}/messages/{message}](#put-users-user-mailboxes-mailbox-messages-message-)
* [Delete a message](#delete-a-message)
+ [DELETE /users/{user}/mailboxes/{mailbox}/messages/{message}](#delete--users--user--mailboxes--mailbox--messages--message-)
+ [DELETE /users/{user}/mailboxes/{mailbox}/messages/{message}](#delete-users-user-mailboxes-mailbox-messages-message-)
* [Get message source](#get-message-source)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/message.eml](#get--users--user--mailboxes--mailbox--messages--message--messageeml)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/message.eml](#get-users-user-mailboxes-mailbox-messages-message-messageeml)
* [Get message attachment](#get-message-attachment)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/attachments/{attachment}](#get--users--user--mailboxes--mailbox--messages--message--attachments--attachment-)
+ [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/attachments/{attachment}](#get-users-user-mailboxes-mailbox-messages-message-attachments-attachment-)
- [Filters](#filters)
* [Create new filter](#create-new-filter)
+ [POST /users/{user}/filters](#post-users-user-filters)
* [List existing filters](#list-existing-filters)
+ [GET /user/{user}/filters](#get-user-user-filters)
* [Get filter details](#get-filter-details)
+ [GET /users/{user}/filters/{filter}](#get-users-user-filters-filter-)
* [Update filter details](#update-filter-details)
+ [PUT /users/{user}/filters/{filter}](#put-users-user-filters-filter-)
* [Delete a filter](#delete-a-filter)
+ [DELETE /users/{user}/filters/{filter}](#delete-users-user-filters-filter-)
- [Quota](#quota)
* [Recalculate user quota](#recalculate-user-quota)
+ [POST /users/{user}/quota/reset](#post--users--user--quota-reset)
+ [POST /users/{user}/quota/reset](#post-users-user-quota-reset)
- [Updates](#updates)
* [Stream update events](#stream-update-events)
+ [GET /users/{user}/updates](#get--users--user--updates)
+ [GET /users/{user}/updates](#get-users-user-updates)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## API Usage Info
### Authentication
This API should be used by your application and not by the end users directly, so normally it should probably be hidden behind a firewall.
To add another layer of protection the API can be set to require an access token. The token value can be set in configuration file "api.accessToken". If the value is set, then all requests against the API must include a query argument *accessToken* with the same value as in the configuration file.
```
curl "http://localhost:8080/users?query=testuser01&accessToken=secrettoken"
```
### Responses
All successful responses look like the following:
@ -581,6 +603,7 @@ Creates a new Application Specific Password for an existing user, returns the ID
- **user** (required) is the ID of the user
- **description** (required) is the name or description for the new Application Specific Password
- **scopes** is an array of scopes this password is valid for. Valid scopes are "imap", "pop3", "smtp" or "*" for all ASP supported scopes
- **generateMobileconfig** is a boolean. If true, then the result includes a base64 formatted profile file to autoconfigure OSX and iOS mail clients
- **ip** is the IP address the request was made from
**Example**
@ -603,7 +626,29 @@ Response for a successful operation:
}
```
Resulting password should be shown to the client. This password is shown only once so if the user forgets it then the APS should be deleted and replaced with a new one.
Or with the profile file
```
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/asps" -H 'content-type: application/json' -d '{
"description": "Mac OSX Mail Client",
"scopes": ["imap"],
"generateMobileconfig": true
"ip": "192.168.10.10"
}'
```
and the result:
```json
{
"success": true,
"id": "59773be3a7bc855155286d91",
"password": "slrfwaavyzmatgxf",
"mobileconfig": "MIIO8gYJKoZIhvcNAQcCo..."
}
```
Resulting password should be shown to the client. This password is shown only once so if the user forgets it then the APS should be deleted and replaced with a new one. Mobileconfig file should be sent to the client with Content-Type value of `application/x-apple-aspen-config`.
### Delete an Application Specific Password

View file

@ -6,8 +6,24 @@ const fs = require('fs');
const certs = new Map();
// load certificate files
[false, 'imap', 'lmtp', 'pop3', 'api'].forEach(type => {
let tlsconf = type ? config[type] && config[type].tls : config.tls;
[false, 'imap', 'lmtp', 'pop3', 'api', 'api.mobileconfig'].forEach(type => {
let tlsconf = config.tls;
if (type) {
let path = (type + '.tls').split('.');
tlsconf = config;
for (let i = 0; i < path.length; i++) {
let key = path[i];
if (!tlsconf[key]) {
tlsconf = false;
break;
}
tlsconf = tlsconf[key];
}
if (!tlsconf || !tlsconf.key) {
tlsconf = config.tls;
}
}
if (!tlsconf) {
return;
@ -41,4 +57,12 @@ const certs = new Map();
});
});
if (!certs.has('default')) {
certs.set('default', {
key: fs.readFileSync(__dirname + '/../certs/example.key', 'ascii'),
cert: fs.readFileSync(__dirname + '/../certs/example.cert', 'ascii'),
ca: false
});
}
module.exports.get = type => (certs.has(type) ? certs.get(type) : certs.get('default')) || false;