-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.js
115 lines (103 loc) · 3.35 KB
/
app.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
const https = require('https');
const http = require('http');
const fs = require('fs');
const spawn = require('child_process').spawn;
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const INJECTED_HTML = `
<style>
/* hide Upgrade to Business on sidebar */
div.sidebar > button {display: none !important;}
/* hide Authentication logs */
[aria-label="Authentication logs"] {display: none !important;}
/* hide everything having the BE Feature banner */
.be-indicator-container, .limited-be {display: none !important;}
/* FIXME: hot fix to show OAuth save button #10 */
.oauth-save-settings-button {display: inline-block !important;}
/* this should not be hidden, but let's make it more subtle */
.be-indicator {
filter: saturate(0) !important;
opacity: 0.2 !important;
pointer-events: none !important;
}
</style>
<script>
// Block tracking script matomo.cloud
// https://github.com/ngxson/portainer-ce-without-annoying/issues/5
(function () {
var headNode = document.getElementsByTagName('script')[0].parentNode;
// save the original function
headNode.originalInsertBefore = headNode.insertBefore;
// intercept the function call
headNode.insertBefore = function(newNode, referenceNode) {
if (newNode && newNode.src && newNode.src.indexOf('matomo') !== -1) {
console.log('Blocked insertion of matomo script node');
} else {
headNode.originalInsertBefore(newNode, referenceNode);
}
}
})();
</script>
`;
const TARGET_URL = 'http://localhost:19000';
const SSL_CERT_PATH = '/data/certs/cert.pem';
const SSL_KEY_PATH = '/data/certs/key.pem';
const FORWARDED_ARGS = process.argv.slice(2);
// proxy logic
const app = express();
app.get('/', async (req, res) => {
try {
const response = await fetch(TARGET_URL);
const body = await response.text();
const newBody = body.replace('<head>', `<head>${INJECTED_HTML}`);
res.send(newBody);
} catch (e) {
console.error(e);
res.status(500).json(e);
}
});
app.get('/api/motd', (req, res) => {
// hide the "Latest News From Portainer"
// https://github.com/portainer/portainer/blob/master/app/portainer/views/home/home.html
res.json({});
});
app.use(createProxyMiddleware({
target: TARGET_URL,
ws: true,
}));
// http + https server
async function waitUntilCertAvailable() {
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
while (!fs.existsSync(SSL_CERT_PATH)) {
await sleep(1000);
}
};
async function runServer() {
http.createServer(app).listen(9000);
await waitUntilCertAvailable();
https.createServer({
key: fs.readFileSync(SSL_KEY_PATH),
cert: fs.readFileSync(SSL_CERT_PATH),
}, app).listen(9443);
}
// child process for portainer
function runPortainer() {
const fwdArgs = FORWARDED_ARGS.join(' ');
console.log(`Launching portainer with args ${fwdArgs}`)
const child = spawn('/bin/sh', [
'-c',
`/portainer --bind=":19000" --bind-https=":19443" ${fwdArgs}`
]);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
child.on('exit', function (code) {
console.log(`portainer exited with status code ${code}`);
process.exit(code);
});
process.on('SIGTERM', function () {
child.kill('SIGTERM');
});
}
// run it
runPortainer();
runServer();