-
Notifications
You must be signed in to change notification settings - Fork 16
/
sslUtil.js
118 lines (106 loc) · 3.86 KB
/
sslUtil.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const os = require("os");
const fs = require("fs");
const log = require("@ui5/logger").getLogger("server:sslUtil");
const {promisify} = require("util");
const stat = promisify(fs.stat);
const path = require("path");
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const makeDir = require("make-dir");
const prompt = require("prompt");
const sslUtil = {
/**
* Creates a new SSL certificate or validates an existing one.
*
* @module server/sslUtil
* @param {string} [keyPath=$HOME/.ui5/server/server.key] Path to private key to be used for https.
* Defaults to <code>$HOME/.ui5/server/server.key</code>
* @param {string} [certPath=$HOME/.ui5/server/server.crt] Path to certificate to be used for for https.
* Defaults to <code>$HOME/.ui5/server/server.crt</codee>
* @returns {Promise<object>} Resolves with an sslObject containing <code>cert</code> and <code>key</code>
*/
getSslCertificate: function(
keyPath = path.join(os.homedir(), ".ui5/server/server.key"),
certPath = path.join(os.homedir(), ".ui5/server/server.crt")
) {
// checks the certificates if they are present
return Promise.all([
fileExists(keyPath).then((bExists) => {
if (!bExists) {
log.verbose(`No SSL private key found at ${keyPath}`);
return false;
}
return readFile(keyPath);
}),
fileExists(certPath).then((bExists) => {
if (!bExists) {
log.verbose(`No SSL certificate found at ${certPath}`);
return false;
}
return readFile(certPath);
})
]).then(function([key, cert]) {
if (key && cert) {
return {key, cert};
}
return createAndInstallCertificate(keyPath, certPath);
});
}
};
function createAndInstallCertificate(keyPath, certPath) {
return new Promise(function(resolve, reject) {
prompt.start();
const property = {
name: "yesno",
message: "No SSL certificates found. Do you want to create new SSL certificates and install them locally?",
validator: /y[es]*|n[o]?/,
warning: "Please respond yes or no",
default: "yes"
};
prompt.get(property, function(err, result) {
if (result.yesno !== "" && result.yesno !== "yes") {
reject("Certificate installation aborted! Please install the SSL certificate manually.");
return;
}
resolve();
});
}).then(function() {
// In case certificate is not found, create a self-signed one and put it into the user's trust store
const devCert = require("devcert-sanscache");
// Inform end user about entering his root password (needed for importing
// the created certificate into the system)
/* eslint-disable no-console */
// TODO: Prompt and logging should happen in CLI module rather than server
if (process.platform === "win32") {
console.log("Please press allow in the opened dialog to confirm importing the newly created " +
"SSL certificate into the operating system and browsers.");
} else {
console.log("Please enter your root password to allow importing the newly created " +
"SSL certificate into the operating system and browsers.");
}
return devCert("ui5-tooling").then(({key, cert}) => {
return Promise.all([
// Write certificates to the ui5 certificate folder
// such that they are used by default upon next startup
makeDir(path.dirname(keyPath)).then(() => writeFile(keyPath, key)),
makeDir(path.dirname(certPath)).then(() => writeFile(certPath, cert))
]).then(function() {
return {key, cert};
}).catch((err) => {
console.log("Could not create certificate");
console.error(err);
});
});
/* eslint-enable no-console */
});
}
function fileExists(filePath) {
return stat(filePath).then(() => true, (err) => {
if (err.code === "ENOENT") { // "File or directory does not exist"
return false;
} else {
throw err;
}
});
}
module.exports = sslUtil;