[feature] separate subscription service

This commit is contained in:
Alireza Ahmadi
2023-05-20 19:52:54 +02:00
parent 5b306e57c9
commit 2b8c913be9
24 changed files with 584 additions and 70 deletions

View File

@@ -71,7 +71,7 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="app.subSettings.enable">
<td>Subscription</td>
<td>
<a-form-item>
@@ -79,7 +79,7 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item>
@@ -215,6 +215,7 @@
case Protocols.VMESS: return clientSettings.vmesses;
case Protocols.VLESS: return clientSettings.vlesses;
case Protocols.TROJAN: return clientSettings.trojans;
case Protocols.SHADOWSOCKS: return clientSettings.shadowsockses;
default: return null;
}
},
@@ -223,6 +224,7 @@
case Protocols.VMESS: return new Inbound.VmessSettings.Vmess();
case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS();
case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan();
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks();
default: return null;
}
},

View File

@@ -54,7 +54,7 @@
</a-form-item>
</td>
</tr>
<tr v-if="client.email">
<tr v-if="client.email && app.subSettings.enable">
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomText(16,16)" type="sync"></a-icon></td>
<td>
<a-form-item>
@@ -62,7 +62,7 @@
</a-form-item>
</td>
</tr>
<tr v-if="client.email">
<tr v-if="client.email && app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item>

View File

@@ -29,18 +29,18 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.subSettings.enable">
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomText(16,16)" type="sync"></a-icon></td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.subId" style="width: 200px;"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.tgId" style="width: 200px;"></a-input>
</a-form-item>
</td>

View File

@@ -27,18 +27,18 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.subSettings.enable">
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomText(16,16)" type="sync"></a-icon></td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.subId" style="width: 200px;"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.tgId" style="width: 200px;"></a-input>
</a-form-item>
</td>

View File

@@ -38,18 +38,18 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.subSettings.enable">
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomText(16,16)" type="sync"></a-icon></td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.subId" style="width: 200px;"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.tgId" style="width: 200px;"></a-input>
</a-form-item>
</td>

View File

@@ -35,18 +35,18 @@
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.subSettings.enable">
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomText(16,16)" type="sync"></a-icon></td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.subId" style="width: 200px;"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<tr v-if="client.email && app.tgBotEnable">
<td>Telegram Username</td>
<td>
<a-form-item v-if="client.email">
<a-form-item>
<a-input v-model.trim="client.tgId" style="width: 200px;"></a-input>
</a-form-item>
</td>

View File

@@ -102,19 +102,16 @@
</td>
</tr>
</table>
<table v-if="infoModal.clientSettings.subId + infoModal.clientSettings.tgId" style="margin-bottom: 10px;">
<tr v-if="infoModal.clientSettings.subId">
<td>Subscription link</td>
<td>
<a :href="[[ subBase + infoModal.clientSettings.subId ]]" target="_blank">[[ subBase + infoModal.clientSettings.subId ]]</a>
<a-icon id="copy-sub-link" type="snippets" @click="copyToClipboard('copy-sub-link', subBase + infoModal.clientSettings.subId)"></a-icon>
</td>
</tr>
<tr v-if="infoModal.clientSettings.tgId">
<td>Telegram Username</td>
<td><a :href="[[ tgBase + infoModal.clientSettings.tgId ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></td>
</tr>
</table>
<template v-if="app.subSettings.enable && infoModal.clientSettings.subId">
<a-divider>Subscription link</a-divider>
<a :href="[[ infoModal.subLink ]]" target="_blank">[[ infoModal.subLink ]]</a>
<a-icon id="copy-sub-link" type="snippets" @click="copyToClipboard('copy-sub-link', infoModal.subLink)"></a-icon>
</template>
<template v-if="app.tgBotEnable && infoModal.clientSettings.tgId">
<a-divider>Telegram Username</a-divider>
<a :href="[[ infoModal.tgLink ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a>
<a-icon id="copy-tg-link" type="snippets" @click="copyToClipboard('copy-tg-link', '@' + infoModal.clientSettings.tgId)"></a-icon>
</template>
</template>
<template v-else>
<a-divider></a-divider>
@@ -198,6 +195,8 @@
link: null,
index: null,
isExpired: false,
subLink: '',
tgLink: '',
show(dbInbound, index) {
this.index = index;
this.inbound = dbInbound.toInbound();
@@ -207,11 +206,27 @@
this.clientSettings = this.settings.clients ? Object.values(this.settings.clients)[index] : null;
this.isExpired = this.inbound.isExpiry(index);
this.clientStats = this.settings.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
if (this.clientSettings) {
if (this.clientSettings.subId) {
this.subLink = this.genSubLink(this.clientSettings.subId);
}
if (this.clientSettings.tgId) {
this.tgLink = "https://t.me/" + this.clientSettings.tgId;
}
}
this.visible = true;
},
close() {
infoModal.visible = false;
},
genSubLink(subID) {
protocol = app.subSettings.tls ? "https://" : "http://";
hostName = app.subSettings.domain === "" ? window.location.hostname : app.subSettings.domain;
subPort = app.subSettings.port;
port = (subPort === 443 && app.subSettings.tls) || (subPort === 80 && !app.subSettings.tls) ? "" : ":" + String(subPort);
subPath = app.subSettings.path;
return protocol + hostName + port + subPath + subID;
}
};
const infoModalApp = new Vue({
@@ -237,12 +252,6 @@
}
return infoModal.dbInbound.isEnable;
},
get subBase() {
return window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port:"") + basePath + "sub/";
},
get tgBase() {
return "https://t.me/"
},
},
methods: {
copyToClipboard(elmentId,content) {

View File

@@ -339,7 +339,15 @@
clientCount: {},
isRefreshEnabled: localStorage.getItem("isRefreshEnabled") === "true" ? true : false,
refreshing: false,
refreshInterval: Number(localStorage.getItem("refreshInterval")) || 5000
refreshInterval: Number(localStorage.getItem("refreshInterval")) || 5000,
subSettings: {
enable : false,
port: 0,
path: '',
domain: '',
tls: false
},
tgBotEnable: false
},
methods: {
loading(spinning = true) {
@@ -361,10 +369,20 @@
if (!msg.success) {
return;
}
this.expireDiff = msg.obj.expireDiff * 86400000;
this.trafficDiff = msg.obj.trafficDiff * 1073741824;
this.defaultCert = msg.obj.defaultCert;
this.defaultKey = msg.obj.defaultKey;
with(msg.obj){
this.expireDiff = expireDiff * 86400000;
this.trafficDiff = trafficDiff * 1073741824;
this.defaultCert = defaultCert;
this.defaultKey = defaultKey;
this.tgBotEnable = tgBotEnable;
this.subSettings = {
enable : subEnable,
port: subPort,
path: subPath,
domain: subDomain,
tls: subTLS
};
}
},
setInbounds(dbInbounds) {
this.inbounds.splice(0);

View File

@@ -255,6 +255,24 @@
<setting-list-item type="number" title='{{ i18n "pages.settings.tgNotifyCpu" }}' desc='{{ i18n "pages.settings.tgNotifyCpuDesc" }}' v-model="allSetting.tgCpu" :min="0" :max="100"></setting-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane key="5" tab='{{ i18n "pages.settings.subSettings" }}'>
<a-row :xs="24" :sm="24" :lg="12">
<h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 20px 20px; text-align: center;">
<a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
{{ i18n "pages.settings.infoDesc" }}
</h2>
</a-row>
<a-list item-layout="horizontal" :style="themeSwitcher.textStyle">
<setting-list-item type="switch" title='{{ i18n "pages.settings.subEnable"}}' desc='{{ i18n "pages.settings.subEnableDesc"}}' v-model="allSetting.subEnable"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.subListen"}}' desc='{{ i18n "pages.settings.subListenDesc"}}' v-model="allSetting.subListen"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.subPort"}}' desc='{{ i18n "pages.settings.subPortDesc"}}' v-model.number="allSetting.subPort"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.subPath"}}' desc='{{ i18n "pages.settings.subPathDesc"}}' v-model="allSetting.subPath"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.subDomain"}}' desc='{{ i18n "pages.settings.subDomainDesc"}}' v-model="allSetting.subDomain"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.subCertPath"}}' desc='{{ i18n "pages.settings.subCertPathDesc"}}' v-model="allSetting.subCertFile"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.subKeyPath"}}' desc='{{ i18n "pages.settings.subKeyPathDesc"}}' v-model="allSetting.subKeyFile"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.subUpdates"}}' desc='{{ i18n "pages.settings.subUpdatesDesc"}}' v-model="allSetting.subUpdates"></setting-list-item>
</a-list>
</a-tab-pane>
</a-tabs>
</a-space>
</a-spin>