mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-01-13 09:12:44 +00:00
Merge branch 'main' into usrlocal
This commit is contained in:
commit
6c192b35f4
6 changed files with 132 additions and 15 deletions
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
|
|
@ -17,7 +17,8 @@ on:
|
||||||
- '**.go'
|
- '**.go'
|
||||||
- 'go.mod'
|
- 'go.mod'
|
||||||
- 'go.sum'
|
- 'go.sum'
|
||||||
- 'x-ui.service'
|
- 'x-ui.service.debian'
|
||||||
|
- 'x-ui.service.rhel'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
@ -78,7 +79,8 @@ jobs:
|
||||||
|
|
||||||
mkdir x-ui
|
mkdir x-ui
|
||||||
cp xui-release x-ui/
|
cp xui-release x-ui/
|
||||||
cp x-ui.service x-ui/
|
cp x-ui.service.debian x-ui/
|
||||||
|
cp x-ui.service.rhel x-ui/
|
||||||
cp x-ui.sh x-ui/
|
cp x-ui.sh x-ui/
|
||||||
mv x-ui/xui-release x-ui/x-ui
|
mv x-ui/xui-release x-ui/x-ui
|
||||||
mkdir x-ui/bin
|
mkdir x-ui/bin
|
||||||
|
|
|
||||||
27
install.sh
27
install.sh
|
|
@ -647,6 +647,20 @@ install_x-ui() {
|
||||||
mkdir -p /var/log/x-ui
|
mkdir -p /var/log/x-ui
|
||||||
config_after_install
|
config_after_install
|
||||||
|
|
||||||
|
# Etckeeper compatibility
|
||||||
|
if [ -d "/etc/.git" ]; then
|
||||||
|
if [ -f "/etc/.gitignore" ]; then
|
||||||
|
if ! grep -q "x-ui/x-ui.db" "/etc/.gitignore"; then
|
||||||
|
echo "" >> "/etc/.gitignore"
|
||||||
|
echo "x-ui/x-ui.db" >> "/etc/.gitignore"
|
||||||
|
echo -e "${green}Added x-ui.db to /etc/.gitignore for etckeeper${plain}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "x-ui/x-ui.db" > "/etc/.gitignore"
|
||||||
|
echo -e "${green}Created /etc/.gitignore and added x-ui.db for etckeeper${plain}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $release == "alpine" ]]; then
|
if [[ $release == "alpine" ]]; then
|
||||||
wget --inet4-only -O /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc
|
wget --inet4-only -O /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
|
|
@ -657,7 +671,18 @@ install_x-ui() {
|
||||||
rc-update add x-ui
|
rc-update add x-ui
|
||||||
rc-service x-ui start
|
rc-service x-ui start
|
||||||
else
|
else
|
||||||
cp -f x-ui.service ${xui_service}/
|
if [ -f "x-ui.service" ]; then
|
||||||
|
cp -f x-ui.service /etc/systemd/system/
|
||||||
|
else
|
||||||
|
case "${release}" in
|
||||||
|
ubuntu | debian | armbian)
|
||||||
|
cp -f x-ui.service.debian ${xui_service}/x-ui.service
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cp -f x-ui.service.rhel ${xui_service}/x-ui.service
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable x-ui
|
systemctl enable x-ui
|
||||||
systemctl start x-ui
|
systemctl start x-ui
|
||||||
|
|
|
||||||
19
update.sh
19
update.sh
|
|
@ -616,8 +616,10 @@ update_x-ui() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo -e "${green}Removing old x-ui version...${plain}"
|
echo -e "${green}Removing old x-ui version...${plain}"
|
||||||
rm /usr/bin/x-ui -f >/dev/null 2>&1
|
rm ${xui_folder} -f >/dev/null 2>&1
|
||||||
rm ${xui_folder}/x-ui.service -f >/dev/null 2>&1
|
rm ${xui_folder}/x-ui.service -f >/dev/null 2>&1
|
||||||
|
rm ${xui_folder}/x-ui.service.debian -f >/dev/null 2>&1
|
||||||
|
rm ${xui_folder}/x-ui.service.rhel -f >/dev/null 2>&1
|
||||||
rm ${xui_folder}/x-ui -f >/dev/null 2>&1
|
rm ${xui_folder}/x-ui -f >/dev/null 2>&1
|
||||||
rm ${xui_folder}/x-ui.sh -f >/dev/null 2>&1
|
rm ${xui_folder}/x-ui.sh -f >/dev/null 2>&1
|
||||||
echo -e "${green}Removing old xray version...${plain}"
|
echo -e "${green}Removing old xray version...${plain}"
|
||||||
|
|
@ -680,8 +682,21 @@ update_x-ui() {
|
||||||
rc-update add x-ui >/dev/null 2>&1
|
rc-update add x-ui >/dev/null 2>&1
|
||||||
rc-service x-ui start >/dev/null 2>&1
|
rc-service x-ui start >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
|
if [ -f "x-ui.service" ]; then
|
||||||
echo -e "${green}Installing systemd unit...${plain}"
|
echo -e "${green}Installing systemd unit...${plain}"
|
||||||
cp -f x-ui.service ${xui_service}/ >/dev/null 2>&1
|
cp -f x-ui.service ${xui_service} >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
case "${release}" in
|
||||||
|
ubuntu | debian | armbian)
|
||||||
|
echo -e "${green}Installing debian-like systemd unit...${plain}"
|
||||||
|
cp -f x-ui.service.debian ${xui_service}/x-ui.service >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${green}Installing rhel-like systemd unit...${plain}"
|
||||||
|
cp -f x-ui.service.rhel ${xui_service}/x-ui.service >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
chown root:root ${xui_service}/x-ui.service >/dev/null 2>&1
|
chown root:root ${xui_service}/x-ui.service >/dev/null 2>&1
|
||||||
systemctl daemon-reload >/dev/null 2>&1
|
systemctl daemon-reload >/dev/null 2>&1
|
||||||
systemctl enable x-ui >/dev/null 2>&1
|
systemctl enable x-ui >/dev/null 2>&1
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,10 @@
|
||||||
oldAllSetting: new AllSetting(),
|
oldAllSetting: new AllSetting(),
|
||||||
allSetting: new AllSetting(),
|
allSetting: new AllSetting(),
|
||||||
saveBtnDisable: true,
|
saveBtnDisable: true,
|
||||||
|
entryHost: null,
|
||||||
|
entryPort: null,
|
||||||
|
entryProtocol: null,
|
||||||
|
entryIsIP: false,
|
||||||
user: {},
|
user: {},
|
||||||
lang: LanguageManager.getLanguage(),
|
lang: LanguageManager.getLanguage(),
|
||||||
inboundOptions: [],
|
inboundOptions: [],
|
||||||
|
|
@ -233,6 +237,31 @@
|
||||||
loading(spinning = true) {
|
loading(spinning = true) {
|
||||||
this.loadingStates.spinning = spinning;
|
this.loadingStates.spinning = spinning;
|
||||||
},
|
},
|
||||||
|
_isIp(h) {
|
||||||
|
if (typeof h !== "string") return false;
|
||||||
|
|
||||||
|
// IPv4: four dot-separated octets 0-255
|
||||||
|
const v4 = h.split(".");
|
||||||
|
if (
|
||||||
|
v4.length === 4 &&
|
||||||
|
v4.every(p => /^\d{1,3}$/.test(p) && Number(p) <= 255)
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
// IPv6: hex groups, optional single :: compression
|
||||||
|
if (!h.includes(":") || h.includes(":::")) return false;
|
||||||
|
const parts = h.split("::");
|
||||||
|
if (parts.length > 2) return false;
|
||||||
|
|
||||||
|
const splitGroups = s => (s ? s.split(":").filter(Boolean) : []);
|
||||||
|
const head = splitGroups(parts[0]);
|
||||||
|
const tail = splitGroups(parts[1]);
|
||||||
|
const validGroup = seg => /^[0-9a-fA-F]{1,4}$/.test(seg);
|
||||||
|
|
||||||
|
if (![...head, ...tail].every(validGroup)) return false;
|
||||||
|
const groups = head.length + tail.length;
|
||||||
|
|
||||||
|
return parts.length === 2 ? groups < 8 : groups === 8;
|
||||||
|
},
|
||||||
async getAllSetting() {
|
async getAllSetting() {
|
||||||
const msg = await HttpUtil.post("/panel/setting/all");
|
const msg = await HttpUtil.post("/panel/setting/all");
|
||||||
|
|
||||||
|
|
@ -307,16 +336,41 @@
|
||||||
this.loading(true);
|
this.loading(true);
|
||||||
const msg = await HttpUtil.post("/panel/setting/restartPanel");
|
const msg = await HttpUtil.post("/panel/setting/restartPanel");
|
||||||
this.loading(false);
|
this.loading(false);
|
||||||
if (msg.success) {
|
if (!msg.success) return;
|
||||||
|
|
||||||
this.loading(true);
|
this.loading(true);
|
||||||
await PromiseUtil.sleep(5000);
|
await PromiseUtil.sleep(5000);
|
||||||
var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
|
|
||||||
if (host == this.oldAllSetting.webDomain) host = null;
|
const { webDomain, webPort, webBasePath, webCertFile, webKeyFile } = this.allSetting;
|
||||||
if (port == this.oldAllSetting.webPort) port = null;
|
const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:";
|
||||||
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
|
||||||
const url = URLBuilder.buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
let base = webBasePath ? webBasePath.replace(/^\//, "") : "";
|
||||||
window.location.replace(url);
|
if (base && !base.endsWith("/")) base += "/";
|
||||||
|
|
||||||
|
if (!this.entryIsIP) {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.pathname = `/${base}panel/settings`;
|
||||||
|
url.protocol = newProtocol;
|
||||||
|
window.location.replace(url.toString());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let finalHost = this.entryHost;
|
||||||
|
let finalPort = this.entryPort || "";
|
||||||
|
|
||||||
|
if (webDomain && this._isIp(webDomain)) {
|
||||||
|
finalHost = webDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webPort && Number(webPort) !== Number(this.entryPort)) {
|
||||||
|
finalPort = String(webPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(`${newProtocol}//${finalHost}`);
|
||||||
|
if (finalPort) url.port = finalPort;
|
||||||
|
url.pathname = `/${base}panel/settings`;
|
||||||
|
|
||||||
|
window.location.replace(url.toString());
|
||||||
},
|
},
|
||||||
toggleTwoFactor(newValue) {
|
toggleTwoFactor(newValue) {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
|
|
@ -568,6 +622,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
this.entryHost = window.location.hostname;
|
||||||
|
this.entryPort = window.location.port;
|
||||||
|
this.entryProtocol = window.location.protocol;
|
||||||
|
this.entryIsIP = this._isIp(this.entryHost);
|
||||||
await this.getAllSetting();
|
await this.getAllSetting();
|
||||||
await this.loadInboundTags();
|
await this.loadInboundTags();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ After=network.target
|
||||||
Wants=network.target
|
Wants=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
EnvironmentFile=-/etc/default/x-ui
|
||||||
Environment="XRAY_VMESS_AEAD_FORCED=false"
|
Environment="XRAY_VMESS_AEAD_FORCED=false"
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/usr/local/x-ui/
|
WorkingDirectory=/usr/local/x-ui/
|
||||||
16
x-ui.service.rhel
Normal file
16
x-ui.service.rhel
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[Unit]
|
||||||
|
Description=x-ui Service
|
||||||
|
After=network.target
|
||||||
|
Wants=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=-/etc/sysconfig/x-ui
|
||||||
|
Environment="XRAY_VMESS_AEAD_FORCED=false"
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/usr/local/x-ui/
|
||||||
|
ExecStart=/usr/local/x-ui/x-ui
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Loading…
Reference in a new issue