diff --git a/admin/app/translations.js b/admin/app/translations.js index 11fb9c0b..1f6497fb 100644 --- a/admin/app/translations.js +++ b/admin/app/translations.js @@ -834,6 +834,7 @@ function config($translateProvider) { INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', + KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_NOT_FOUND: 'Master Meter Not Found', @@ -1821,6 +1822,7 @@ function config($translateProvider) { INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', + KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_NOT_FOUND: 'Master Meter Not Found', @@ -2807,6 +2809,7 @@ function config($translateProvider) { INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', + KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_NOT_FOUND: 'Master Meter Not Found', diff --git a/database/myems_fdd_db.sql b/database/myems_fdd_db.sql index c21d38cf..d80c1d23 100644 --- a/database/myems_fdd_db.sql +++ b/database/myems_fdd_db.sql @@ -7,6 +7,22 @@ DROP DATABASE IF EXISTS `myems_fdd_db` ; CREATE DATABASE IF NOT EXISTS `myems_fdd_db` ; USE `myems_fdd_db` ; +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_fdd_db`.`tbl_aliyun_sms_api` +-- refer to https://dysms.console.aliyun.com/ +-- API Version 2017-05-25 +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` ; + +CREATE TABLE IF NOT EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `access_key_id` VARCHAR(256) NOT NULL, + `access_key_secret` VARCHAR(256) NOT NULL, + `endpoint` VARCHAR(256) NOT NULL, + `sign_name` VARCHAR(256) NOT NULL, + `template_code` VARCHAR(256) NOT NULL, + PRIMARY KEY (`id`)); + -- --------------------------------------------------------------------------------------------------------------------- -- Table `myems_fdd_db`.`tbl_email_messages` -- --------------------------------------------------------------------------------------------------------------------- diff --git a/database/myems_system_db.sql b/database/myems_system_db.sql index 5182ae94..136ede93 100644 --- a/database/myems_system_db.sql +++ b/database/myems_system_db.sql @@ -1243,6 +1243,6 @@ USE `myems_system_db`; INSERT INTO `myems_system_db`.`tbl_versions` (`id`, `version`, `release_date`) VALUES -(1, '1.2.3', '2021-09-04'); +(1, '1.2.4', '2021-09-11'); COMMIT; diff --git a/database/upgrade/upgrade1.2.4.sql b/database/upgrade/upgrade1.2.4.sql new file mode 100644 index 00000000..0c262461 --- /dev/null +++ b/database/upgrade/upgrade1.2.4.sql @@ -0,0 +1,18 @@ +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_fdd_db`.`tbl_aliyun_sms_api` +-- refer to https://dysms.console.aliyun.com/ +-- API Version 2017-05-25 +-- --------------------------------------------------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `access_key_id` VARCHAR(256) NOT NULL, + `access_key_secret` VARCHAR(256) NOT NULL, + `endpoint` VARCHAR(256) NOT NULL, + `sign_name` VARCHAR(256) NOT NULL, + `template_code` VARCHAR(256) NOT NULL, + PRIMARY KEY (`id`)); + +DROP TABLE IF EXISTS `myems_fdd_db`.`tbl_gsm_modems` ; + +-- UPDATE VERSION NUMBER +UPDATE myems_system_db.tbl_versions SET version='1.2.4', release_date='2021-09-11' WHERE id=1; diff --git a/myems-api/README.md b/myems-api/README.md index 185d9a76..2a55fc7d 100644 --- a/myems-api/README.md +++ b/myems-api/README.md @@ -117,9 +117,7 @@ git clone https://github.com/MyEMS/myems.git cd ~/myems/myems-api sudo cp -R ~/myems/myems-api /myems-api ``` - Change the config file: - - Note: change cookie domain to the actual domain or IP address of Web UI and Admin UI + Change IP address in the config file: ```bash sudo nano /myems-api/config.py ``` @@ -283,9 +281,9 @@ curl -i -X GET {{base_url}}/costfiles curl -i -X DELETE {{base_url}}/costfiles/{id} ``` * POST Upload a Cost File - (user must login first to get cookie) + (call users login API to get 'User-UUID' and 'Token') ```bash -curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/costfiles +curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/costfiles ``` * GET Restore a Cost File by ID from database to disk ```bash @@ -944,9 +942,9 @@ curl -i -X GET {{base_url}}/knowledgefiles curl -i -X DELETE {{base_url}}/knowledgefiles/{id} ``` * POST Upload a Knowledge File - (user must login first to get cookie) + (call users login API to get 'User-UUID' and 'Token') ```bash -curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/knowledgefiles +curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/knowledgefiles ``` * GET Restore a Knowledge File by id from database to disk ```bash @@ -1140,9 +1138,9 @@ curl -i -X GET {{base_url}}/offlinemeterfiles curl -i -X DELETE {{base_url}}/offlinemeterfiles/{id} ``` * POST Upload an Offline Meter File - (user must log in first to get cookie) + (call users login API to get 'User-UUID' and 'Token') ```bash -curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/offlinemeterfiles +curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/offlinemeterfiles ``` * GET Restore an Offline Meter File by ID from database to disk ```bash diff --git a/myems-api/config.py b/myems-api/config.py index 5a365c99..b762986a 100644 --- a/myems-api/config.py +++ b/myems-api/config.py @@ -61,10 +61,6 @@ myems_reporting_db = { 'database': 'myems_reporting_db', } -# address for Cookie domain -# use the actual domain or IP address of Web UI and Admin UI -myems_api_domain = '127.0.0.1' - # indicated in how many minutes to calculate meter energy consumption # 30 for half hourly period # 60 for hourly period diff --git a/myems-api/core/knowledgefile.py b/myems-api/core/knowledgefile.py index 43946971..75154c46 100644 --- a/myems-api/core/knowledgefile.py +++ b/myems-api/core/knowledgefile.py @@ -257,12 +257,11 @@ class KnowledgeFileItem: file_uuid = row[0] # Define file_path file_path = os.path.join(config.upload_path, file_uuid) - # remove the file from disk os.remove(file_path) except Exception as ex: raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', - description='API.KNOWLEDGE_FILE_NOT_FOUND') + description='API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK') cursor.execute(" DELETE FROM tbl_knowledge_files WHERE id = %s ", (id_,)) cnx.commit() diff --git a/myems-api/core/user.py b/myems-api/core/user.py index b78b5d3f..9d1fb7c6 100644 --- a/myems-api/core/user.py +++ b/myems-api/core/user.py @@ -447,10 +447,6 @@ class UserLogin: cnx.commit() cursor.close() cnx.disconnect() - resp.set_cookie('user_uuid', user_uuid, - domain=config.myems_api_domain, path='/', secure=False, http_only=False) - resp.set_cookie('token', token, - domain=config.myems_api_domain, path='/', secure=False, http_only=False) del result['salt'] del result['password'] result['token'] = token @@ -502,11 +498,6 @@ class UserLogout: if rowcount is None or rowcount == 0: raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND', description='API.USER_SESSION_NOT_FOUND') - - resp.set_cookie('user_uuid', '', - domain=config.myems_api_domain, path='/', secure=False, http_only=False) - resp.set_cookie('token', '', - domain=config.myems_api_domain, path='/', secure=False, http_only=False) resp.body = json.dumps("OK") resp.status = falcon.HTTP_200 diff --git a/myems-api/core/userlogger.py b/myems-api/core/userlogger.py index fd76756d..f40e5c4b 100644 --- a/myems-api/core/userlogger.py +++ b/myems-api/core/userlogger.py @@ -54,12 +54,12 @@ def user_logger(func): func(*args, **kwargs) return req, resp = args - cookies = req.cookies - if cookies is not None and 'user_uuid' in cookies.keys(): - user_uuid = cookies['user_uuid'] + headers = req.headers + if headers is not None and 'USER-UUID' in headers.keys(): + user_uuid = headers['USER-UUID'] else: # todo: deal with requests with NULL user_uuid - print('user_logger: user_uuid is NULL') + print('user_logger: USER-UUID is NULL') # do not log for NULL user_uuid func(*args, **kwargs) return diff --git a/myems-api/reports/dashboard.py b/myems-api/reports/dashboard.py index 844a0d7c..0b03d626 100644 --- a/myems-api/reports/dashboard.py +++ b/myems-api/reports/dashboard.py @@ -33,7 +33,6 @@ class Reporting: #################################################################################################################### @staticmethod def on_get(req, resp): - print(req.params) user_uuid = req.params.get('useruuid') period_type = req.params.get('periodtype') base_start_datetime_local = req.params.get('baseperiodstartdatetime') diff --git a/web/README.md b/web/README.md index ad00db13..57493eca 100644 --- a/web/README.md +++ b/web/README.md @@ -1,67 +1,63 @@ # MyEMS Web ## Introduction -MyEMS Web 用户界面,用于能源数据分析 -Providing Web UI for MyEMS users to analysis energy data +MyEMS Web 用户界面,用于查询能源报表 +Providing Web UI of MyEMS for viewing energy reports ## Prerequisites Node.js -nginx-1.18.0 or later - -## Running in Local environment -This project is scaffolded using Create React App. +## Running in Local Environment for Development * Install Node.js via binary archive on Linux Download Current Linux Binaries (x64) from https://nodejs.org/en/download/current/ -Unzip the binary archive to /usr/local/bin/nodejs, ```bash sudo mkdir -p /usr/local/lib/nodejs -sudo tar -xJvf node-v1x.x.x-linux-x64.tar.xz -C /usr/local/lib/nodejs +sudo tar -xJvf node-vxx.x.x-linux-x64.tar.xz -C /usr/local/lib/nodejs +sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/node /usr/bin/node +sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/npm /usr/bin/npm +sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/npx /usr/bin/npx ``` -Using sudo to symlink node, npm, and npx into /usr/bin/: -```bash -sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/node /usr/bin/node -``` -```bash -sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/npm /usr/bin/npm -``` -```bash -sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/npx /usr/bin/npx -``` -Test installation using +Test installation ```bash node -v -``` -```bash npm version -``` -```bash npx -v ``` -* Open the “myems/web” directory with your cmd or terminal -* Run 'sudo npm i --unsafe-perm=true --allow-root' - -This command will download all the necessary dependencies for falcon in the node_modules directory. -* If you modified any scss files, then you need to compile SCSS -Run 'sudo npm run scss' command in your project directory to compile scss. -* Run 'sudo npm start' +* Download all the necessary dependencies into the node_modules directory. +```bash +cd myems/web +sudo npm i --unsafe-perm=true --allow-root +``` +* If you modified any scss files then you need to compile SCSS, else you can safely ignore this step. +Run below command in your project directory to compile scss. +```bash +sudo npm run scss +``` +* Starting the Development Server A local web server will start at http://localhost:3000. We are using webpack and webpack-serve to automatically detect file changes. So, if you edit and save a file, your browser will automatically refresh and preview the change. +``` +sudo npm start +``` -## Creating a Production Build -* Run 'sudo npm run build' command in your project directory to make the Production build. - +## Install Production Build Option 1: on Node.js Web Server +* Run below command in your project directory to make the Production build. This will create an optimized production build by compililing, merging and minifying all the source files as necessary and put them in the build/ folder. +```bash +sudo npm run build +``` +* Run the production build locally at http://localhost:80. +If you want to listen on other port, change it in myems/web/server.js +``` +sudo node server.js +``` -You can run 'node server.js' to run the production build locally at http://localhost:5000. - -## Option 1: Install Production Build on NGINX Server +## Install Production Build Option 2: on NGINX Server (Highly Recommended) * Install NGINX Server - refer to http://nginx.org/en/docs/install.html * Configure NGINX @@ -107,16 +103,16 @@ Restart NGINX sudo systemctl restart nginx ``` -* Download myems: +* Download MyEMS: ```bash cd ~ git clone https://github.com/MyEMS/myems.git ``` -* Install myems-web : +* Install MyEMS Web UI: Check and change the config file if necessary: ```bash -cd ~/myems/web +cd myems/web sudo nano src/config.js ``` Build and Compress @@ -133,7 +129,7 @@ sudo rm -r /var/www/html/web sudo mv build /var/www/html/web ``` -## Option 2: Install Production Build on Apache2 Server +## Install Production Build Option 3: on Apache2 Server * Install Apache2 Server refer to https://httpd.apache.org/docs/2.4/install.html @@ -165,21 +161,21 @@ Add a new 'VirtualHost' as below ``` -* Download myems: +* Download MyEMS: ```bash cd ~ git clone https://github.com/MyEMS/myems.git ``` -* Install myems-web : +* Install MyEMS Web UI: Check and change the config file if necessary: ```bash -cd ~/myems/web +cd myems/web sudo nano src/config.js ``` Build and Compress ```bash -cd ~/myems/web/ +cd myems/web/ sudo npm run build tar czvf myems-web.tar.gz build ``` @@ -190,4 +186,4 @@ tar czvf myems-web.tar.gz build tar xzf myems-web.tar.gz sudo rm -r /var/www/web sudo mv build /var/www/web -``` \ No newline at end of file +``` diff --git a/web/package-lock.json b/web/package-lock.json index 3952689e..b7fe83ae 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -30,6 +30,7 @@ "echarts-for-react": "^2.0.16", "element-resize-event": "^3.0.3", "emoji-mart": "^3.0.0", + "express-rate-limit": "^5.3.0", "fuse.js": "^6.4.3", "google-maps-react": "^2.0.6", "i18next": "^19.6.3", @@ -8599,6 +8600,11 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz", + "integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew==" + }, "node_modules/express/node_modules/array-flatten": { "version": "1.1.1", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" @@ -28780,6 +28786,11 @@ } } }, + "express-rate-limit": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz", + "integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew==" + }, "ext": { "version": "1.4.0", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", diff --git a/web/package.json b/web/package.json index 59399009..439b31e3 100644 --- a/web/package.json +++ b/web/package.json @@ -25,6 +25,7 @@ "echarts-for-react": "^2.0.16", "element-resize-event": "^3.0.3", "emoji-mart": "^3.0.0", + "express-rate-limit": "^5.3.0", "fuse.js": "^6.4.3", "google-maps-react": "^2.0.6", "i18next": "^19.6.3", diff --git a/web/server.js b/web/server.js index 2c37d479..11de3884 100644 --- a/web/server.js +++ b/web/server.js @@ -21,6 +21,6 @@ app.use(limiter); app.get('*', function(req, res) { res.sendFile(path.join(__dirname, 'build', 'index.html')); }); -app.listen(process.env.PORT || 5000, function() { - console.log(`Frontend start on http://localhost:5000`); +app.listen(process.env.PORT || 80, function() { + console.log(`Frontend start on http://localhost:80`); }); diff --git a/web/src/i18n.js b/web/src/i18n.js index f10b33f6..9bf58b21 100644 --- a/web/src/i18n.js +++ b/web/src/i18n.js @@ -597,6 +597,7 @@ const resources = { "API.INVALID_VIRTUAL_METER_NAME": "Invalid virtual meter name", "API.INVALID_WEB_MESSAGE_ID": "Invalid web message id", "API.INVALID_WECHAT_MESSAGE_ID": "Invalid wechat message id", + "API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "Knowledge File Cannot be Removed from Disk", "API.KNOWLEDGE_FILE_NOT_FOUND": "Knowledge file not found", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "Master meter does not belong to same energy category", "API.MASTER_METER_NOT_FOUND": "Master meter not found", @@ -1346,6 +1347,7 @@ const resources = { "API.INVALID_VIRTUAL_METER_NAME": "", "API.INVALID_WEB_MESSAGE_ID": "", "API.INVALID_WECHAT_MESSAGE_ID": "", + "API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "", "API.KNOWLEDGE_FILE_NOT_FOUND": "", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "", "API.MASTER_METER_NOT_FOUND": "", @@ -2095,6 +2097,7 @@ const resources = { "API.INVALID_VIRTUAL_METER_NAME": "", "API.INVALID_WEB_MESSAGE_ID": "", "API.INVALID_WECHAT_MESSAGE_ID": "", + "API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "", "API.KNOWLEDGE_FILE_NOT_FOUND": "", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "", "API.MASTER_METER_NOT_FOUND": "",