create-steedos-app 2.1.55 → 2.1.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/package.json +2 -2
  2. package/templates/default/README.md +80 -1
  3. package/templates/default/_package.json +8 -8
  4. package/templates/default/env +2 -0
  5. package/templates/default/gitignore +4 -1
  6. package/templates/default/jsreport-app/_package.json +3 -2
  7. package/templates/default/node-red-app/LICENSE.txt +706 -0
  8. package/templates/default/node-red-app/README.md +78 -0
  9. package/templates/default/node-red-app/_package.json +26 -0
  10. package/templates/default/node-red-app/index.js +137 -0
  11. package/templates/default/node-red-app/public/css/simplegrid.css +145 -0
  12. package/templates/default/node-red-app/public/css/style.css +482 -0
  13. package/templates/default/node-red-app/public/favicon.ico +0 -0
  14. package/templates/default/node-red-app/public/first-run.html +280 -0
  15. package/templates/default/node-red-app/public/fonts/css.css +224 -0
  16. package/templates/default/node-red-app/public/images/progress-bar.png +0 -0
  17. package/templates/default/node-red-app/public/images/progress-left.png +0 -0
  18. package/templates/default/node-red-app/public/images/progress-middle.png +0 -0
  19. package/templates/default/node-red-app/public/images/progress-o-bar.png +0 -0
  20. package/templates/default/node-red-app/public/images/progress-o-left.png +0 -0
  21. package/templates/default/node-red-app/public/images/progress-o-middle.png +0 -0
  22. package/templates/default/node-red-app/public/images/progress-o-right.png +0 -0
  23. package/templates/default/node-red-app/public/images/progress-right.png +0 -0
  24. package/templates/default/node-red-app/public/images/spin.svg +41 -0
  25. package/templates/default/node-red-app/public/images/title-wave.png +0 -0
  26. package/templates/default/node-red-app/public/index.html +220 -0
  27. package/templates/default/node-red-app/public/scripts/jquery-1.11.2.min.js +4 -0
  28. package/templates/default/node-red-app/public/scripts/zxcvbn.js +28 -0
  29. package/templates/default/node-red-app/public/steedos.png +0 -0
  30. package/templates/default/node-red-app/red.js +294 -0
  31. package/templates/default/node-red-app/routers/health.js +13 -0
  32. package/templates/default/node-red-app/settings.js +121 -0
  33. package/templates/default/steedos-app/_package.json +1 -1
  34. package/templates/default/steedos-config.yml +2 -2
@@ -0,0 +1,294 @@
1
+ // Copied from https://github.com/node-red/node-red/blob/6d294a0c74343601fb194066fa41edf3b092cdae/packages/node_modules/node-red/red.js
2
+ // with major modifications
3
+
4
+ 'use strict';
5
+
6
+ var http = require('http');
7
+ var https = require('https');
8
+ var util = require("util");
9
+ var express = require("express");
10
+ var crypto = require("crypto");
11
+ var bcrypt;
12
+
13
+ try {
14
+ bcrypt = require('bcrypt');
15
+ }
16
+ catch(e) {
17
+ bcrypt = require('bcryptjs');
18
+ }
19
+
20
+ var RED = require("node-red");
21
+
22
+ module.exports = function(settings) {
23
+ var server;
24
+ var app = express();
25
+ require('./routers/health')(app);
26
+
27
+ if (process.env.NODE_RED_ENABLE_SAFE_MODE && !/^false$/i.test(process.env.NODE_RED_ENABLE_SAFE_MODE)) {
28
+ settings.safeMode = true;
29
+ }
30
+
31
+ // Delay logging of (translated) messages until the RED object has been initialized
32
+ var delayedLogItems = [];
33
+
34
+ var startupHttps = settings.https;
35
+ if (typeof startupHttps === "function") {
36
+ // Get the result of the function, because createServer doesn't accept functions as input
37
+ startupHttps = startupHttps();
38
+ }
39
+ var httpsPromise = Promise.resolve(startupHttps);
40
+
41
+ httpsPromise.then(function(startupHttps) {
42
+ if (startupHttps) {
43
+ server = https.createServer(startupHttps,function(req,res) {app(req,res);});
44
+
45
+ if (settings.httpsRefreshInterval) {
46
+ var httpsRefreshInterval = parseFloat(settings.httpsRefreshInterval)||12;
47
+ if (httpsRefreshInterval > 596) {
48
+ // Max value based on (2^31-1)ms - the max that setInterval can accept
49
+ httpsRefreshInterval = 596;
50
+ }
51
+ // Check whether setSecureContext is available (Node.js 11+)
52
+ if (server.setSecureContext) {
53
+ // Check whether `http` is a callable function
54
+ if (typeof settings.https === "function") {
55
+ delayedLogItems.push({type:"info", id:"server.https.refresh-interval", params:{interval:httpsRefreshInterval}});
56
+ setInterval(function () {
57
+ try {
58
+ // Get the result of the function, because createServer doesn't accept functions as input
59
+ Promise.resolve(settings.https()).then(function(refreshedHttps) {
60
+ if (refreshedHttps) {
61
+ // Only update the credentials in the server when key or cert has changed
62
+ if(!server.key || !server.cert || !server.key.equals(refreshedHttps.key) || !server.cert.equals(refreshedHttps.cert)) {
63
+ server.setSecureContext(refreshedHttps);
64
+ RED.log.info(RED.log._("server.https.settings-refreshed"));
65
+ }
66
+ }
67
+ }).catch(function(err) {
68
+ RED.log.error(RED.log._("server.https.refresh-failed",{message:err}));
69
+ });
70
+ } catch(err) {
71
+ RED.log.error(RED.log._("server.https.refresh-failed",{message:err}));
72
+ }
73
+ }, httpsRefreshInterval*60*60*1000);
74
+ } else {
75
+ delayedLogItems.push({type:"warn", id:"server.https.function-required"});
76
+ }
77
+ } else {
78
+ delayedLogItems.push({type:"warn", id:"server.https.nodejs-version"});
79
+ }
80
+ }
81
+ } else {
82
+ server = http.createServer(function(req,res) {app(req,res);});
83
+ }
84
+ server.setMaxListeners(0);
85
+
86
+ function formatRoot(root) {
87
+ if (root[0] != "/") {
88
+ root = "/" + root;
89
+ }
90
+ if (root.slice(-1) != "/") {
91
+ root = root + "/";
92
+ }
93
+ return root;
94
+ }
95
+
96
+ if (settings.httpRoot === false) {
97
+ settings.httpAdminRoot = false;
98
+ settings.httpNodeRoot = false;
99
+ } else {
100
+ settings.httpRoot = settings.httpRoot||"/";
101
+ settings.disableEditor = settings.disableEditor||false;
102
+ }
103
+
104
+ if (settings.httpAdminRoot !== false) {
105
+ settings.httpAdminRoot = formatRoot(settings.httpAdminRoot || settings.httpRoot || "/");
106
+ settings.httpAdminAuth = settings.httpAdminAuth || settings.httpAuth;
107
+ } else {
108
+ settings.disableEditor = true;
109
+ }
110
+
111
+ if (settings.httpNodeRoot !== false) {
112
+ settings.httpNodeRoot = formatRoot(settings.httpNodeRoot || settings.httpRoot || "/");
113
+ settings.httpNodeAuth = settings.httpNodeAuth || settings.httpAuth;
114
+ }
115
+
116
+ // replicate (settings.uiPort = settings.uiPort||1880;) but allow zero
117
+ if (settings.uiPort === undefined){
118
+ settings.uiPort = 1880;
119
+ }
120
+
121
+ settings.uiHost = settings.uiHost||"0.0.0.0";
122
+
123
+ try {
124
+ RED.init(server,settings);
125
+ } catch(err) {
126
+ if (err.code == "unsupported_version") {
127
+ console.log("Unsupported version of Node.js:",process.version);
128
+ console.log("Node-RED requires Node.js v8.9.0 or later");
129
+ } else {
130
+ console.log("Failed to start server:");
131
+ if (err.stack) {
132
+ console.log(err.stack);
133
+ } else {
134
+ console.log(err);
135
+ }
136
+ }
137
+ process.exit(1);
138
+ }
139
+
140
+ function basicAuthMiddleware(user,pass) {
141
+ var basicAuth = require('basic-auth');
142
+ var checkPassword;
143
+ var localCachedPassword;
144
+ if (pass.length == "32") {
145
+ // Assume its a legacy md5 password
146
+ checkPassword = function(p) {
147
+ return crypto.createHash('md5').update(p,'utf8').digest('hex') === pass;
148
+ }
149
+ } else {
150
+ checkPassword = function(p) {
151
+ return bcrypt.compareSync(p,pass);
152
+ }
153
+ }
154
+
155
+ var checkPasswordAndCache = function(p) {
156
+ // For BasicAuth routes we know the password cannot change without
157
+ // a restart of Node-RED. This means we can cache the provided crypted
158
+ // version to save recalculating each time.
159
+ if (localCachedPassword === p) {
160
+ return true;
161
+ }
162
+ var result = checkPassword(p);
163
+ if (result) {
164
+ localCachedPassword = p;
165
+ }
166
+ return result;
167
+ }
168
+
169
+ return function(req,res,next) {
170
+ if (req.method === 'OPTIONS') {
171
+ return next();
172
+ }
173
+ var requestUser = basicAuth(req);
174
+ if (!requestUser || requestUser.name !== user || !checkPasswordAndCache(requestUser.pass)) {
175
+ res.set('WWW-Authenticate', 'Basic realm="Authorization Required"');
176
+ return res.sendStatus(401);
177
+ }
178
+ next();
179
+ }
180
+ }
181
+
182
+ if (settings.httpAdminRoot !== false && settings.httpAdminAuth) {
183
+ RED.log.warn(RED.log._("server.httpadminauth-deprecated"));
184
+ app.use(settings.httpAdminRoot, basicAuthMiddleware(settings.httpAdminAuth.user,settings.httpAdminAuth.pass));
185
+ }
186
+
187
+ if (settings.httpAdminRoot !== false) {
188
+ app.use(settings.httpAdminRoot,RED.httpAdmin);
189
+ }
190
+ if (settings.httpNodeRoot !== false && settings.httpNodeAuth) {
191
+ app.use(settings.httpNodeRoot,basicAuthMiddleware(settings.httpNodeAuth.user,settings.httpNodeAuth.pass));
192
+ }
193
+ if (settings.httpNodeRoot !== false) {
194
+ app.use(settings.httpNodeRoot,RED.httpNode);
195
+ }
196
+ if (settings.httpStatic) {
197
+ settings.httpStaticAuth = settings.httpStaticAuth || settings.httpAuth;
198
+ if (settings.httpStaticAuth) {
199
+ app.use("/",basicAuthMiddleware(settings.httpStaticAuth.user,settings.httpStaticAuth.pass));
200
+ }
201
+ app.use("/",express.static(settings.httpStatic));
202
+ }
203
+
204
+ function getListenPath() {
205
+ var port = settings.serverPort;
206
+ if (port === undefined){
207
+ port = settings.uiPort;
208
+ }
209
+
210
+ var listenPath = 'http'+(settings.https?'s':'')+'://'+
211
+ (settings.uiHost == '::'?'localhost':(settings.uiHost == '0.0.0.0'?'127.0.0.1':settings.uiHost))+
212
+ ':'+port;
213
+ if (settings.httpAdminRoot !== false) {
214
+ listenPath += settings.httpAdminRoot;
215
+ } else if (settings.httpStatic) {
216
+ listenPath += "/";
217
+ }
218
+ return listenPath;
219
+ }
220
+
221
+ RED.start().then(function() {
222
+ if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
223
+ server.on('error', function(err) {
224
+ if (err.errno === "EADDRINUSE") {
225
+ RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
226
+ RED.log.error(RED.log._("server.port-in-use"));
227
+ } else {
228
+ RED.log.error(RED.log._("server.uncaught-exception"));
229
+ if (err.stack) {
230
+ RED.log.error(err.stack);
231
+ } else {
232
+ RED.log.error(err);
233
+ }
234
+ }
235
+ process.exit(1);
236
+ });
237
+
238
+ // Log all the delayed messages, since they can be translated at this point
239
+ delayedLogItems.forEach(function (delayedLogItem, index) {
240
+ RED.log[delayedLogItem.type](RED.log._(delayedLogItem.id, delayedLogItem.params||{}));
241
+ });
242
+
243
+ server.listen(settings.uiPort,settings.uiHost,function() {
244
+ if (settings.httpAdminRoot === false) {
245
+ RED.log.info(RED.log._("server.admin-ui-disabled"));
246
+ }
247
+ settings.serverPort = server.address().port;
248
+ process.title = 'node-red';
249
+ RED.log.info(RED.log._("server.now-running", {listenpath:getListenPath()}));
250
+ });
251
+ } else {
252
+ RED.log.info(RED.log._("server.headless-mode"));
253
+ }
254
+ }).catch(function(err) {
255
+ RED.log.error(RED.log._("server.failed-to-start"));
256
+ if (err.stack) {
257
+ RED.log.error(err.stack);
258
+ } else {
259
+ RED.log.error(err);
260
+ }
261
+ });
262
+
263
+ process.on('uncaughtException',function(err) {
264
+ util.log('[red] Uncaught Exception:');
265
+ if (err.stack) {
266
+ util.log(err.stack);
267
+ } else {
268
+ util.log(err);
269
+ }
270
+ process.exit(1);
271
+ });
272
+
273
+ var stopping = false;
274
+ function exitWhenStopped() {
275
+ if (!stopping) {
276
+ stopping = true;
277
+ RED.stop().then(function() {
278
+ process.exit();
279
+ });
280
+ }
281
+ }
282
+ process.on('SIGINT', exitWhenStopped);
283
+ process.on('SIGTERM', exitWhenStopped);
284
+ process.on('SIGHUP', exitWhenStopped);
285
+ process.on('SIGUSR2', exitWhenStopped); // for nodemon restart
286
+ process.on('SIGBREAK', exitWhenStopped); // for windows ctrl-break
287
+ process.on('message', function(m) { // for PM2 under window with --shutdown-with-message
288
+ if (m === 'shutdown') { exitWhenStopped() }
289
+ });
290
+
291
+ }).catch(function(err) {
292
+ console.log("Failed to get https settings: " + err);
293
+ });
294
+ };
@@ -0,0 +1,13 @@
1
+ const express = require('express');
2
+
3
+ module.exports = function (app) {
4
+ const router = express.Router();
5
+
6
+ router.get('/', function (req, res, next) {
7
+ res.json({
8
+ status: 'UP'
9
+ });
10
+ });
11
+
12
+ app.use('/health', router);
13
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Copyright 2014, 2019 IBM Corp.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ **/
16
+
17
+ var path = require("path");
18
+ var util = require("util");
19
+ var fs = require("fs");
20
+
21
+ const mongoUrl = process.env.MONGO_URL;
22
+
23
+ const REGEX_LEADING_ALPHA = /^[^a-zA-Z]*/;
24
+ const REGEX_ALPHA_NUM = /[^a-zA-Z0-9]/g;
25
+
26
+ // function _sanitizeAppName(name) {
27
+ // name = name || 'node-red';
28
+ // return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, '');
29
+ // }
30
+
31
+ // var dbName = _sanitizeAppName(process.env.NODE_RED_STORAGE_DB_NAME || "nodered");
32
+
33
+ var userDir = process.env.NODE_RED_STORAGE_USER_DIR || path.join(__dirname, ".node-red");
34
+ // Ensure userDir exists - something that is normally taken care of by
35
+ // localfilesystem storage when running locally
36
+ if (!fs.existsSync(userDir)) fs.mkdirSync(userDir);
37
+ if (!fs.existsSync(path.join(userDir, "node_modules"))) fs.mkdirSync(path.join(userDir, "node_modules"));
38
+
39
+ var settings = module.exports = {
40
+ uiPort: process.env.PORT || 1880,
41
+ mqttReconnectTime: 15000,
42
+ debugMaxLength: 1000,
43
+
44
+ //Flag for enabling Appmetrics dashboard (https://github.com/RuntimeTools/appmetrics-dash)
45
+ useAppmetrics: false,
46
+
47
+ userDir: userDir,
48
+
49
+ flowFile: path.join('..', 'flows', `${process.env.NODE_RED_STORAGE_APP_NAME || "nodered"}.json`),
50
+
51
+ // Add the bluemix-specific nodes in
52
+ nodesDir: path.join(__dirname, "nodes"),
53
+
54
+ // Blacklist the non-bluemix friendly nodes
55
+ nodesExcludes: ['90-exec.js', '28-tail.js', '10-file.js', '23-watch.js'],
56
+
57
+ // Enable module reinstalls on start-up; this ensures modules installed
58
+ // post-deploy are restored after a restage
59
+ autoInstallModules: true,
60
+
61
+ // Move the admin UI
62
+ httpAdminRoot: '/red',
63
+
64
+ // Serve up the welcome page
65
+ httpStatic: path.join(__dirname, "public"),
66
+
67
+ functionGlobalContext: {
68
+ lodash: require('lodash'),
69
+ moment: require('moment'),
70
+ validator: require('validator')
71
+ },
72
+
73
+ // Configure the logging output
74
+ logging: {
75
+ // Only console logging is currently supported
76
+ console: {
77
+ // Level of logging to be recorded. Options are:
78
+ // fatal - only those errors which make the application unusable should be recorded
79
+ // error - record errors which are deemed fatal for a particular request + fatal errors
80
+ // warn - record problems which are non fatal + errors + fatal errors
81
+ // info - record information about the general running of the application + warn + error + fatal errors
82
+ // debug - record information which is more verbose than info + info + warn + error + fatal errors
83
+ // trace - record very detailed logging + debug + info + warn + error + fatal errors
84
+ // off - turn off all logging (doesn't affect metrics or audit)
85
+ level: "info",
86
+ // Whether or not to include metric events in the log output
87
+ metrics: false,
88
+ // Whether or not to include audit events in the log output
89
+ audit: true
90
+ }
91
+ },
92
+
93
+ editorTheme: {
94
+ page: {
95
+ title: "Flow Builder",
96
+ favicon: path.join(__dirname, "public", "favicon.ico"),
97
+ css: "",
98
+ scripts: []
99
+ },
100
+ header: {
101
+ title: "Flow Builder",
102
+ image: path.join(__dirname, "public", "steedos.png"),
103
+ // url: "https://www.steedos.com" // optional url to make the header text/image a link to this url
104
+ },
105
+ }
106
+ };
107
+
108
+ if (!mongoUrl) {
109
+ util.log("Failed to find the env MONGO_URL");
110
+ util.log("Falling back to local filesystem storage. Changes will *not* be saved across application restarts.");
111
+ } else {
112
+ // Set the Cloudant storage module settings
113
+ settings.mongodbSettings = {
114
+ // The name of the service instance to use.
115
+ mongoURI: process.env.MONGO_URL,
116
+ // The prefix for all document names stored by this instance.
117
+ appname: process.env.NODE_RED_STORAGE_APP_NAME || "nodered"
118
+ }
119
+ util.log("Using mongodb storage: " + settings.mongodbSettings.mongoURI + " appname:" + settings.mongodbSettings.appname);
120
+ settings.storageModule = require('@steedos/node-red-contrib-mongodb-storage')
121
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steedos-app-default",
3
- "version": "2.1.55",
3
+ "version": "2.1.59",
4
4
  "description": "A Steedos App",
5
5
  "main": "package.service.js",
6
6
  "license": "MIT",
@@ -35,8 +35,8 @@ cfs:
35
35
  tenant:
36
36
  _id: ${STEEDOS_CLOUD_SPACE_ID}
37
37
  name: 华炎魔方
38
- logo_url:
39
- logo_square_url:
38
+ logo_url: ${STEEDOS_CLOUD_LOGO_URL}
39
+ logo_square_url: ${STEEDOS_CLOUD_LOGO_SQUARE_URL}
40
40
  background_url:
41
41
  enable_register: ${STEEDOS_TENANT_CONFIG_ENABLE_REGISTER} # 启用注册功能 true / false
42
42
  enable_forget_password: false