generate manifest.json from domain and add pwalogo

Signed-off-by: si458 <simonsmith5521@gmail.com>

si458 committed Sep 24, 2024 at 19:09 UTC 0bee2be3cfc15b9c54a8d43e8d19a41dce28dd86
4 files changed +64 -24
meshcentral-config-schema.json
+5
@@ -1112,6 +1112,11 @@
1112 "default": null,
1113 "description": "Web site .png logo file placed in meshcentral-data that used on the login page when sitestyle is 2."
1114 },
1115 + "pwaLogo": {
1116 + "type": "string",
1117 + "default": null,
1118 + "description": "Web site .png logo file that is 512x512 in size placed in meshcentral-data that is used for PWA installs on iOS and Android."
1119 + },
1120 "rootRedirect": {
1121 "type": "string",
1122 "default": null,
public/manifest.json deleted
-23
@@ -1,23 +0,0 @@
1 -{
2 - "name": "MeshCentral",
3 - "short_name": "MeshCentral",
4 - "description": "Open source web based, remote computer management.",
5 - "scope": ".",
6 - "start_url": "/",
7 - "display": "fullscreen",
8 - "orientation": "portrait",
9 - "theme_color": "#ffffff",
10 - "background_color": "#ffffff",
11 - "icons": [
12 - {
13 - "src": "android-chrome-192x192.png",
14 - "sizes": "192x192",
15 - "type": "image/png"
16 - },
17 - {
18 - "src": "android-chrome-512x512.png",
19 - "sizes": "512x512",
20 - "type": "image/png"
21 - }
22 - ]
23 -}
\ No newline at end of file
sample-config-advanced.json
+1
@@ -189,6 +189,7 @@
189 "title2": "Servername",
190 "_titlePicture": "title-sample.png",
191 "_loginPicture": "title-sample.png",
192 + "_pwaLogo": "title-sample.png",
193 "_rootRedirect": "https://www.youtube.com/watch?v=Gs069dndIYk",
194 "_mobileSite": false,
195 "_maxDeviceView": 1000,
webserver.js
+58 -1
@@ -3724,6 +3724,31 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3724 res.send(Buffer.from(getRootCertBase64(), 'base64'));
3725 }
3726
3727 + // Return a customised mainifest.json for PWA
3728 + function handleManifestRequest(req, res){
3729 + const domain = getDomain(req);
3730 + if (domain == null) { parent.debug('web', 'handleManifestRequest: no domain'); res.sendStatus(404); return; }
3731 + if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false)) { parent.debug('web', 'handleManifestRequest: invalid ip'); return; } // Check server-wide IP filter only.
3732 + parent.debug('web', 'handleManifestRequest()');
3733 + var manifest = {
3734 + "name": (domain.title != null) ? domain.title : 'MeshCentral',
3735 + "short_name": (domain.title != null) ? domain.title : 'MeshCentral',
3736 + "description": "Open source web based, remote computer management.",
3737 + "scope": ".",
3738 + "start_url": "/",
3739 + "display": "fullscreen",
3740 + "orientation": "portrait",
3741 + "theme_color": "#ffffff",
3742 + "background_color": "#ffffff",
3743 + "icons": [{
3744 + "src": "pwalogo.png",
3745 + "sizes": "512x512",
3746 + "type": "image/png"
3747 + }]
3748 + };
3749 + res.json(manifest);
3750 + }
3751 +
3752 // Handle user public file downloads
3753 function handleDownloadUserFiles(req, res) {
3754 const domain = checkUserIpAddress(req, res);
@@ -3846,6 +3871,36 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3871 }
3872 }
3873
3874 + // Handle PWA logo request
3875 + function handlePWALogoRequest(req, res) {
3876 + const domain = checkUserIpAddress(req, res);
3877 + if (domain == null) { return; }
3878 +
3879 + //res.set({ 'Cache-Control': 'max-age=86400' }); // 1 day
3880 + if (domain.pwalogo) {
3881 + if ((parent.configurationFiles != null) && (parent.configurationFiles[domain.pwalogo] != null)) {
3882 + // Use the logo in the database
3883 + res.set({ 'Content-Type': domain.pwalogo.toLowerCase().endsWith('.png') ? 'image/png' : 'image/jpeg' });
3884 + res.send(parent.configurationFiles[domain.pwalogo]);
3885 + return;
3886 + } else {
3887 + // Use the logo on file
3888 + try { res.sendFile(obj.common.joinPath(obj.parent.datapath, domain.pwalogo)); return; } catch (ex) { }
3889 + }
3890 + }
3891 +
3892 + if ((domain.webpublicpath != null) && (obj.fs.existsSync(obj.path.join(domain.webpublicpath, 'android-chrome-512x512.png')))) {
3893 + // Use the domain logo picture
3894 + try { res.sendFile(obj.path.join(domain.webpublicpath, 'android-chrome-512x512.png')); } catch (ex) { res.sendStatus(404); }
3895 + } else if (parent.webPublicOverridePath && obj.fs.existsSync(obj.path.join(obj.parent.webPublicOverridePath, 'android-chrome-512x512.png'))) {
3896 + // Use the override logo picture
3897 + try { res.sendFile(obj.path.join(obj.parent.webPublicOverridePath, 'android-chrome-512x512.png')); } catch (ex) { res.sendStatus(404); }
3898 + } else {
3899 + // Use the default logo picture
3900 + try { res.sendFile(obj.path.join(obj.parent.webPublicPath, 'android-chrome-512x512.png')); } catch (ex) { res.sendStatus(404); }
3901 + }
3902 + }
3903 +
3904 // Handle translation request
3905 function handleTranslationsRequest(req, res) {
3906 const domain = checkUserIpAddress(req, res);
@@ -6222,7 +6277,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6277 }
6278
6279 // Setup middleware
6225 - obj.app.engine('handlebars', obj.exphbs({ defaultLayout: false }));
6280 + obj.app.engine('handlebars', obj.exphbs.engine({ defaultLayout: false }));
6281 obj.app.set('view engine', 'handlebars');
6282 if (obj.args.trustedproxy) {
6283 // Reverse proxy should add the "X-Forwarded-*" headers
@@ -6542,6 +6597,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6597 obj.app.post(url + 'tokenlogin', obj.bodyParser.urlencoded({ extended: false }), handleLoginRequest);
6598 obj.app.get(url + 'logout', handleLogoutRequest);
6599 obj.app.get(url + 'MeshServerRootCert.cer', handleRootCertRequest);
6600 + obj.app.get(url + 'manifest.json', handleManifestRequest);
6601 obj.app.post(url + 'changepassword', obj.bodyParser.urlencoded({ extended: false }), handlePasswordChangeRequest);
6602 obj.app.post(url + 'deleteaccount', obj.bodyParser.urlencoded({ extended: false }), handleDeleteAccountRequest);
6603 obj.app.post(url + 'createaccount', obj.bodyParser.urlencoded({ extended: false }), handleCreateAccountRequest);
@@ -6603,6 +6659,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6659 obj.app.get(url + 'agentdownload.ashx', handleAgentDownloadFile);
6660 obj.app.get(url + 'logo.png', handleLogoRequest);
6661 obj.app.get(url + 'loginlogo.png', handleLoginLogoRequest);
6662 + obj.app.get(url + 'pwalogo.png', handlePWALogoRequest);
6663 obj.app.post(url + 'translations', obj.bodyParser.urlencoded({ extended: false }), handleTranslationsRequest);
6664 obj.app.get(url + 'welcome.jpg', handleWelcomeImageRequest);
6665 obj.app.get(url + 'welcome.png', handleWelcomeImageRequest);