flexbiz-server 12.3.30 → 12.3.32
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.
- package/install_centos7.sh +292 -22
- package/package.json +3 -2
- package/server/app.js +16 -15
- package/server/auths/local.js +32 -32
- package/server/cluster.js +23 -22
- package/server/controllers/controller.js +82 -73
- package/server/controllers/controllerRPT.js +7 -9
- package/server/controllers/controllerUtils.js +36 -36
- package/server/controllers/createHandler.js +34 -30
- package/server/controllers/deleteHandler.js +11 -11
- package/server/controllers/exportHandler.js +18 -18
- package/server/controllers/findHandler.js +36 -33
- package/server/controllers/importHandler.js +22 -22
- package/server/controllers/rptExcelHandler.js +5 -4
- package/server/controllers/rptHandler.js +11 -10
- package/server/controllers/updateFieldHandler.js +2 -2
- package/server/controllers/updateHandler.js +37 -33
- package/server/controllers/viewHandler.js +13 -13
- package/server/data/sys/listinfo.js +59661 -33452
- package/server/data/sys/menuinfo.js +24 -1
- package/server/data/sys/moduleinfo.js +9000 -520
- package/server/data/sys/reportinfo.js +1348 -1176
- package/server/flow/nodes/data.js +3 -4
- package/server/global.js +4 -3
- package/server/libs/WorkerStaticPool.js +12 -11
- package/server/libs/ckcn.js +11 -11
- package/server/libs/dktk.js +3 -3
- package/server/libs/dkvt.js +9 -8
- package/server/libs/docs.js +1 -0
- package/server/libs/dtbanletheosp.js +14 -14
- package/server/libs/getGiaban.js +34 -35
- package/server/libs/htmlReport.js +8 -6
- package/server/libs/invoiceEasy.js +109 -0
- package/server/libs/invoiceViettel.js +29 -0
- package/server/libs/invoiceVnpt.js +22 -0
- package/server/libs/mailmanagement.js +2 -2
- package/server/libs/permission.js +27 -25
- package/server/libs/post-book.js +13 -13
- package/server/libs/post-socai.js +22 -20
- package/server/libs/post-sokho.js +21 -18
- package/server/libs/prototypes.js +5 -6
- package/server/libs/redis-cache.js +1 -1
- package/server/libs/thnxt.js +9 -8
- package/server/libs/tinhhoahong.js +3 -3
- package/server/libs/tinhhoahongnpp.js +27 -27
- package/server/libs/tinhkhauhao1ts.js +1 -1
- package/server/libs/utils.js +62 -67
- package/server/libs/vsocai.js +6 -6
- package/server/models/app.js +6 -6
- package/server/models/approve.js +20 -22
- package/server/models/banggiaban.js +5 -4
- package/server/models/calllog.js +1 -1
- package/server/models/chamcong.js +4 -4
- package/server/models/checkin.js +3 -2
- package/server/models/customer.js +2 -2
- package/server/models/dmloaicong.js +2 -2
- package/server/models/dmnv.js +2 -2
- package/server/models/dmvt.js +11 -10
- package/server/models/email.js +2 -0
- package/server/models/hd2.js +14 -13
- package/server/models/hd3.js +11 -10
- package/server/models/hmcn.js +2 -2
- package/server/models/listinfo.js +262 -164
- package/server/models/mailaccount.js +3 -3
- package/server/models/notification.js +4 -3
- package/server/models/options.js +3 -2
- package/server/models/pcl.js +6 -0
- package/server/models/pgh.js +5 -0
- package/server/models/phucap.js +4 -3
- package/server/models/pn1.js +6 -6
- package/server/models/pnc.js +6 -5
- package/server/models/pnh.js +6 -5
- package/server/models/pxc.js +6 -5
- package/server/models/pxh.js +7 -6
- package/server/models/receivedinvoice.js +2 -0
- package/server/models/right.js +1 -1
- package/server/models/socai.js +13 -13
- package/server/models/sokho.js +19 -19
- package/server/models/tdttco.js +2 -2
- package/server/models/tdttco_tt.js +2 -2
- package/server/models/tdttno.js +2 -2
- package/server/models/tdttno_tt.js +2 -2
- package/server/models/user.js +21 -25
- package/server/models/warrantyclaim.js +2 -0
- package/server/models/warrantypolicy.js +1 -0
- package/server/modules/lists/ls-approve.js +2 -2
- package/server/modules/lists/ls-calllog.js +4 -1
- package/server/modules/lists/ls-checkin.js +12 -6
- package/server/modules/lists/ls-dmchietkhau.js +12 -11
- package/server/modules/lists/ls-dmnkh.js +5 -5
- package/server/modules/lists/ls-dmnv.js +2 -2
- package/server/modules/lists/ls-dmvt.js +25 -25
- package/server/modules/lists/ls-email.js +3 -0
- package/server/modules/lists/ls-mailaccount.js +5 -4
- package/server/modules/lists/ls-phucap.js +2 -1
- package/server/modules/public/callin.js +6 -5
- package/server/modules/public/subscribe.js +3 -3
- package/server/modules/reports/calc-tinhluong.js +22 -16
- package/server/modules/reports/rp-bkct.js +4 -4
- package/server/modules/reports/rp-cdpskh.js +6 -6
- package/server/modules/reports/rp-chitietchitientheohoadon.js +2 -2
- package/server/modules/reports/rp-chitiettaisan.js +7 -6
- package/server/modules/reports/rp-chitietthutientheohoadon.js +2 -2
- package/server/modules/reports/rp-ckcn.js +1 -1
- package/server/modules/reports/rp-ctbanle2.js +14 -14
- package/server/modules/reports/rp-dtbanlekempk.js +9 -0
- package/server/modules/reports/rp-dtbanletheoct.js +13 -11
- package/server/modules/reports/rp-dtbanletheoctkempk.js +26 -0
- package/server/modules/reports/rp-getdinhmuc4lenhcp.js +5 -5
- package/server/modules/reports/rp-getluong.js +8 -8
- package/server/modules/reports/rp-getluongchuyen.js +4 -4
- package/server/modules/reports/rp-phanbochitienchohoadon.js +2 -2
- package/server/modules/reports/rp-phanbothutienchohoadon.js +4 -4
- package/server/modules/reports/rp-sokho.js +7 -5
- package/server/modules/reports/rp-soquy.js +12 -7
- package/server/modules/reports/rp-sotaisan.js +1 -1
- package/server/modules/reports/rp-thbanhangkempk.js +29 -0
- package/server/modules/reports/rp-thnxt.js +12 -9
- package/server/modules/reports/rp-thnxt_sl.js +8 -8
- package/server/modules/reports/rp-thnxtnpp.js +7 -8
- package/server/modules/reports/rp-thnxttt.js +8 -8
- package/server/modules/systems/sys-app.js +18 -15
- package/server/modules/systems/sys-listinfo.js +7 -6
- package/server/modules/systems/sys-trangthai.js +3 -2
- package/server/modules/systems/sys-user.js +6 -6
- package/server/modules/systems/sys-users.js +8 -8
- package/server/modules/vouchers/vo-bc1.js +8 -8
- package/server/modules/vouchers/vo-dh2.js +9 -9
- package/server/modules/vouchers/vo-hd2.js +95 -103
- package/server/modules/vouchers/vo-hd3.js +46 -38
- package/server/modules/vouchers/vo-htl.js +8 -9
- package/server/modules/vouchers/vo-pbl.js +47 -47
- package/server/modules/vouchers/vo-pcl.js +8 -0
- package/server/modules/vouchers/vo-pgh.js +19 -0
- package/server/modules/vouchers/vo-pn1.js +31 -29
- package/server/modules/vouchers/vo-pnc.js +19 -18
- package/server/modules/vouchers/vo-pnh.js +16 -13
- package/server/modules/vouchers/vo-pt1.js +16 -16
- package/server/modules/vouchers/vo-ptl.js +7 -8
- package/server/modules/vouchers/vo-pxc.js +22 -20
- package/server/modules/vouchers/vo-pxh.js +24 -11
- package/server/modules/vouchers/vo-qts.js +1 -1
- package/server/modules/vouchers/vo-so1.js +9 -9
- package/server/modules/vouchers/vo-so7.js +10 -10
- package/server/modules/vouchers/vo-so9.js +7 -7
- package/server/route.js +50 -50
- package/server/services/invoiceFetcher.js +15 -0
- package/server/workers/customerOnImport.js +3 -3
- package/server/workers/inputWorker.js +1 -1
- package/server/workers/pushNotify.js +5 -4
- package/server/workers/reportWorker.js +2 -2
- package/server/workers/restoreApp.js +18 -17
package/install_centos7.sh
CHANGED
|
@@ -7,7 +7,6 @@ sudo yum update -y
|
|
|
7
7
|
sudo yum install -y epel-release
|
|
8
8
|
echo "Cập nhật hệ thống hoàn tất."
|
|
9
9
|
|
|
10
|
-
---
|
|
11
10
|
|
|
12
11
|
# --- Cài đặt MongoDB (Phiên bản mới nhất - 7.0) ---
|
|
13
12
|
echo ""
|
|
@@ -54,7 +53,6 @@ sudo systemctl start mongod
|
|
|
54
53
|
sudo systemctl enable mongod
|
|
55
54
|
echo "Cài đặt MongoDB hoàn tất."
|
|
56
55
|
|
|
57
|
-
---
|
|
58
56
|
|
|
59
57
|
# --- Cài đặt Redis và cấu hình vĩnh viễn ---
|
|
60
58
|
echo ""
|
|
@@ -69,23 +67,23 @@ REDIS_CONF="/etc/redis.conf"
|
|
|
69
67
|
# stop-writes-on-bgsave-error
|
|
70
68
|
if ! grep -q "stop-writes-on-bgsave-error no" "$REDIS_CONF"; then
|
|
71
69
|
sudo sed -i 's/^stop-writes-on-bgsave-error yes/stop-writes-on-bgsave-error no/' "$REDIS_CONF"
|
|
72
|
-
if ! grep -q "stop-writes-on-bgsave-error no" "$REDIS_CONF"; then
|
|
70
|
+
if ! grep -q "stop-writes-on-bgsave-error no" "$REDIS_CONF"; then # Nếu không có yes/no nào thì thêm mới
|
|
73
71
|
echo "stop-writes-on-bgsave-error no" | sudo tee -a "$REDIS_CONF"
|
|
74
72
|
fi
|
|
75
73
|
fi
|
|
76
74
|
|
|
77
75
|
# dir và dbfilename
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
if grep -q "^dir " "$REDIS_CONF"; then
|
|
77
|
+
sudo sed -i 's|^dir .*|dir /home|' "$REDIS_CONF"
|
|
78
|
+
else
|
|
79
|
+
echo "dir /home" | sudo tee -a "$REDIS_CONF"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
if grep -q "^dbfilename " "$REDIS_CONF"; then
|
|
83
|
+
sudo sed -i 's/^dbfilename .*/dbfilename temp.rdb/' "$REDIS_CONF"
|
|
84
|
+
else
|
|
85
|
+
echo "dbfilename temp.rdb" | sudo tee -a "$REDIS_CONF"
|
|
86
|
+
fi
|
|
89
87
|
|
|
90
88
|
# Vô hiệu hóa lưu dữ liệu vào đĩa (CẢNH BÁO: Mất dữ liệu khi khởi động lại)
|
|
91
89
|
# Vô hiệu hóa appendonly
|
|
@@ -96,9 +94,8 @@ elif ! grep -q "^appendonly no" "$REDIS_CONF"; then
|
|
|
96
94
|
fi
|
|
97
95
|
|
|
98
96
|
# Vô hiệu hóa save
|
|
99
|
-
# Xóa tất cả các dòng save cũ
|
|
100
|
-
sudo
|
|
101
|
-
echo "save \"\"" | sudo tee -a "$REDIS_CONF"
|
|
97
|
+
sudo sed -i '/^save /d' "$REDIS_CONF" # Xóa tất cả các dòng save cũ
|
|
98
|
+
echo "save \"\"" | sudo tee -a "$REDIS_CONF" # Thêm dòng save rỗng
|
|
102
99
|
|
|
103
100
|
# Cấu hình vm.overcommit_memory để tránh lỗi "Cannot allocate memory"
|
|
104
101
|
echo "Cấu hình vm.overcommit_memory..."
|
|
@@ -111,7 +108,6 @@ sudo systemctl start redis
|
|
|
111
108
|
sudo systemctl enable redis
|
|
112
109
|
echo "Cài đặt Redis và cấu hình hoàn tất."
|
|
113
110
|
|
|
114
|
-
---
|
|
115
111
|
|
|
116
112
|
# --- Cài đặt Node.js (Phiên bản LTS mới nhất) ---
|
|
117
113
|
echo ""
|
|
@@ -124,7 +120,6 @@ fi
|
|
|
124
120
|
sudo yum install -y nodejs
|
|
125
121
|
echo "Cài đặt Node.js hoàn tất."
|
|
126
122
|
|
|
127
|
-
---
|
|
128
123
|
|
|
129
124
|
# --- Cài đặt PM2 ---
|
|
130
125
|
echo ""
|
|
@@ -137,7 +132,6 @@ if ! sudo systemctl is-enabled pm2-$(whoami) &>/dev/null; then
|
|
|
137
132
|
fi
|
|
138
133
|
echo "Cài đặt PM2 hoàn tất."
|
|
139
134
|
|
|
140
|
-
---
|
|
141
135
|
|
|
142
136
|
# --- Cài đặt Nginx và cấu hình SELinux ---
|
|
143
137
|
echo ""
|
|
@@ -162,7 +156,6 @@ if ! getsebool httpd_can_network_connect | grep -q "on"; then
|
|
|
162
156
|
fi
|
|
163
157
|
echo "Cài đặt Nginx và cấu hình SELinux hoàn tất."
|
|
164
158
|
|
|
165
|
-
---
|
|
166
159
|
|
|
167
160
|
# --- Tạo 20GB RAM ảo (Swap Space) ---
|
|
168
161
|
echo ""
|
|
@@ -186,9 +179,286 @@ else
|
|
|
186
179
|
fi
|
|
187
180
|
echo "Tạo 20GB RAM ảo hoàn tất."
|
|
188
181
|
|
|
182
|
+
|
|
183
|
+
# --- Tạo dự án Node.js và cấu hình Babel Build ---
|
|
184
|
+
echo ""
|
|
185
|
+
echo "--- Bắt đầu tạo dự án Node.js và cấu hình Babel Build ---"
|
|
186
|
+
|
|
187
|
+
# Lấy đường dẫn của script hiện tại
|
|
188
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
189
|
+
|
|
190
|
+
# Hỏi tên dự án từ người dùng
|
|
191
|
+
read -p "Nhập tên dự án Node.js của bạn (mặc định: flexbiz-server): " PROJECT_NAME
|
|
192
|
+
PROJECT_NAME=${PROJECT_NAME:-flexbiz-server} # Đặt giá trị mặc định nếu người dùng không nhập gì
|
|
193
|
+
|
|
194
|
+
PROJECT_PATH="$SCRIPT_DIR/$PROJECT_NAME"
|
|
195
|
+
|
|
196
|
+
# Kiểm tra xem thư mục dự án đã tồn tại chưa
|
|
197
|
+
if [ -d "$PROJECT_PATH" ]; then
|
|
198
|
+
echo "Thư mục dự án '$PROJECT_NAME' đã tồn tại tại '$PROJECT_PATH'."
|
|
199
|
+
echo "Bỏ qua việc tạo dự án và cài đặt dependencies/cấu hình ban đầu."
|
|
200
|
+
cd "$PROJECT_PATH" || { echo "Lỗi: Không thể chuyển đến thư mục dự án đã tồn tại."; exit 1; }
|
|
201
|
+
else
|
|
202
|
+
echo "Tạo thư mục dự án: $PROJECT_PATH"
|
|
203
|
+
mkdir -p "$PROJECT_PATH"
|
|
204
|
+
|
|
205
|
+
echo "Chuyển đến thư mục dự án và khởi tạo Node.js project..."
|
|
206
|
+
cd "$PROJECT_PATH" || { echo "Lỗi: Không thể chuyển đến thư mục dự án."; exit 1; }
|
|
207
|
+
|
|
208
|
+
npm init -y # Khởi tạo package.json với các giá trị mặc định
|
|
209
|
+
|
|
210
|
+
echo "Cài đặt các dependencies và devDependencies..."
|
|
211
|
+
npm install "blocked-at@^1.2.0" "flexbiz-server@latest" "http-proxy-middleware@3.0.5" # dependencies
|
|
212
|
+
npm install --save-dev "@babel/cli" "@babel/core" "@babel/node" "@babel/preset-env" # devDependencies
|
|
213
|
+
npm i -g "web-push"
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
echo "Tạo file .babelrc..."
|
|
217
|
+
cat << EOF > "$PROJECT_PATH/.babelrc"
|
|
218
|
+
{
|
|
219
|
+
"presets": ["@babel/preset-env"]
|
|
220
|
+
}
|
|
221
|
+
EOF
|
|
222
|
+
|
|
223
|
+
echo "Tạo thư mục src và file src/index.js..."
|
|
224
|
+
mkdir -p "$PROJECT_PATH/src"
|
|
225
|
+
cat << 'EOF_INDEXJS' > "$PROJECT_PATH/src/index.js"
|
|
226
|
+
import express from "express";
|
|
227
|
+
import Server from 'flexbiz-server/server/app';
|
|
228
|
+
const configs = require("./configs");
|
|
229
|
+
|
|
230
|
+
const app = express();
|
|
231
|
+
|
|
232
|
+
// Áp dụng các cấu hình
|
|
233
|
+
configs.use_ssl = false;
|
|
234
|
+
configs.BLOCKCHAIN_SOCKET = false;
|
|
235
|
+
configs.limitRequestSize = '50mb';
|
|
236
|
+
configs.limitFileSize = 1024*1024*50;
|
|
237
|
+
configs.has_api_barcode = true;
|
|
238
|
+
configs.createIndexes = true;
|
|
239
|
+
|
|
240
|
+
const port = process.argv[2] || 9999;
|
|
241
|
+
console.log("file start with port", port);
|
|
242
|
+
|
|
243
|
+
Server(app, {
|
|
244
|
+
configs,
|
|
245
|
+
port,
|
|
246
|
+
input_cpus: 4,
|
|
247
|
+
import_cpus: 1,
|
|
248
|
+
report_cpus: 1,
|
|
249
|
+
createRedisCache: true,
|
|
250
|
+
useSocket: true,
|
|
251
|
+
useAgenda: false,
|
|
252
|
+
cluster: false,
|
|
253
|
+
});
|
|
254
|
+
EOF_INDEXJS
|
|
255
|
+
|
|
256
|
+
echo "Tạo file src/configs.js (placeholder)..."
|
|
257
|
+
cat << 'EOF_CONFIGSJS' > "$PROJECT_PATH/src/configs.js"
|
|
258
|
+
// Đây là một file configs.js placeholder.
|
|
259
|
+
// Bạn cần thay đổi nội dung này với các cấu hình thực tế của mình.
|
|
260
|
+
exports.domain = 'localhost';
|
|
261
|
+
exports.api_url = 'http://localhost';
|
|
262
|
+
exports.home_url = 'http://localhost';
|
|
263
|
+
|
|
264
|
+
//Các domain không hạn chế quyền truy cập. Có thể khai báo trong api domain
|
|
265
|
+
exports.trust_domains = "";
|
|
266
|
+
exports.trust_keys =[];
|
|
267
|
+
|
|
268
|
+
exports.company = 'Tên công ty';
|
|
269
|
+
exports.program = "";
|
|
270
|
+
exports.version = "7.0.1";
|
|
271
|
+
exports.PORT = '443';
|
|
272
|
+
exports.use_ssl = true;
|
|
273
|
+
exports.trust_proxy = true;
|
|
274
|
+
exports.check_expire_date = false;//Kiểm tra hạn sử dụng của công ty
|
|
275
|
+
exports.timezone = 'Asia/Ho_Chi_Minh';
|
|
276
|
+
exports.initSysData = false;
|
|
277
|
+
exports.limitRequestSize = '5mb';
|
|
278
|
+
exports.limitFileSize = 1024*1024*2;
|
|
279
|
+
exports.limitRowImport = 20000;//giới hạn số dòng mỗi lần import
|
|
280
|
+
|
|
281
|
+
exports.cryptoPassword = 'ABC@1';//khoá dùng để mã hoá dữ liệu. cần thay đổi thông tin này
|
|
282
|
+
exports.MAX_TRY_OTP =3;
|
|
283
|
+
|
|
284
|
+
//maxLag for toobusy
|
|
285
|
+
exports.maxLag = 5000;
|
|
286
|
+
|
|
287
|
+
exports.check_token_expired = false;//Kiểm tra hạn sử dụng của token
|
|
288
|
+
exports.require_verify = false;//Yêu cầu user phải xác thực tài khoản trước khi sử dụng
|
|
289
|
+
exports.use_pin_as_otp = false;//Sử dụng mã pin thay cho OTP
|
|
290
|
+
|
|
291
|
+
exports.APP_SECRET = "";
|
|
292
|
+
//Token của user public
|
|
293
|
+
exports.public_token = "flex.public.token";
|
|
294
|
+
//Key để push thông báo qua website: use tool of webPush to create a vapidkeys. just need to run: web-push generate-vapid-keys --json
|
|
295
|
+
exports.vapidKeys = {"publicKey":"","privateKey":""}
|
|
296
|
+
//recaptcha
|
|
297
|
+
exports.GOOGLE_RECAPTCHA_SECRET_KEY = "";
|
|
298
|
+
//sử đụng google transtale api để tự động dịch label hay tin tức
|
|
299
|
+
exports.GOOGLE_TRANSLATE_API_KEY = "";
|
|
300
|
+
//đường dẫn các thư mục chứa source code và tài nguyên của hệ thống
|
|
301
|
+
exports.paths={
|
|
302
|
+
public:__dirname + "/public",
|
|
303
|
+
modules:__dirname + "/modules",
|
|
304
|
+
models:__dirname + "/models",
|
|
305
|
+
templates: __dirname + "/templates",
|
|
306
|
+
images: __dirname + "/images",
|
|
307
|
+
videos: __dirname + "/videos",
|
|
308
|
+
uploads: __dirname + "/uploads",
|
|
309
|
+
log: __dirname + "/log",
|
|
310
|
+
admin: "",
|
|
311
|
+
maps:"",
|
|
312
|
+
workers:""
|
|
313
|
+
}
|
|
314
|
+
//Cấu hình giới hạn băng thông truy cập
|
|
315
|
+
exports.limitRequest={
|
|
316
|
+
api:{
|
|
317
|
+
duration: 1,//seconds
|
|
318
|
+
points: 1000,
|
|
319
|
+
blockDuration:0,//seconds
|
|
320
|
+
},
|
|
321
|
+
sys:{
|
|
322
|
+
duration: 1,//seconds
|
|
323
|
+
points: 1000,
|
|
324
|
+
blockDuration:0,//seconds
|
|
325
|
+
},
|
|
326
|
+
public:{
|
|
327
|
+
duration: 1,//seconds
|
|
328
|
+
points: 1000,
|
|
329
|
+
blockDuration:0,//seconds
|
|
330
|
+
},
|
|
331
|
+
//required
|
|
332
|
+
auth:{
|
|
333
|
+
duration: 1,//seconds
|
|
334
|
+
points: 1000,
|
|
335
|
+
blockDuration:0,//seconds
|
|
336
|
+
},
|
|
337
|
+
//required
|
|
338
|
+
other:{
|
|
339
|
+
duration: 1,//seconds
|
|
340
|
+
points: 1000,
|
|
341
|
+
blockDuration:0,//seconds
|
|
342
|
+
},
|
|
343
|
+
}
|
|
344
|
+
//Cấu hình smtp để gửi email thông báo mặc định. Có thể cấu hình cho từng công ty thông qua màn hình khai báo thông tin công ty
|
|
345
|
+
exports.sender = {
|
|
346
|
+
"host": "",
|
|
347
|
+
"port": 465,
|
|
348
|
+
"requireTLS": true,
|
|
349
|
+
"tls": {
|
|
350
|
+
"ciphers": 'SSLv3'
|
|
351
|
+
},
|
|
352
|
+
"secureConnection": false,
|
|
353
|
+
"auth": {
|
|
354
|
+
"user": "",
|
|
355
|
+
"pass": ""
|
|
356
|
+
},
|
|
357
|
+
"name":"System"
|
|
358
|
+
}
|
|
359
|
+
exports.sender_otp = exports.sender;
|
|
360
|
+
//Tự động tạo user ADMIN
|
|
361
|
+
exports.adminUsers = [
|
|
362
|
+
{
|
|
363
|
+
email: 'admin',
|
|
364
|
+
name: 'Admin',
|
|
365
|
+
defaultPassword: 'admin@123456'
|
|
366
|
+
}
|
|
367
|
+
];
|
|
368
|
+
//Admin hệ thống cao nhất
|
|
369
|
+
exports.supperAdmin = "admin";
|
|
370
|
+
//Các admin phụ
|
|
371
|
+
exports.subAdmins = [];
|
|
372
|
+
//User Partners
|
|
373
|
+
exports.partnerUsers = [];
|
|
374
|
+
//
|
|
375
|
+
exports.admins =exports.adminUsers.map(u=>u.email)
|
|
376
|
+
exports.partners = exports.partnerUsers.map(u=>u.email);
|
|
377
|
+
//Danh sách các user support hệ thống: là các admin và subAdmins
|
|
378
|
+
exports.supportUsers = [...exports.admins,...exports.subAdmins];
|
|
379
|
+
console.log("support users",exports.supportUsers);
|
|
380
|
+
//cấu hình sms dùng để gửi tin nhắn OTP
|
|
381
|
+
exports.sms = {
|
|
382
|
+
send: async (Phone,otp_code,id_app)=>{
|
|
383
|
+
let Brandname="";
|
|
384
|
+
let Content =``;
|
|
385
|
+
let ApiKey = "";
|
|
386
|
+
let SecretKey = "";
|
|
387
|
+
let SmsType ="2";
|
|
388
|
+
let url = ``
|
|
389
|
+
|
|
390
|
+
const axios = require('axios');
|
|
391
|
+
try{
|
|
392
|
+
let data = (await axios.get(url)).data;
|
|
393
|
+
if(data.CodeResult=="100"){
|
|
394
|
+
return data;
|
|
395
|
+
}else{
|
|
396
|
+
throw data.message || data.ErrorMessage || data.error || data;
|
|
397
|
+
}
|
|
398
|
+
}catch(e){
|
|
399
|
+
console.error("send sms",e);
|
|
400
|
+
throw e.message || e.ErrorMessage || e;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
//openapi key dùng để kết nối với chatgpt
|
|
405
|
+
exports.openapi_key = "";
|
|
406
|
+
|
|
407
|
+
//google key để đọc file google document và các dịch vụ khác của google
|
|
408
|
+
exports.google_credentials = {
|
|
409
|
+
|
|
410
|
+
}
|
|
411
|
+
//Cấu hình đăng nhập bằng google nếu cần
|
|
412
|
+
exports.google = {
|
|
413
|
+
clientID: '',
|
|
414
|
+
clientSecret: '',
|
|
415
|
+
callbackURL: exports.domain + '/auth/google/callback',
|
|
416
|
+
scope: ['profile', 'email', 'https://www.googleapis.com/auth/drive']
|
|
417
|
+
};
|
|
418
|
+
//Cấu hình đăng nhập bằng facebook nếu cần
|
|
419
|
+
exports.facebook = {
|
|
420
|
+
clientID: '',
|
|
421
|
+
clientSecret: '',
|
|
422
|
+
callbackURL: exports.domain + '/auth/facebook/callback',
|
|
423
|
+
scope: ['email']
|
|
424
|
+
};
|
|
425
|
+
//Cấu hình database
|
|
426
|
+
exports.database = {
|
|
427
|
+
url: 'mongodb://127.0.0.1/flexbiz'
|
|
428
|
+
};
|
|
429
|
+
EOF_CONFIGSJS
|
|
430
|
+
|
|
431
|
+
echo "Cập nhật scripts trong package.json..."
|
|
432
|
+
# Cài đặt jq nếu chưa có
|
|
433
|
+
if ! command -v jq &> /dev/null; then
|
|
434
|
+
echo "Cài đặt jq để chỉnh sửa package.json..."
|
|
435
|
+
sudo yum install -y jq
|
|
436
|
+
fi
|
|
437
|
+
|
|
438
|
+
# Cập nhật script "build"
|
|
439
|
+
jq '.scripts.build = "babel src -d dist"' package.json > temp.json && mv temp.json package.json
|
|
440
|
+
# Cập nhật script "start" để chạy code đã biên dịch
|
|
441
|
+
jq '.scripts.start = "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=2000 node dist/index.js"' package.json > temp.json && mv temp.json package.json
|
|
442
|
+
# Cập nhật script "dev" để chạy với babel-node (cho phát triển)
|
|
443
|
+
jq '.scripts.dev = "NODE_OPTIONS=--max-old-space-size=2000 babel-node src/index.js"' package.json > temp.json && mv temp.json package.json
|
|
444
|
+
|
|
445
|
+
# Xóa script "test" mặc định nếu nó còn là "echo \"Error: no test specified\" && exit 1"
|
|
446
|
+
if grep -q '"test": "echo \\"Error: no test specified\\" && exit 1"' package.json; then
|
|
447
|
+
jq 'del(.scripts.test)' package.json > temp.json && mv temp.json package.json
|
|
448
|
+
fi
|
|
449
|
+
|
|
450
|
+
echo "Dự án Node.js '$PROJECT_NAME' đã được tạo và các dependencies đã được cài đặt tại $PROJECT_PATH."
|
|
451
|
+
echo "Để biên dịch code, chạy: npm run build"
|
|
452
|
+
echo "Để chạy code đã biên dịch (production), chạy: npm start"
|
|
453
|
+
echo "Để chạy code trực tiếp với Babel (development), chạy: npm run dev"
|
|
454
|
+
echo "QUAN TRỌNG: Hãy chỉnh sửa file $PROJECT_PATH/src/configs.js với cấu hình thực tế của bạn."
|
|
455
|
+
fi
|
|
456
|
+
|
|
189
457
|
echo ""
|
|
190
458
|
echo "========================================"
|
|
191
459
|
echo "Tất cả phần mềm và cấu hình đã được cài đặt thành công!"
|
|
460
|
+
echo "Dự án Node.js của bạn được tạo tại: $PROJECT_PATH"
|
|
461
|
+
echo "Để chạy dự án, hãy chuyển đến thư mục $PROJECT_PATH và chạy: npm start"
|
|
192
462
|
echo "Kiểm tra trạng thái:"
|
|
193
463
|
echo "MongoDB: systemctl status mongod"
|
|
194
464
|
echo "Redis: systemctl status redis"
|
|
@@ -200,7 +470,7 @@ echo "SELinux httpd_can_network_connect: getsebool httpd_can_network_connect"
|
|
|
200
470
|
echo "Redis: redis-cli config get stop-writes-on-bgsave-error"
|
|
201
471
|
echo "Redis: redis-cli config get dir"
|
|
202
472
|
echo "Redis: redis-cli config get dbfilename"
|
|
203
|
-
echo "Redis: redis-cli config get appendonly"
|
|
204
473
|
echo "Redis: redis-cli config get save"
|
|
474
|
+
echo "Redis: redis-cli config get appendonly"
|
|
205
475
|
echo "MongoDB LimitNOFILE: systemctl show mongod | grep LimitNOFILE"
|
|
206
476
|
echo "========================================"
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "flexbiz-server",
|
|
3
3
|
"main": "./server/app.js",
|
|
4
4
|
"description": "Flexible Server",
|
|
5
|
-
"version": "12.3.
|
|
5
|
+
"version": "12.3.32",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Van Truong Pham",
|
|
8
8
|
"email": "invncur@gmail.com"
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"google-auth-library": "^9.15.1",
|
|
42
42
|
"google-translate": "^3.0.0",
|
|
43
43
|
"googleapis": "^144.0.0",
|
|
44
|
+
"imapflow": "^1.1.0",
|
|
44
45
|
"jsonwebtoken": "^8.5.1",
|
|
45
46
|
"jspdf": "^2.1.1",
|
|
46
47
|
"jszip": "^3.1.5",
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"moment-timezone": "^0.5.33",
|
|
53
54
|
"mongodb-backup": "^1.6.9",
|
|
54
55
|
"mongodb-restore": "^1.6.2",
|
|
55
|
-
"mongoose": "^
|
|
56
|
+
"mongoose": "^8.17.1",
|
|
56
57
|
"morgan": "^1.10.0",
|
|
57
58
|
"multer": "^0.1.8",
|
|
58
59
|
"natives": "^1.1.6",
|
package/server/app.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
'use strict';require("events").EventEmitter.defaultMaxListeners=1E7;
|
|
2
2
|
const os=require("os"),express=require("express"),bodyParser=require("body-parser"),passport=require("passport"),https=require("https"),http=require("http"),fs=require("fs"),cors=require("cors"),_global=require("./global"),defaultConfigs=require("./defaultConfigs"),crypto=require("crypto"),mainServer=function($app$$,$options$$={cluster:!0,port:443,useSocket:!0},$callbackServer$$=null){const $configs$$=global.configs={...defaultConfigs,...$options$$.configs,lite:$options$$.lite},$User$$=global.getModel("user");
|
|
3
|
-
$configs$$.admins||($configs$$.admins=$configs$$.adminUsers.map($u$$=>$u$$.email));$configs$$.supportUsers||($configs$$.supportUsers=[...$configs$$.admins]);$configs$$.public_token||($configs$$.public_token="flex.public.token");
|
|
4
|
-
$app$$.use(function($req$$,$res$$,$next$$){$toobusy$$()?(console.error("Server is busy right now. This request has been cancel:",$req$$.originalUrl),$res$$.status(503).send({error:"Server is busy right now, sorry."})):$next$$()})
|
|
5
|
-
require("cookie-parser");$app$$.use($
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
require("rotating-file-stream");const $logDirectory$$=$configs$$.paths.log||__dirname+"/log";fs.existsSync($logDirectory$$)||fs.mkdirSync($logDirectory$$);$accessLogStream_rfs
|
|
10
|
-
$res$$.status(500).send("Server Error!")});global.mongoose.connect($configs$$.database.url,{useNewUrlParser:!0}).then(async()=>{console.log("Connected to Database");
|
|
3
|
+
$configs$$.admins||($configs$$.admins=$configs$$.adminUsers.map($u$$=>$u$$.email));$configs$$.supportUsers||($configs$$.supportUsers=[...$configs$$.admins]);$configs$$.public_token||($configs$$.public_token="flex.public.token");var $_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=$options$$.port||$configs$$.port||$configs$$.PORT||443;$configs$$.port=$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$;global.port=$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$;
|
|
4
|
+
require("moment-timezone").tz.setDefault($configs$$.timezone||"Asia/Ho_Chi_Minh");$app$$||($app$$=express());$app$$.set("trust proxy",1);const $toobusy$$=require("toobusy-js");$configs$$.maxLag&&$toobusy$$.maxLag($configs$$.maxLag);$app$$.use(function($req$$,$res$$,$next$$){$toobusy$$()?(console.error("Server is busy right now. This request has been cancel:",$req$$.originalUrl),$res$$.status(503).send({error:"Server is busy right now, sorry."})):$next$$()});$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=
|
|
5
|
+
require("express-session");$app$$.use($_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$({secret:"QV098PVT123456HLBN",resave:!1,saveUninitialized:!0,cookie:{secure:!1}}));$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=require("cookie-parser");$app$$.use($_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$());$app$$.use(function($req$$,$res$$,$next$$){let $uid$$=$req$$.cookies.uid;$uid$$||($uid$$=$req$$.headers.uid);$uid$$||($uid$$="uid:"+
|
|
6
|
+
crypto.randomBytes(20).toString("hex"),$res$$.cookie("uid",$uid$$,{expires:new Date(Date.now()+31536E6),sameSite:"none",secure:!0}));$res$$.set("uid",$uid$$);$req$$.cookies.uid=$uid$$;$next$$()});$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=require("compression");$app$$.use($_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$());$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=$configs$$.paths.uploads||__dirname+"/uploads";const $limitFileSize$$=
|
|
7
|
+
$configs$$.limitFileSize||1048576;$app$$.use(function($req$jscomp$2_size$$,$res$$,$next$$){if(($req$jscomp$2_size$$=$req$jscomp$2_size$$.headers["content-lenght"])&&$req$jscomp$2_size$$>$limitFileSize$$)return $res$$.status(400).send({error:"File too large"});$next$$()});$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=require("multer")({dest:$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$,limits:{files:1,fileSize:$limitFileSize$$}});$app$$.use($_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$);
|
|
8
|
+
$app$$.use(cors({credentials:!0,exposedHeaders:["set-cookie","uid"],origin:($origin$$,$callback$$)=>{$callback$$(null,!0)}}));$configs$$.paths||($configs$$.paths={});!0!==$options$$.lite&&($app$$.use("/",express.static($configs$$.paths.public||__dirname+"/public")),$app$$.use("/admin",express.static($configs$$.paths.admin||__dirname+"/admin")),$app$$.use("/templates",express.static($configs$$.paths.templates||__dirname+"/templates")),$app$$.use("/images",express.static($configs$$.paths.images||__dirname+
|
|
9
|
+
"/images")));$app$$.use(bodyParser.json({limit:$configs$$.limitRequestSize||"1mb"}));$app$$.use(bodyParser.urlencoded({limit:$configs$$.limitRequestSize||"1mb",extended:!0}));$app$$.use(passport.initialize());$_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$=require("morgan");var $accessLogStream_rfs$$=require("rotating-file-stream");const $logDirectory$$=$configs$$.paths.log||__dirname+"/log";fs.existsSync($logDirectory$$)||fs.mkdirSync($logDirectory$$);$accessLogStream_rfs$$=
|
|
10
|
+
$accessLogStream_rfs$$("access.log",{interval:"1d",path:$logDirectory$$});$app$$.use($_port_compress_cookieParser_morgan_multer_root_dir_uploads_session$$("combined",{stream:$accessLogStream_rfs$$,skip:function($req$$,$res$$){return 400>$res$$.statusCode}}));$app$$.use(function($err$$,$req$$,$res$$,$next$$){console.error($err$$.stack);$res$$.status(500).send("Server Error!")});global.mongoose.connect($configs$$.database.url,{useNewUrlParser:!0}).then(async()=>{console.log("[app] Connected to Database");
|
|
11
|
+
const $redis$$=require("redis"),{retryStrategyRedis:$retryStrategyRedis$$}=require("./libs/utils");global.clientRedis=$redis$$.createClient({host:"127.0.0.1",port:6379,retry_strategy:$retryStrategyRedis$$});global.clientRedis.on("error",$err$$=>console.error("Redis Client Error",$err$$));global.clientRedis.on("end",()=>{console.error("[app] Redis connection closed.")});global.clientRedis.on("connect",function(){console.log("[app] redis connected");$User$$.initClientSockets();0!=$options$$.createRedisCache&&
|
|
11
12
|
require("./libs/redis-cache").set();$options$$.start_abci_handler&&global.getModel("assabcihandler").start();!0!==$options$$.lite?require("./route")($app$$,()=>{if(!1!==$options$$.createServer){var $StaticPool$jscomp$0$$=require("sticky-session");$configs$$.use_ssl?($cpus_report_cpus_server_sslConfig$$=require("./sslConfig"),$cpus_report_cpus_server_sslConfig$$=https.createServer($cpus_report_cpus_server_sslConfig$$($options$$.sslDir),$app$$)):$cpus_report_cpus_server_sslConfig$$=http.createServer($app$$);
|
|
12
|
-
$cpus_report_cpus_server_sslConfig$$.timeout=6E5;!1!==$options$$.useSocket
|
|
13
|
-
$worker$$.process.pid+" died",$code$$,$signal$$)});$StaticPool$jscomp$0$$.on("online",function($worker$$){console.info("worker "+$worker$$.process.pid+" is online")})}else $cpus_report_cpus_server_sslConfig$$.listen(global.port,()=>{console.log("server start at "+global.port+" port")})}var $cpus_report_cpus_server_sslConfig$$=os.cpus().length;$StaticPool$jscomp$0$$=$options$$.import_cpus||($options$$.start_import_data_pool?$options$$.start_report_pool||$options$$.start_input_data_pool?
|
|
14
|
-
2):0);var $StaticPool$jscomp$1$$=$options$$.input_cpus||($options$$.start_input_data_pool?Math.max(Math.round($cpus_report_cpus_server_sslConfig$$/2),2):0);$cpus_report_cpus_server_sslConfig$$=$options$$.report_cpus||($options$$.start_import_data_pool?Math.max(Math.min($cpus_report_cpus_server_sslConfig$$-$StaticPool$jscomp$1$$-$StaticPool$jscomp$0$$,Math.round($cpus_report_cpus_server_sslConfig$$/2))-1,2):0);if($StaticPool$jscomp$1$$){const $StaticPool$$=
|
|
15
|
-
new $StaticPool$$(__dirname+"/workers/inputWorker.js",$options$$.max_queue_imports||0,$StaticPool$jscomp$1$$,3E5,$StaticPool$jscomp$1$$,"input pool");global.inputMainPool.exec({load:!0,configs:JSON.stringify($configs$$)},()=>{console.
|
|
16
|
-
global.importDataMainPool.exec({load:!0,configs:JSON.stringify($configs$$)},()=>{console.
|
|
17
|
-
|
|
13
|
+
$cpus_report_cpus_server_sslConfig$$.timeout=6E5;!1!==$options$$.useSocket&&$User$$.initSocket($cpus_report_cpus_server_sslConfig$$);if(!1!==$options$$.cluster){if(!$StaticPool$jscomp$0$$.listen($cpus_report_cpus_server_sslConfig$$,global.port))$cpus_report_cpus_server_sslConfig$$.once("listening",function(){console.log("[app] server started on",global.port)});$StaticPool$jscomp$0$$=require("cluster");$StaticPool$jscomp$0$$.on("exit",function($worker$$,$code$$,$signal$$){console.error("[app] worker "+
|
|
14
|
+
$worker$$.process.pid+" died",$code$$,$signal$$)});$StaticPool$jscomp$0$$.on("online",function($worker$$){console.info("[app] worker "+$worker$$.process.pid+" is online")})}else $cpus_report_cpus_server_sslConfig$$.listen(global.port,()=>{console.log("[app] server start at "+global.port+" port")})}var $cpus_report_cpus_server_sslConfig$$=os.cpus().length;$StaticPool$jscomp$0$$=$options$$.import_cpus||($options$$.start_import_data_pool?$options$$.start_report_pool||$options$$.start_input_data_pool?
|
|
15
|
+
1:Math.round($cpus_report_cpus_server_sslConfig$$/2):0);var $StaticPool$jscomp$1$$=$options$$.input_cpus||($options$$.start_input_data_pool?Math.max(Math.round($cpus_report_cpus_server_sslConfig$$/2),2):0);$cpus_report_cpus_server_sslConfig$$=$options$$.report_cpus||($options$$.start_import_data_pool?Math.max(Math.min($cpus_report_cpus_server_sslConfig$$-$StaticPool$jscomp$1$$-$StaticPool$jscomp$0$$,Math.round($cpus_report_cpus_server_sslConfig$$/2))-1,2):0);if($StaticPool$jscomp$1$$){const $StaticPool$$=
|
|
16
|
+
require("./libs/WorkerStaticPool");global.inputMainPool=new $StaticPool$$(__dirname+"/workers/inputWorker.js",$options$$.max_queue_imports||0,$StaticPool$jscomp$1$$,3E5,$StaticPool$jscomp$1$$,"input pool");global.inputMainPool.exec({load:!0,configs:JSON.stringify($configs$$)},()=>{console.log("[app] Crud pool ready")})}$StaticPool$jscomp$0$$&&($StaticPool$jscomp$1$$=require("./libs/WorkerStaticPool"),global.importDataMainPool=new $StaticPool$jscomp$1$$(__dirname+"/workers/inputWorker.js",$options$$.max_queue_imports||
|
|
17
|
+
0,$StaticPool$jscomp$0$$,36E5,1,"import pool"),global.importDataMainPool.exec({load:!0,configs:JSON.stringify($configs$$)},()=>{console.log("[app] Import pool ready")}));$cpus_report_cpus_server_sslConfig$$&&($StaticPool$jscomp$0$$=require("./libs/WorkerStaticPool"),global.reportMainPool=new $StaticPool$jscomp$0$$(__dirname+"/workers/reportWorker.js",$options$$.max_queue_reports||0,$cpus_report_cpus_server_sslConfig$$,3E5,2,"report pool"),global.reportMainPool.exec({load:!0,configs:JSON.stringify($configs$$)},
|
|
18
|
+
()=>{console.log("[app] Report pool ready")}));$callbackServer$$&&$callbackServer$$()}):require("./route")($app$$,()=>{$callbackServer$$&&$callbackServer$$()},!0)})}).catch($err$$=>{console.log("[app] Not Connected to Database ERROR! ",$err$$)});return $app$$};process.on("SIGINT",async()=>{global.sharedRedisConnection&&await global.sharedRedisConnection.quit();process.exit(0)});
|
|
18
19
|
process.on("uncaughtException",function($err$jscomp$3_error$$){console.error((new Date).toUTCString()+" uncaughtException:",$err$jscomp$3_error$$.message);console.error($err$jscomp$3_error$$.stack);$err$jscomp$3_error$$=`
|
|
19
20
|
Error: ${$err$jscomp$3_error$$.message}
|
|
20
21
|
Stack: ${$err$jscomp$3_error$$.stack}
|
|
21
|
-
`;try{const $logDirectory$$=__dirname+"/log";fs.existsSync($logDirectory$$)||fs.mkdirSync($logDirectory$$);fs.writeFile(`${$logDirectory$$}/error-${(new Date).getTime()}.txt`,$err$jscomp$3_error$$,()=>{console.log("wrote log error")})}catch($e$$){console.log($e$$)}process.exit(1)});module.exports=mainServer;
|
|
22
|
+
`;try{const $logDirectory$$=__dirname+"/log";fs.existsSync($logDirectory$$)||fs.mkdirSync($logDirectory$$);fs.writeFile(`${$logDirectory$$}/error-${(new Date).getTime()}.txt`,$err$jscomp$3_error$$,()=>{console.log("[app] wrote log error")})}catch($e$$){console.log($e$$)}process.exit(1)});module.exports=mainServer;
|