init users on create inbound #411
This commit is contained in:
+2
-1
@@ -88,7 +88,8 @@ func (a *APIHandler) postHandler(c *gin.Context) {
|
||||
obj := c.Request.FormValue("object")
|
||||
act := c.Request.FormValue("action")
|
||||
data := c.Request.FormValue("data")
|
||||
objs, err := a.ConfigService.Save(obj, act, json.RawMessage(data), loginUser, hostname)
|
||||
initUsers := c.Request.FormValue("initUsers")
|
||||
objs, err := a.ConfigService.Save(obj, act, json.RawMessage(data), initUsers, loginUser, hostname)
|
||||
if err != nil {
|
||||
jsonMsg(c, "save", err)
|
||||
return
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"s-ui/logger"
|
||||
"s-ui/util"
|
||||
"s-ui/util/common"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -156,6 +157,56 @@ func (s *ClientService) updateLinksWithFixedInbounds(tx *gorm.DB, clients []*mod
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ClientService) UpdateClientsOnInboundAdd(tx *gorm.DB, initIds string, inboundId uint, hostname string) error {
|
||||
clientIds := strings.Split(initIds, ",")
|
||||
var clients []model.Client
|
||||
err := tx.Model(model.Client{}).Where("id in ?", clientIds).Find(&clients).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var inbound model.Inbound
|
||||
err = tx.Model(model.Inbound{}).Preload("Tls").Where("id = ?", inboundId).Find(&inbound).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, client := range clients {
|
||||
// Add inbounds
|
||||
var clientInbounds []uint
|
||||
json.Unmarshal(client.Inbounds, &clientInbounds)
|
||||
clientInbounds = append(clientInbounds, inboundId)
|
||||
client.Inbounds, err = json.MarshalIndent(clientInbounds, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add links
|
||||
var clientLinks, newClientLinks []map[string]string
|
||||
json.Unmarshal(client.Links, &clientLinks)
|
||||
newLinks := util.LinkGenerator(client.Config, &inbound, hostname)
|
||||
for _, newLink := range newLinks {
|
||||
newClientLinks = append(newClientLinks, map[string]string{
|
||||
"remark": inbound.Tag,
|
||||
"type": "local",
|
||||
"uri": newLink,
|
||||
})
|
||||
}
|
||||
for _, clientLink := range clientLinks {
|
||||
if clientLink["remark"] != inbound.Tag {
|
||||
newClientLinks = append(newClientLinks, clientLink)
|
||||
}
|
||||
}
|
||||
|
||||
client.Links, err = json.MarshalIndent(newClientLinks, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.Save(&client).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ClientService) UpdateClientsOnInboundDelete(tx *gorm.DB, id uint, tag string) error {
|
||||
var clients []model.Client
|
||||
err := tx.Table("clients").
|
||||
|
||||
@@ -116,7 +116,7 @@ func (s *ConfigService) StopCore() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ConfigService) Save(obj string, act string, data json.RawMessage, loginUser string, hostname string) ([]string, error) {
|
||||
func (s *ConfigService) Save(obj string, act string, data json.RawMessage, initUsers string, loginUser string, hostname string) ([]string, error) {
|
||||
var err error
|
||||
var inboundIds []uint
|
||||
var inboundId uint
|
||||
@@ -139,7 +139,7 @@ func (s *ConfigService) Save(obj string, act string, data json.RawMessage, login
|
||||
case "tls":
|
||||
inboundIds, err = s.TlsService.Save(tx, act, data)
|
||||
case "inbounds":
|
||||
inboundId, err = s.InboundService.Save(tx, act, data, hostname)
|
||||
inboundId, err = s.InboundService.Save(tx, act, data, initUsers, hostname)
|
||||
case "outbounds":
|
||||
err = s.OutboundService.Save(tx, act, data)
|
||||
case "endpoints":
|
||||
@@ -173,7 +173,6 @@ func (s *ConfigService) Save(obj string, act string, data json.RawMessage, login
|
||||
// Commit changes so far
|
||||
tx.Commit()
|
||||
LastUpdate = time.Now().Unix()
|
||||
var objs []string = []string{obj}
|
||||
tx = db.Begin()
|
||||
|
||||
// Update side changes
|
||||
@@ -186,8 +185,10 @@ func (s *ConfigService) Save(obj string, act string, data json.RawMessage, login
|
||||
}
|
||||
objs = append(objs, "clients")
|
||||
}
|
||||
if obj == "inbounds" && act != "add" {
|
||||
if obj == "inbounds" {
|
||||
switch act {
|
||||
case "new":
|
||||
err = s.ClientService.UpdateClientsOnInboundAdd(tx, initUsers, inboundId, hostname)
|
||||
case "edit":
|
||||
err = s.ClientService.UpdateLinksByInboundChange(tx, []uint{inboundId}, hostname)
|
||||
case "del":
|
||||
|
||||
+67
-14
@@ -96,7 +96,7 @@ func (s *InboundService) FromIds(ids []uint) ([]*model.Inbound, error) {
|
||||
return inbounds, nil
|
||||
}
|
||||
|
||||
func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, hostname string) (uint, error) {
|
||||
func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, initUsers string, hostname string) (uint, error) {
|
||||
var err error
|
||||
var id uint
|
||||
|
||||
@@ -107,7 +107,6 @@ func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, hos
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
id = inbound.Id
|
||||
if inbound.TlsId > 0 {
|
||||
err = tx.Model(model.Tls{}).Where("id = ?", inbound.TlsId).Find(&inbound.Tls).Error
|
||||
if err != nil {
|
||||
@@ -115,6 +114,17 @@ func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, hos
|
||||
}
|
||||
}
|
||||
|
||||
err = util.FillOutJson(&inbound, hostname)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err = tx.Save(&inbound).Error
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
id = inbound.Id
|
||||
|
||||
if corePtr.IsRunning() {
|
||||
if act == "edit" {
|
||||
var oldTag string
|
||||
@@ -133,7 +143,11 @@ func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, hos
|
||||
return 0, err
|
||||
}
|
||||
|
||||
inboundConfig, err = s.addUsers(tx, inboundConfig, inbound.Id, inbound.Type)
|
||||
if act == "edit" {
|
||||
inboundConfig, err = s.addUsers(tx, inboundConfig, inbound.Id, inbound.Type)
|
||||
} else {
|
||||
inboundConfig, err = s.initUsers(tx, inboundConfig, initUsers, inbound.Id, inbound.Type)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -143,16 +157,6 @@ func (s *InboundService) Save(tx *gorm.DB, act string, data json.RawMessage, hos
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
err = util.FillOutJson(&inbound, hostname)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err = tx.Save(&inbound).Error
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case "del":
|
||||
var tag string
|
||||
err = json.Unmarshal(data, &tag)
|
||||
@@ -263,7 +267,56 @@ func (s *InboundService) addUsers(db *gorm.DB, inboundJson []byte, inboundId uin
|
||||
inbound["users"] = usersJson
|
||||
}
|
||||
|
||||
inbound["users"] = usersJson
|
||||
return json.Marshal(inbound)
|
||||
}
|
||||
|
||||
func (s *InboundService) initUsers(db *gorm.DB, inboundJson []byte, clientIds string, inboundId uint, inboundType string) ([]byte, error) {
|
||||
ClientIds := strings.Split(clientIds, ",")
|
||||
if len(ClientIds) == 0 {
|
||||
return inboundJson, nil
|
||||
}
|
||||
switch inboundType {
|
||||
case "mixed", "socks", "http", "shadowsocks", "vmess", "trojan", "naive", "hysteria", "shadowtls", "tuic", "hysteria2", "vless":
|
||||
break
|
||||
default:
|
||||
return inboundJson, nil
|
||||
}
|
||||
|
||||
var inbound map[string]interface{}
|
||||
err := json.Unmarshal(inboundJson, &inbound)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if inboundType == "shadowtls" {
|
||||
version, _ := inbound["version"].(float64)
|
||||
if int(version) < 3 {
|
||||
return inboundJson, nil
|
||||
}
|
||||
}
|
||||
if inboundType == "shadowsocks" {
|
||||
method, _ := inbound["method"].(string)
|
||||
if method == "2022-blake3-aes-128-gcm" {
|
||||
inboundType = "shadowsocks16"
|
||||
}
|
||||
}
|
||||
var users []string
|
||||
err = db.Raw(`SELECT json_extract(clients.config, ?)
|
||||
FROM clients
|
||||
WHERE enable = true AND id in ?`,
|
||||
"$."+inboundType, ClientIds).Scan(&users).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var usersJson []json.RawMessage
|
||||
for _, user := range users {
|
||||
usersJson = append(usersJson, json.RawMessage(user))
|
||||
}
|
||||
|
||||
if len(usersJson) > 0 || inboundType != "shadowsocks" {
|
||||
inbound["users"] = usersJson
|
||||
}
|
||||
|
||||
return json.Marshal(inbound)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,34 +2,41 @@
|
||||
<v-card :subtitle="$t('pages.clients')">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch
|
||||
v-model="hasUser"
|
||||
@change="() => {inbound.users = hasUser? [] : undefined}"
|
||||
color="primary"
|
||||
:label="$t('in.clients')"
|
||||
hide-details></v-switch>
|
||||
<v-select v-model="data.model" :items="initUsersModels" @update:model-value="data.values = []" hide-details></v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4" v-if="data.model == 'group'">
|
||||
<v-select v-model="data.values" multiple chips :items="groupNames" :label="$t('client.group')" hide-details></v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="8" v-if="data.model == 'client'">
|
||||
<v-select v-model="data.values" multiple chips :items="clientNames" :label="$t('pages.clients')" hide-details></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { i18n } from '@/locales';
|
||||
|
||||
|
||||
export default {
|
||||
props: ['inbound'],
|
||||
props: ['data', 'clients'],
|
||||
data() {
|
||||
return {
|
||||
hasUser: false,
|
||||
initUsersModels: [
|
||||
{ title: i18n.global.t('none'), value: 'none' },
|
||||
{ title: i18n.global.t('all'), value: 'all' },
|
||||
{ title: i18n.global.t('client.group'), value: 'group' },
|
||||
{ title: i18n.global.t('pages.clients'), value: 'client' },
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cardTitle() {
|
||||
this.hasUser = Object.hasOwn(this.$props.inbound,'users')
|
||||
return this.$props.inbound?.type.toUpperCase()
|
||||
clientNames() {
|
||||
return this.$props.clients.map((c:any) => { return { title: c.name, value: c.id } } )
|
||||
},
|
||||
groupNames() {
|
||||
return Array.from(new Set(this.$props.clients.map((c:any) => c.group)))
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.hasUser = Object.hasOwn(this.$props.inbound,'users')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -50,7 +50,7 @@
|
||||
<Tun v-if="inbound.type == inTypes.Tun" :data="inbound" />
|
||||
<TProxy v-if="inbound.type == inTypes.TProxy" :inbound="inbound" />
|
||||
<Transport v-if="Object.hasOwn(inbound,'transport')" :data="inbound" />
|
||||
<Users v-if="HasOptionalUser.includes(inbound.type)" :inbound="inbound" />
|
||||
<Users v-if="hasUser" :clients="clients" :data="initUsers" />
|
||||
<InTls v-if="HasTls.includes(inbound.type)" :inbound="inbound" :tlsConfigs="tlsConfigs" :tls_id="inbound.tls_id" />
|
||||
<Multiplex v-if="Object.hasOwn(inbound,'multiplex')" direction="in" :data="inbound" />
|
||||
</v-window-item>
|
||||
@@ -95,7 +95,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { InTypes, createInbound, Addr } from '@/types/inbounds'
|
||||
import { InTypes, createInbound, Addr, inboundWithUsers, ShadowTLS } from '@/types/inbounds'
|
||||
import RandomUtil from '@/plugins/randomUtil'
|
||||
|
||||
import Listen from '@/components/Listen.vue'
|
||||
@@ -125,7 +125,11 @@ export default {
|
||||
loading: false,
|
||||
side: "s",
|
||||
inTypes: InTypes,
|
||||
HasOptionalUser: [InTypes.Mixed,InTypes.SOCKS,InTypes.HTTP,InTypes.Shadowsocks],
|
||||
inboundWithUsers: inboundWithUsers,
|
||||
initUsers: {
|
||||
model: 'none',
|
||||
values: <any>[],
|
||||
},
|
||||
HasInData: [
|
||||
InTypes.SOCKS,
|
||||
InTypes.HTTP,
|
||||
@@ -179,6 +183,10 @@ export default {
|
||||
this.loading = false
|
||||
}
|
||||
this.side = "s"
|
||||
this.initUsers = {
|
||||
model: 'none',
|
||||
values: [],
|
||||
}
|
||||
},
|
||||
changeType() {
|
||||
if (!this.inbound.listen_port) this.inbound.listen_port = RandomUtil.randomIntRange(10000, 60000)
|
||||
@@ -205,7 +213,22 @@ export default {
|
||||
},
|
||||
saveChanges() {
|
||||
this.loading = true
|
||||
this.$emit('save', this.inbound)
|
||||
if (this.hasUser) {
|
||||
let clientIds = []
|
||||
switch (this.initUsers.model) {
|
||||
case 'all':
|
||||
clientIds = this.clients.map((c:any) => c.id)
|
||||
break
|
||||
case 'group':
|
||||
clientIds = this.clients.filter((c:any) => this.initUsers.values.includes(c.group)).map((c:any) => c.id)
|
||||
break
|
||||
case 'user':
|
||||
clientIds = this.initUsers.values
|
||||
}
|
||||
this.$emit('save', this.inbound, clientIds.length > 0 ? clientIds : undefined)
|
||||
} else {
|
||||
this.$emit('save', this.inbound)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
},
|
||||
@@ -217,6 +240,15 @@ export default {
|
||||
if (this.OnlyTLS.includes(this.inbound.type) && this.inbound.tls_id == 0) return false
|
||||
return true
|
||||
},
|
||||
clients() {
|
||||
return Data().clients?? []
|
||||
},
|
||||
hasUser() {
|
||||
if (this.$props.id > 0) return false
|
||||
if (!inboundWithUsers.includes(this.inbound.type)) return false
|
||||
if (this.inbound.type == InTypes.ShadowTLS && (<ShadowTLS>this.inbound).version < 3 ) return false
|
||||
return true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(newValue) {
|
||||
|
||||
@@ -64,10 +64,12 @@ const Data = defineStore('Data', {
|
||||
}
|
||||
return <Client>{}
|
||||
},
|
||||
async save (object: string, action: string, data: any, initUsers?: number[]): Promise<boolean> {
|
||||
let postData = {
|
||||
object: object,
|
||||
action: action,
|
||||
data: JSON.stringify(data, null, 2),
|
||||
initUsers: initUsers?.join(',') ?? undefined
|
||||
}
|
||||
const msg = await HttpUtils.post('api/save', postData)
|
||||
if (msg.success) {
|
||||
|
||||
Reference in New Issue
Block a user