@lobehub/chat 1.20.1 → 1.20.2
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/CHANGELOG.md +25 -0
- package/Dockerfile +49 -36
- package/Dockerfile.database +53 -36
- package/package.json +1 -1
- package/src/config/modelProviders/siliconcloud.ts +21 -21
- package/src/config/modelProviders/zhipu.ts +14 -1
- package/scripts/serverLauncher/startServer.js +0 -181
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.20.2](https://github.com/lobehub/lobe-chat/compare/v1.20.1...v1.20.2)
|
6
|
+
|
7
|
+
<sup>Released on **2024-09-27**</sup>
|
8
|
+
|
9
|
+
#### 💄 Styles
|
10
|
+
|
11
|
+
- **misc**: Add zhipu glm-4-flashx model.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Styles
|
19
|
+
|
20
|
+
- **misc**: Add zhipu glm-4-flashx model, closes [#4173](https://github.com/lobehub/lobe-chat/issues/4173) ([b0c3abc](https://github.com/lobehub/lobe-chat/commit/b0c3abc))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
5
30
|
### [Version 1.20.1](https://github.com/lobehub/lobe-chat/compare/v1.20.0...v1.20.1)
|
6
31
|
|
7
32
|
<sup>Released on **2024-09-27**</sup>
|
package/Dockerfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## Base image for all
|
1
|
+
## Base image for all the stages
|
2
2
|
FROM node:20-slim AS base
|
3
3
|
|
4
4
|
ARG USE_CN_MIRROR
|
@@ -10,22 +10,19 @@ RUN \
|
|
10
10
|
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
|
11
11
|
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
|
12
12
|
fi \
|
13
|
-
# Add required package
|
13
|
+
# Add required package & update base package
|
14
14
|
&& apt update \
|
15
|
-
&& apt install
|
16
|
-
|
17
|
-
&&
|
18
|
-
|
19
|
-
|
20
|
-
&&
|
21
|
-
|
22
|
-
&&
|
23
|
-
|
24
|
-
|
25
|
-
&&
|
26
|
-
&& cp /usr/local/bin/node /distroless/bin/node \
|
27
|
-
# Copy CA certificates to distroless
|
28
|
-
&& cp /etc/ssl/certs/ca-certificates.crt /distroless/etc/ssl/certs/ca-certificates.crt \
|
15
|
+
&& apt install busybox proxychains-ng -qy \
|
16
|
+
&& apt full-upgrade -qy \
|
17
|
+
&& apt autoremove -qy --purge \
|
18
|
+
&& apt clean -qy \
|
19
|
+
# Configure BusyBox
|
20
|
+
&& busybox --install -s \
|
21
|
+
# Add nextjs:nodejs to run the app
|
22
|
+
&& addgroup --system --gid 1001 nodejs \
|
23
|
+
&& adduser --system --home "/app" --gid 1001 -uid 1001 nextjs \
|
24
|
+
# Set permission for nextjs:nodejs
|
25
|
+
&& chown -R nextjs:nodejs "/etc/proxychains4.conf" \
|
29
26
|
# Cleanup temp files
|
30
27
|
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
31
28
|
|
@@ -83,9 +80,7 @@ COPY . .
|
|
83
80
|
RUN npm run build:docker
|
84
81
|
|
85
82
|
## Application image, copy all the files for production
|
86
|
-
FROM
|
87
|
-
|
88
|
-
COPY --from=base /distroless/ /
|
83
|
+
FROM scratch AS app
|
89
84
|
|
90
85
|
COPY --from=builder /app/public /app/public
|
91
86
|
|
@@ -95,25 +90,13 @@ COPY --from=builder /app/.next/standalone /app/
|
|
95
90
|
COPY --from=builder /app/.next/static /app/.next/static
|
96
91
|
COPY --from=builder /deps/node_modules/.pnpm /app/node_modules/.pnpm
|
97
92
|
|
98
|
-
# Copy server launcher
|
99
|
-
COPY --from=builder /app/scripts/serverLauncher/startServer.js /app/startServer.js
|
100
|
-
|
101
|
-
RUN \
|
102
|
-
# Add nextjs:nodejs to run the app
|
103
|
-
addgroup -S -g 1001 nodejs \
|
104
|
-
&& adduser -D -G nodejs -H -S -h /app -u 1001 nextjs \
|
105
|
-
# Set permission for nextjs:nodejs
|
106
|
-
&& chown -R nextjs:nodejs /app /etc/proxychains4.conf
|
107
|
-
|
108
93
|
## Production image, copy all the files and run next
|
109
|
-
FROM
|
94
|
+
FROM base
|
110
95
|
|
111
96
|
# Copy all the files from app, set the correct permission for prerender cache
|
112
|
-
COPY --from=app / /
|
97
|
+
COPY --from=app --chown=nextjs:nodejs /app /app
|
113
98
|
|
114
99
|
ENV NODE_ENV="production" \
|
115
|
-
NODE_OPTIONS="--use-openssl-ca" \
|
116
|
-
NODE_EXTRA_CA_CERTS="/etc/ssl/certs/ca-certificates.crt"
|
117
100
|
NODE_TLS_REJECT_UNAUTHORIZED=""
|
118
101
|
|
119
102
|
# set hostname to localhost
|
@@ -193,6 +176,36 @@ USER nextjs
|
|
193
176
|
|
194
177
|
EXPOSE 3210/tcp
|
195
178
|
|
196
|
-
|
197
|
-
|
198
|
-
|
179
|
+
CMD \
|
180
|
+
if [ -n "$PROXY_URL" ]; then \
|
181
|
+
# Set regex for IPv4
|
182
|
+
IP_REGEX="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$"; \
|
183
|
+
# Set proxychains command
|
184
|
+
PROXYCHAINS="proxychains -q"; \
|
185
|
+
# Parse the proxy URL
|
186
|
+
host_with_port="${PROXY_URL#*//}"; \
|
187
|
+
host="${host_with_port%%:*}"; \
|
188
|
+
port="${PROXY_URL##*:}"; \
|
189
|
+
protocol="${PROXY_URL%%://*}"; \
|
190
|
+
# Resolve to IP address if the host is a domain
|
191
|
+
if ! [[ "$host" =~ "$IP_REGEX" ]]; then \
|
192
|
+
nslookup=$(nslookup -q="A" "$host" | tail -n +3 | grep 'Address:'); \
|
193
|
+
if [ -n "$nslookup" ]; then \
|
194
|
+
host=$(echo "$nslookup" | tail -n 1 | awk '{print $2}'); \
|
195
|
+
fi; \
|
196
|
+
fi; \
|
197
|
+
# Generate proxychains configuration file
|
198
|
+
printf "%s\n" \
|
199
|
+
'localnet 127.0.0.0/255.0.0.0' \
|
200
|
+
'localnet ::1/128' \
|
201
|
+
'proxy_dns' \
|
202
|
+
'remote_dns_subnet 224' \
|
203
|
+
'strict_chain' \
|
204
|
+
'tcp_connect_time_out 8000' \
|
205
|
+
'tcp_read_time_out 15000' \
|
206
|
+
'[ProxyList]' \
|
207
|
+
"$protocol $host $port" \
|
208
|
+
> "/etc/proxychains4.conf"; \
|
209
|
+
fi; \
|
210
|
+
# Run the server
|
211
|
+
${PROXYCHAINS} node "/app/server.js";
|
package/Dockerfile.database
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## Base image for all
|
1
|
+
## Base image for all the stages
|
2
2
|
FROM node:20-slim AS base
|
3
3
|
|
4
4
|
ARG USE_CN_MIRROR
|
@@ -10,22 +10,19 @@ RUN \
|
|
10
10
|
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
|
11
11
|
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
|
12
12
|
fi \
|
13
|
-
# Add required package
|
13
|
+
# Add required package & update base package
|
14
14
|
&& apt update \
|
15
|
-
&& apt install
|
16
|
-
|
17
|
-
&&
|
18
|
-
|
19
|
-
|
20
|
-
&&
|
21
|
-
|
22
|
-
&&
|
23
|
-
|
24
|
-
|
25
|
-
&&
|
26
|
-
&& cp /usr/local/bin/node /distroless/bin/node \
|
27
|
-
# Copy CA certificates to distroless
|
28
|
-
&& cp /etc/ssl/certs/ca-certificates.crt /distroless/etc/ssl/certs/ca-certificates.crt \
|
15
|
+
&& apt install busybox proxychains-ng -qy \
|
16
|
+
&& apt full-upgrade -qy \
|
17
|
+
&& apt autoremove -qy --purge \
|
18
|
+
&& apt clean -qy \
|
19
|
+
# Configure BusyBox
|
20
|
+
&& busybox --install -s \
|
21
|
+
# Add nextjs:nodejs to run the app
|
22
|
+
&& addgroup --system --gid 1001 nodejs \
|
23
|
+
&& adduser --system --home "/app" --gid 1001 -uid 1001 nextjs \
|
24
|
+
# Set permission for nextjs:nodejs
|
25
|
+
&& chown -R nextjs:nodejs "/etc/proxychains4.conf" \
|
29
26
|
# Cleanup temp files
|
30
27
|
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
31
28
|
|
@@ -87,9 +84,7 @@ COPY . .
|
|
87
84
|
RUN npm run build:docker
|
88
85
|
|
89
86
|
## Application image, copy all the files for production
|
90
|
-
FROM
|
91
|
-
|
92
|
-
COPY --from=base /distroless/ /
|
87
|
+
FROM scratch AS app
|
93
88
|
|
94
89
|
COPY --from=builder /app/public /app/public
|
95
90
|
|
@@ -108,25 +103,13 @@ COPY --from=builder /app/src/database/server/migrations /app/migrations
|
|
108
103
|
COPY --from=builder /app/scripts/migrateServerDB/docker.cjs /app/docker.cjs
|
109
104
|
COPY --from=builder /app/scripts/migrateServerDB/errorHint.js /app/errorHint.js
|
110
105
|
|
111
|
-
# Copy server launcher
|
112
|
-
COPY --from=builder /app/scripts/serverLauncher/startServer.js /app/startServer.js
|
113
|
-
|
114
|
-
RUN \
|
115
|
-
# Add nextjs:nodejs to run the app
|
116
|
-
addgroup -S -g 1001 nodejs \
|
117
|
-
&& adduser -D -G nodejs -H -S -h /app -u 1001 nextjs \
|
118
|
-
# Set permission for nextjs:nodejs
|
119
|
-
&& chown -R nextjs:nodejs /app /etc/proxychains4.conf
|
120
|
-
|
121
106
|
## Production image, copy all the files and run next
|
122
|
-
FROM
|
107
|
+
FROM base
|
123
108
|
|
124
109
|
# Copy all the files from app, set the correct permission for prerender cache
|
125
|
-
COPY --from=app / /
|
110
|
+
COPY --from=app --chown=nextjs:nodejs /app /app
|
126
111
|
|
127
112
|
ENV NODE_ENV="production" \
|
128
|
-
NODE_OPTIONS="--use-openssl-ca" \
|
129
|
-
NODE_EXTRA_CA_CERTS="/etc/ssl/certs/ca-certificates.crt"
|
130
113
|
NODE_TLS_REJECT_UNAUTHORIZED=""
|
131
114
|
|
132
115
|
# set hostname to localhost
|
@@ -225,6 +208,40 @@ USER nextjs
|
|
225
208
|
|
226
209
|
EXPOSE 3210/tcp
|
227
210
|
|
228
|
-
|
229
|
-
|
230
|
-
|
211
|
+
CMD \
|
212
|
+
if [ -n "$PROXY_URL" ]; then \
|
213
|
+
# Set regex for IPv4
|
214
|
+
IP_REGEX="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$"; \
|
215
|
+
# Set proxychains command
|
216
|
+
PROXYCHAINS="proxychains -q"; \
|
217
|
+
# Parse the proxy URL
|
218
|
+
host_with_port="${PROXY_URL#*//}"; \
|
219
|
+
host="${host_with_port%%:*}"; \
|
220
|
+
port="${PROXY_URL##*:}"; \
|
221
|
+
protocol="${PROXY_URL%%://*}"; \
|
222
|
+
# Resolve to IP address if the host is a domain
|
223
|
+
if ! [[ "$host" =~ "$IP_REGEX" ]]; then \
|
224
|
+
nslookup=$(nslookup -q="A" "$host" | tail -n +3 | grep 'Address:'); \
|
225
|
+
if [ -n "$nslookup" ]; then \
|
226
|
+
host=$(echo "$nslookup" | tail -n 1 | awk '{print $2}'); \
|
227
|
+
fi; \
|
228
|
+
fi; \
|
229
|
+
# Generate proxychains configuration file
|
230
|
+
printf "%s\n" \
|
231
|
+
'localnet 127.0.0.0/255.0.0.0' \
|
232
|
+
'localnet ::1/128' \
|
233
|
+
'proxy_dns' \
|
234
|
+
'remote_dns_subnet 224' \
|
235
|
+
'strict_chain' \
|
236
|
+
'tcp_connect_time_out 8000' \
|
237
|
+
'tcp_read_time_out 15000' \
|
238
|
+
'[ProxyList]' \
|
239
|
+
"$protocol $host $port" \
|
240
|
+
> "/etc/proxychains4.conf"; \
|
241
|
+
fi; \
|
242
|
+
# Run migration
|
243
|
+
node "/app/docker.cjs"; \
|
244
|
+
if [ "$?" -eq "0" ]; then \
|
245
|
+
# Run the server
|
246
|
+
${PROXYCHAINS} node "/app/server.js"; \
|
247
|
+
fi;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.20.
|
3
|
+
"version": "1.20.2",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -86,26 +86,26 @@ const SiliconCloud: ModelProviderCard = {
|
|
86
86
|
tokens: 32_768,
|
87
87
|
},
|
88
88
|
{
|
89
|
-
description: '
|
90
|
-
displayName: '
|
91
|
-
id: '
|
89
|
+
description: 'InternLM2.5 提供多场景下的智能对话解决方案。',
|
90
|
+
displayName: 'Internlm 2.5 7B',
|
91
|
+
id: 'internlm/internlm2_5-7b-chat',
|
92
92
|
pricing: {
|
93
93
|
currency: 'CNY',
|
94
94
|
input: 0,
|
95
95
|
output: 0,
|
96
96
|
},
|
97
|
-
tokens:
|
97
|
+
tokens: 32_768,
|
98
98
|
},
|
99
99
|
{
|
100
|
-
description: '
|
101
|
-
displayName: '
|
102
|
-
id: '
|
100
|
+
description: '创新的开源模型InternLM2.5,通过大规模的参数提高了对话智能。',
|
101
|
+
displayName: 'Internlm 2.5 20B',
|
102
|
+
id: 'internlm/internlm2_5-20b-chat',
|
103
103
|
pricing: {
|
104
104
|
currency: 'CNY',
|
105
|
-
input: 1
|
106
|
-
output: 1
|
105
|
+
input: 1,
|
106
|
+
output: 1,
|
107
107
|
},
|
108
|
-
tokens:
|
108
|
+
tokens: 32_768,
|
109
109
|
},
|
110
110
|
{
|
111
111
|
description: 'GLM-4 9B 开放源码版本,为会话应用提供优化后的对话体验。',
|
@@ -119,26 +119,26 @@ const SiliconCloud: ModelProviderCard = {
|
|
119
119
|
tokens: 32_768,
|
120
120
|
},
|
121
121
|
{
|
122
|
-
description: '
|
123
|
-
displayName: '
|
124
|
-
id: '
|
122
|
+
description: 'Yi-1.5 9B 支持16K Tokens, 提供高效、流畅的语言生成能力。',
|
123
|
+
displayName: 'Yi-1.5 9B',
|
124
|
+
id: '01-ai/Yi-1.5-9B-Chat-16K',
|
125
125
|
pricing: {
|
126
126
|
currency: 'CNY',
|
127
127
|
input: 0,
|
128
128
|
output: 0,
|
129
129
|
},
|
130
|
-
tokens:
|
130
|
+
tokens: 16_384,
|
131
131
|
},
|
132
132
|
{
|
133
|
-
description: '
|
134
|
-
displayName: '
|
135
|
-
id: '
|
133
|
+
description: 'Yi-1.5 34B, 以丰富的训练样本在行业应用中提供优越表现。',
|
134
|
+
displayName: 'Yi-1.5 34B',
|
135
|
+
id: '01-ai/Yi-1.5-34B-Chat-16K',
|
136
136
|
pricing: {
|
137
137
|
currency: 'CNY',
|
138
|
-
input: 1,
|
139
|
-
output: 1,
|
138
|
+
input: 1.26,
|
139
|
+
output: 1.26,
|
140
140
|
},
|
141
|
-
tokens:
|
141
|
+
tokens: 16_384,
|
142
142
|
},
|
143
143
|
{
|
144
144
|
description: 'Gemma 2 是Google轻量化的开源文本模型系列。',
|
@@ -201,7 +201,7 @@ const SiliconCloud: ModelProviderCard = {
|
|
201
201
|
tokens: 32_768,
|
202
202
|
},
|
203
203
|
],
|
204
|
-
checkModel: 'Qwen/Qwen2
|
204
|
+
checkModel: 'Qwen/Qwen2.5-7B-Instruct',
|
205
205
|
description: 'SiliconCloud,基于优秀开源基础模型的高性价比 GenAI 云服务',
|
206
206
|
id: 'siliconcloud',
|
207
207
|
modelList: { showModelFetcher: true },
|
@@ -97,7 +97,20 @@ const ZhiPu: ModelProviderCard = {
|
|
97
97
|
tokens: 1_024_000,
|
98
98
|
},
|
99
99
|
{
|
100
|
-
description: 'GLM-4-Flash
|
100
|
+
description: 'GLM-4-FlashX 是Flash的增强版本,超快推理速度。',
|
101
|
+
displayName: 'GLM-4-FlashX',
|
102
|
+
enabled: true,
|
103
|
+
functionCall: true,
|
104
|
+
id: 'glm-4-flashx',
|
105
|
+
pricing: {
|
106
|
+
currency: 'CNY',
|
107
|
+
input: 0.1,
|
108
|
+
output: 0.1,
|
109
|
+
},
|
110
|
+
tokens: 128_000,
|
111
|
+
},
|
112
|
+
{
|
113
|
+
description: 'GLM-4-Flash 是处理简单任务的理想选择,速度最快且免费。',
|
101
114
|
displayName: 'GLM-4-Flash',
|
102
115
|
enabled: true,
|
103
116
|
functionCall: true,
|
@@ -1,181 +0,0 @@
|
|
1
|
-
const dns = require('dns').promises;
|
2
|
-
const fs = require('fs');
|
3
|
-
const tls = require('tls');
|
4
|
-
const { spawn } = require('child_process');
|
5
|
-
|
6
|
-
// Set file paths
|
7
|
-
const DB_MIGRATION_SCRIPT_PATH = '/app/docker.cjs';
|
8
|
-
const SERVER_SCRIPT_PATH = '/app/server.js';
|
9
|
-
const PROXYCHAINS_CONF_PATH = '/etc/proxychains4.conf';
|
10
|
-
|
11
|
-
// Function to check if a string is a valid IP address
|
12
|
-
const isValidIP = (ip, version = 4) => {
|
13
|
-
const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/;
|
14
|
-
const ipv6Regex = /^(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,7}:|([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|:((:[0-9a-f]{1,4}){1,7}|:)|fe80:(:[0-9a-f]{0,4}){0,4}%[0-9a-z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-f]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
|
15
|
-
|
16
|
-
switch (version) {
|
17
|
-
case 4:
|
18
|
-
return ipv4Regex.test(ip);
|
19
|
-
case 6:
|
20
|
-
return ipv6Regex.test(ip);
|
21
|
-
default:
|
22
|
-
return ipv4Regex.test(ip) || ipv6Regex.test(ip);
|
23
|
-
}
|
24
|
-
};
|
25
|
-
|
26
|
-
// Function to check TLS validity of a URL
|
27
|
-
const isValidTLS = (url = '') => {
|
28
|
-
if (!url) {
|
29
|
-
console.log('⚠️ TLS Check: No URL provided. Skipping TLS check. Ensure correct setting ENV.');
|
30
|
-
console.log('-------------------------------------');
|
31
|
-
return Promise.resolve();
|
32
|
-
}
|
33
|
-
|
34
|
-
const { protocol, host, port } = parseUrl(url);
|
35
|
-
if (protocol !== 'https') {
|
36
|
-
console.log(`⚠️ TLS Check: Non-HTTPS protocol (${protocol}). Skipping TLS check for ${url}.`);
|
37
|
-
console.log('-------------------------------------');
|
38
|
-
return Promise.resolve();
|
39
|
-
}
|
40
|
-
|
41
|
-
const options = { host, port, servername: host };
|
42
|
-
return new Promise((resolve, reject) => {
|
43
|
-
const socket = tls.connect(options, () => {
|
44
|
-
if (socket.authorized) {
|
45
|
-
console.log(`✅ TLS Check: Valid certificate for ${host}:${port}.`);
|
46
|
-
console.log('-------------------------------------');
|
47
|
-
resolve();
|
48
|
-
}
|
49
|
-
socket.end();
|
50
|
-
});
|
51
|
-
|
52
|
-
socket.on('error', (err) => {
|
53
|
-
const errMsg = `❌ TLS Check: Error for ${host}:${port}. Details:`;
|
54
|
-
switch (err.code) {
|
55
|
-
case 'CERT_HAS_EXPIRED':
|
56
|
-
case 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
57
|
-
console.error(`${errMsg} Certificate is not valid. Consider setting NODE_TLS_REJECT_UNAUTHORIZED="0" or mapping /etc/ssl/certs/ca-certificates.crt.`);
|
58
|
-
break;
|
59
|
-
case 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY':
|
60
|
-
console.error(`${errMsg} Unable to verify issuer. Ensure correct mapping of /etc/ssl/certs/ca-certificates.crt.`);
|
61
|
-
break;
|
62
|
-
default:
|
63
|
-
console.error(`${errMsg} Network issue. Check firewall or DNS.`);
|
64
|
-
break;
|
65
|
-
}
|
66
|
-
reject(err);
|
67
|
-
});
|
68
|
-
});
|
69
|
-
};
|
70
|
-
|
71
|
-
// Function to check TLS connections for OSS and Auth Issuer
|
72
|
-
const checkTLSConnections = async () => {
|
73
|
-
await Promise.all([
|
74
|
-
isValidTLS(process.env.S3_ENDPOINT),
|
75
|
-
isValidTLS(process.env.S3_PUBLIC_DOMAIN),
|
76
|
-
isValidTLS(getEnvVarsByKeyword('_ISSUER')),
|
77
|
-
]);
|
78
|
-
};
|
79
|
-
|
80
|
-
// Function to get environment variable by keyword
|
81
|
-
const getEnvVarsByKeyword = (keyword) => {
|
82
|
-
return Object.entries(process.env)
|
83
|
-
.filter(([key, value]) => key.includes(keyword) && value)
|
84
|
-
.map(([, value]) => value)[0] || null;
|
85
|
-
};
|
86
|
-
|
87
|
-
// Function to parse protocol, host and port from a URL
|
88
|
-
const parseUrl = (url) => {
|
89
|
-
const { protocol, hostname: host, port } = new URL(url);
|
90
|
-
return { protocol: protocol.replace(':', ''), host, port: port || 443 };
|
91
|
-
};
|
92
|
-
|
93
|
-
// Function to resolve host IP via DNS
|
94
|
-
const resolveHostIP = async (host, version = 4) => {
|
95
|
-
try {
|
96
|
-
const { address } = await dns.lookup(host, { family: version });
|
97
|
-
|
98
|
-
if (!isValidIP(address, version)) {
|
99
|
-
console.error(`❌ DNS Error: Invalid resolved IP: ${address}. IP address must be IPv${version}.`);
|
100
|
-
process.exit(1);
|
101
|
-
}
|
102
|
-
|
103
|
-
return address;
|
104
|
-
} catch (err) {
|
105
|
-
console.error(`❌ DNS Error: Could not resolve ${host}. Check DNS server.`, err);
|
106
|
-
process.exit(1);
|
107
|
-
}
|
108
|
-
};
|
109
|
-
|
110
|
-
// Function to generate proxychains configuration
|
111
|
-
const runProxyChainsConfGenerator = async (url) => {
|
112
|
-
const { protocol, host, port } = parseUrl(url);
|
113
|
-
|
114
|
-
if (!['http', 'socks4', 'socks5'].includes(protocol)) {
|
115
|
-
console.error(`❌ ProxyChains: Invalid protocol (${protocol}). Protocol must be 'http', 'socks4' and 'socks5'.`);
|
116
|
-
process.exit(1);
|
117
|
-
}
|
118
|
-
|
119
|
-
const validPort = parseInt(port, 10);
|
120
|
-
if (isNaN(validPort) || validPort <= 0 || validPort > 65535) {
|
121
|
-
console.error(`❌ ProxyChains: Invalid port (${port}). Port must be a number between 1 and 65535.`);
|
122
|
-
process.exit(1);
|
123
|
-
}
|
124
|
-
|
125
|
-
let ip = isValidIP(host, 4) ? host : await resolveHostIP(host, 4);
|
126
|
-
|
127
|
-
const configContent = `
|
128
|
-
localnet 127.0.0.0/255.0.0.0
|
129
|
-
localnet ::1/128
|
130
|
-
proxy_dns
|
131
|
-
remote_dns_subnet 224
|
132
|
-
strict_chain
|
133
|
-
tcp_connect_time_out 8000
|
134
|
-
tcp_read_time_out 15000
|
135
|
-
[ProxyList]
|
136
|
-
${protocol} ${ip} ${port}
|
137
|
-
`.trim();
|
138
|
-
|
139
|
-
fs.writeFileSync(PROXYCHAINS_CONF_PATH, configContent);
|
140
|
-
console.log(`✅ ProxyChains: All outgoing traffic routed via ${protocol}://${ip}:${port}.`);
|
141
|
-
console.log('-------------------------------------');
|
142
|
-
};
|
143
|
-
|
144
|
-
// Function to execute a script with child process spawn
|
145
|
-
const runScript = (scriptPath, useProxy = false) => {
|
146
|
-
const command = useProxy ? ['/bin/proxychains', '-q', '/bin/node', scriptPath] : ['/bin/node', scriptPath];
|
147
|
-
return new Promise((resolve, reject) => {
|
148
|
-
const process = spawn(command.shift(), command, { stdio: 'inherit' });
|
149
|
-
process.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`🔴 Process exited with code ${code}`))));
|
150
|
-
});
|
151
|
-
};
|
152
|
-
|
153
|
-
// Main function to run the server with optional proxy
|
154
|
-
const runServer = async () => {
|
155
|
-
const PROXY_URL = process.env.PROXY_URL || ''; // Default empty string to avoid undefined errors
|
156
|
-
|
157
|
-
if (PROXY_URL) {
|
158
|
-
await runProxyChainsConfGenerator(PROXY_URL);
|
159
|
-
return runScript(SERVER_SCRIPT_PATH, true);
|
160
|
-
}
|
161
|
-
return runScript(SERVER_SCRIPT_PATH);
|
162
|
-
};
|
163
|
-
|
164
|
-
// Main execution block
|
165
|
-
(async () => {
|
166
|
-
console.log('🌐 DNS Server:', dns.getServers());
|
167
|
-
console.log('-------------------------------------');
|
168
|
-
|
169
|
-
if (process.env.DATABASE_DRIVER) {
|
170
|
-
try {
|
171
|
-
await runScript(DB_MIGRATION_SCRIPT_PATH);
|
172
|
-
await checkTLSConnections();
|
173
|
-
} catch (err) {
|
174
|
-
console.error('❌ Error during DB migration or TLS connection check:', err);
|
175
|
-
process.exit(1);
|
176
|
-
}
|
177
|
-
}
|
178
|
-
|
179
|
-
// Run the server in either database or non-database mode
|
180
|
-
await runServer();
|
181
|
-
})();
|