feat: 网站密码认证支持子目录 (#6078)

Refs https://github.com/1Panel-dev/1Panel/issues/5863
This commit is contained in:
zhengkunwang 2024-08-09 18:00:39 +08:00 committed by GitHub
parent e003d74506
commit 9114df9c2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 407 additions and 68 deletions

View File

@ -643,6 +643,47 @@ func (b *BaseApi) UpdateAuthConfig(c *gin.Context) {
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Get AuthBasic conf
// @Description 获取路由密码访问配置
// @Accept json
// @Param request body request.NginxAuthReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/auths/path [post]
func (b *BaseApi) GetPathAuthConfig(c *gin.Context) {
var req request.NginxAuthReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteService.GetPathAuthBasics(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website
// @Summary Get AuthBasic conf
// @Description 更新路由密码访问配置
// @Accept json
// @Param request body request.NginxPathAuthUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/auths/path/update [post]
func (b *BaseApi) UpdatePathAuthConfig(c *gin.Context) {
var req request.NginxPathAuthUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.UpdatePathAuthBasic(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Get AntiLeech conf
// @Description 获取防盗链配置

View File

@ -33,6 +33,13 @@ type NginxAuth struct {
Remark string `json:"remark"`
}
type NginxPathAuth struct {
Username string `json:"username"`
Remark string `json:"remark"`
Path string `json:"path"`
Name string `json:"name"`
}
type NginxKey string
const (

View File

@ -44,6 +44,16 @@ type NginxAuthUpdate struct {
Remark string `json:"remark"`
}
type NginxPathAuthUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Operate string `json:"operate" validate:"required"`
Name string `json:"name"`
Username string `json:"username"`
Password string `json:"password"`
Path string `json:"path"`
Remark string `json:"remark"`
}
type NginxAuthReq struct {
WebsiteID uint `json:"websiteID" validate:"required"`
}

View File

@ -22,6 +22,10 @@ type NginxAuthRes struct {
Items []dto.NginxAuth `json:"items"`
}
type NginxPathAuthRes struct {
dto.NginxPathAuth
}
type NginxAntiLeechRes struct {
Enable bool `json:"enable"`
Extends string `json:"extends"`

View File

@ -89,17 +89,23 @@ type IWebsiteService interface {
LoadWebsiteDirConfig(req request.WebsiteCommonReq) (*response.WebsiteDirConfig, error)
UpdateSiteDir(req request.WebsiteUpdateDir) error
UpdateSitePermission(req request.WebsiteUpdateDirPermission) error
OperateProxy(req request.WebsiteProxyConfig) (err error)
GetProxies(id uint) (res []request.WebsiteProxyConfig, err error)
UpdateProxyFile(req request.NginxProxyUpdate) (err error)
GetAuthBasics(req request.NginxAuthReq) (res response.NginxAuthRes, err error)
UpdateAuthBasic(req request.NginxAuthUpdate) (err error)
GetAntiLeech(id uint) (*response.NginxAntiLeechRes, error)
UpdateAntiLeech(req request.NginxAntiLeechUpdate) (err error)
OperateRedirect(req request.NginxRedirectReq) (err error)
GetRedirect(id uint) (res []response.NginxRedirectConfig, err error)
UpdateRedirectFile(req request.NginxRedirectUpdate) (err error)
GetAuthBasics(req request.NginxAuthReq) (res response.NginxAuthRes, err error)
UpdateAuthBasic(req request.NginxAuthUpdate) (err error)
GetPathAuthBasics(req request.NginxAuthReq) (res []response.NginxPathAuthRes, err error)
UpdatePathAuthBasic(req request.NginxPathAuthUpdate) error
UpdateDefaultHtml(req request.WebsiteHtmlUpdate) error
GetDefaultHtml(resourceType string) (*response.WebsiteHtmlRes, error)
}
@ -1935,6 +1941,50 @@ func (w WebsiteService) UpdateProxyFile(req request.NginxProxyUpdate) (err error
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
}
func (w WebsiteService) GetAuthBasics(req request.NginxAuthReq) (res response.NginxAuthRes, err error) {
var (
website model.Website
nginxInstall model.AppInstall
authContent []byte
nginxParams []response.NginxParam
)
website, err = websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
if err != nil {
return
}
nginxInstall, err = getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return
}
authPath := fmt.Sprintf("/www/sites/%s/auth_basic/auth.pass", website.Alias)
absoluteAuthPath := path.Join(nginxInstall.GetPath(), authPath)
fileOp := files.NewFileOp()
if !fileOp.Stat(absoluteAuthPath) {
return
}
nginxParams, err = getNginxParamsByKeys(constant.NginxScopeServer, []string{"auth_basic"}, &website)
if err != nil {
return
}
res.Enable = len(nginxParams[0].Params) > 0
authContent, err = fileOp.GetContent(absoluteAuthPath)
authArray := strings.Split(string(authContent), "\n")
for _, line := range authArray {
if line == "" {
continue
}
params := strings.Split(line, ":")
auth := dto.NginxAuth{
Username: params[0],
}
if len(params) == 3 {
auth.Remark = params[2]
}
res.Items = append(res.Items, auth)
}
return
}
func (w WebsiteService) UpdateAuthBasic(req request.NginxAuthUpdate) (err error) {
var (
website model.Website
@ -2064,12 +2114,11 @@ func (w WebsiteService) UpdateAuthBasic(req request.NginxAuthUpdate) (err error)
return
}
func (w WebsiteService) GetAuthBasics(req request.NginxAuthReq) (res response.NginxAuthRes, err error) {
func (w WebsiteService) GetPathAuthBasics(req request.NginxAuthReq) (res []response.NginxPathAuthRes, err error) {
var (
website model.Website
nginxInstall model.AppInstall
authContent []byte
nginxParams []response.NginxParam
)
website, err = websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
if err != nil {
@ -2079,35 +2128,127 @@ func (w WebsiteService) GetAuthBasics(req request.NginxAuthReq) (res response.Ng
if err != nil {
return
}
authPath := fmt.Sprintf("/www/sites/%s/auth_basic/auth.pass", website.Alias)
absoluteAuthPath := path.Join(nginxInstall.GetPath(), authPath)
fileOp := files.NewFileOp()
if !fileOp.Stat(absoluteAuthPath) {
authDir := fmt.Sprintf("/www/sites/%s/path_auth", website.Alias)
absoluteAuthDir := path.Join(nginxInstall.GetPath(), authDir)
passDir := path.Join(absoluteAuthDir, "pass")
if !fileOp.Stat(absoluteAuthDir) || !fileOp.Stat(passDir) {
return
}
nginxParams, err = getNginxParamsByKeys(constant.NginxScopeServer, []string{"auth_basic"}, &website)
entries, err := os.ReadDir(absoluteAuthDir)
if err != nil {
return
return nil, err
}
res.Enable = len(nginxParams[0].Params) > 0
authContent, err = fileOp.GetContent(absoluteAuthPath)
authArray := strings.Split(string(authContent), "\n")
for _, line := range authArray {
if line == "" {
continue
for _, entry := range entries {
if !entry.IsDir() {
name := strings.TrimSuffix(entry.Name(), ".conf")
pathAuth := dto.NginxPathAuth{
Name: name,
}
configPath := path.Join(absoluteAuthDir, entry.Name())
content, err := fileOp.GetContent(configPath)
if err != nil {
return nil, err
}
config, err := parser.NewStringParser(string(content)).Parse()
if err != nil {
return nil, err
}
directives := config.Directives
location, _ := directives[0].(*components.Location)
pathAuth.Path = location.Match
passPath := path.Join(passDir, fmt.Sprintf("%s.pass", name))
authContent, err = fileOp.GetContent(passPath)
authArray := strings.Split(string(authContent), "\n")
for _, line := range authArray {
if line == "" {
continue
}
params := strings.Split(line, ":")
pathAuth.Username = params[0]
if len(params) == 3 {
pathAuth.Remark = params[2]
}
}
res = append(res, response.NginxPathAuthRes{
NginxPathAuth: pathAuth,
})
}
params := strings.Split(line, ":")
auth := dto.NginxAuth{
Username: params[0],
}
if len(params) == 3 {
auth.Remark = params[2]
}
res.Items = append(res.Items, auth)
}
return
}
func (w WebsiteService) UpdatePathAuthBasic(req request.NginxPathAuthUpdate) error {
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
if err != nil {
return err
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return err
}
fileOp := files.NewFileOp()
authDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "path_auth")
if !fileOp.Stat(authDir) {
_ = fileOp.CreateDir(authDir, 0755)
}
passDir := path.Join(authDir, "pass")
if !fileOp.Stat(passDir) {
_ = fileOp.CreateDir(passDir, 0755)
}
confPath := path.Join(authDir, fmt.Sprintf("%s.conf", req.Name))
passPath := path.Join(passDir, fmt.Sprintf("%s.pass", req.Name))
var config *components.Config
switch req.Operate {
case "delete":
_ = fileOp.DeleteFile(confPath)
_ = fileOp.DeleteFile(passPath)
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
case "create":
config, err = parser.NewStringParser(string(nginx_conf.PathAuth)).Parse()
if err != nil {
return err
}
if fileOp.Stat(confPath) || fileOp.Stat(passPath) {
return buserr.New(constant.ErrNameIsExist)
}
case "edit":
par, err := parser.NewParser(confPath)
if err != nil {
return err
}
config, err = par.Parse()
if err != nil {
return err
}
}
config.FilePath = confPath
directives := config.Directives
location, _ := directives[0].(*components.Location)
location.UpdateDirective("auth_basic_user_file", []string{fmt.Sprintf("/www/sites/%s/path_auth/pass/%s", website.Alias, fmt.Sprintf("%s.pass", req.Name))})
location.ChangePath("~*", req.Path)
var passwdHash []byte
passwdHash, err = bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
return err
}
line := fmt.Sprintf("%s:%s\n", req.Username, passwdHash)
if req.Remark != "" {
line = fmt.Sprintf("%s:%s:%s\n", req.Username, passwdHash, req.Remark)
}
_ = fileOp.SaveFile(passPath, line, 0644)
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
}
nginxInclude := fmt.Sprintf("/www/sites/%s/path_auth/*.conf", website.Alias)
if err = updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "include", Params: []string{nginxInclude}}}, &website); err != nil {
return nil
}
return nil
}
func (w WebsiteService) UpdateAntiLeech(req request.NginxAntiLeechUpdate) (err error) {
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID))
if err != nil {

View File

@ -37,3 +37,6 @@ var DomainNotFoundHTML []byte
//go:embed stop.html
var StopHTML []byte
//go:embed path_auth.conf
var PathAuth []byte

View File

@ -0,0 +1,4 @@
location ~* ^/test* {
auth_basic "Authorization";
auth_basic_user_file /www/site/pass/ceshi.pass ;
}

View File

@ -56,6 +56,8 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) {
websiteRouter.POST("/auths", baseApi.GetAuthConfig)
websiteRouter.POST("/auths/update", baseApi.UpdateAuthConfig)
websiteRouter.POST("/auths/path", baseApi.GetPathAuthConfig)
websiteRouter.POST("/auths/path/update", baseApi.UpdatePathAuthConfig)
websiteRouter.POST("/leech", baseApi.GetAntiLeech)
websiteRouter.POST("/leech/update", baseApi.UpdateAntiLeech)

View File

@ -393,6 +393,7 @@ export namespace Website {
content?: string;
proxyAddress?: string;
proxyProtocol?: string;
sni?: boolean;
}
export interface ProxReplace {
@ -425,6 +426,18 @@ export namespace Website {
username: string;
password: string;
remark: string;
scope: string;
path?: '';
name?: '';
}
export interface NginxPathAuthConfig {
websiteID: number;
operate: string;
path: string;
username: string;
password: string;
name: string;
}
export interface LeechConfig {

View File

@ -210,6 +210,14 @@ export const OperateAuthConfig = (req: Website.NginxAuthConfig) => {
return http.post<any>(`/websites/auths/update`, req);
};
export const GetPathAuthConfig = (req: Website.AuthReq) => {
return http.post<Website.NginxPathAuthConfig[]>(`/websites/auths/path`, req);
};
export const OperatePathAuthConfig = (req: Website.NginxPathAuthConfig) => {
return http.post(`/websites/auths/path/update`, req);
};
export const GetAntiLeech = (req: Website.LeechReq) => {
return http.post<Website.LeechConfig>(`/websites/leech`, req);
};

View File

@ -2056,7 +2056,6 @@ const message = {
proxyHelper1: 'When accessing this directory, the content of the target URL will be returned and displayed',
proxyPassHelper: 'The proxied site must be a valid and accessible URL',
proxyHostHelper: 'Pass the domain name in the request header to the proxy server',
replacementHelper: 'Up to 5 replacements can be added, please leave blank if no replacement is required',
modifier: 'Matching Rules',
modifierHelper: 'Example: = exact match, ~ regular match, ^~ match the beginning of the path, etc',
replace: 'Text Replacement',
@ -2134,6 +2133,7 @@ const message = {
generateDomain: 'Generate',
domainSSLHelper:
'Enabling SSL on a non-443 port will cause the 443 port to stop listening. If you need the 443 port to continue listening, please add the domain:443',
global: 'Global',
},
php: {
short_open_tag: 'Short tag support',

View File

@ -1912,7 +1912,6 @@ const message = {
proxyHelper1: '訪問這個目錄時將會把目標URL的內容返回並顯示',
proxyPassHelper: '代理的站點必須為可正常訪問的URL',
proxyHostHelper: '將域名添加到請求頭傳遞到代理服務器',
replacementHelper: '最多可以添加5條替換內容,如果不需要替換請留空',
modifier: '匹配規則',
modifierHelper: '= 精確匹配~ 正則匹配^~ 匹配路徑開頭 ',
replace: '文本替換',
@ -1983,6 +1982,7 @@ const message = {
batchAdd: '批量添加域名',
generateDomain: '生成',
domainSSLHelper: ' 443 端口開啟 SSL 會導致 443 端口移除監聽如需 443 端口繼續監聽請添加域名:443',
global: '全局',
},
php: {
short_open_tag: '短標簽支持',

View File

@ -1914,7 +1914,6 @@ const message = {
proxyHelper1: '访问这个目录时将会把目标URL的内容返回并显示',
proxyPassHelper: '代理的站点必须为可正常访问的URL',
proxyHostHelper: '将域名添加到请求头传递到代理服务器',
replacementHelper: '最多可以添加5条替换内容,如果不需要替换请留空',
modifier: '匹配规则',
modifierHelper: '= 精确匹配~ 正则匹配^~ 匹配路径开头 ',
replace: '文本替换',
@ -1985,6 +1984,7 @@ const message = {
batchAdd: '批量添加域名',
generateDomain: '生成',
domainSSLHelper: ' 443 端口开启 SSL 会导致 443 端口去掉监听如需 443 端口继续监听请添加域名:443',
global: '全局',
},
php: {
short_open_tag: '短标签支持',

View File

@ -20,8 +20,17 @@
/>
</el-form-item>
<el-form ref="proxyForm" label-position="top" :model="authBasic" :rules="rules">
<el-form-item :label="$t('commons.table.name')" prop="name" v-if="authBasic.scope != 'root'">
<el-input v-model.trim="authBasic.name" :disabled="authBasic.operate === 'edit'"></el-input>
</el-form-item>
<el-form-item :label="$t('website.path')" prop="path" v-if="authBasic.scope != 'root'">
<el-input v-model.trim="authBasic.path" :disabled="authBasic.operate === 'edit'"></el-input>
</el-form-item>
<el-form-item :label="$t('commons.login.username')" prop="username">
<el-input v-model.trim="authBasic.username" :disabled="authBasic.operate === 'edit'"></el-input>
<el-input
v-model.trim="authBasic.username"
:disabled="authBasic.scope == 'root' && authBasic.operate === 'edit'"
></el-input>
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="password">
<el-input type="password" clearable show-password v-model.trim="authBasic.password">
@ -51,7 +60,7 @@
<script lang="ts" setup>
import DrawerHeader from '@/components/drawer-header/index.vue';
import { OperateAuthConfig } from '@/api/modules/website';
import { OperateAuthConfig, OperatePathAuthConfig } from '@/api/modules/website';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { FormInstance } from 'element-plus';
@ -64,6 +73,8 @@ const proxyForm = ref<FormInstance>();
const rules = ref({
username: [Rules.requiredInput, Rules.name],
password: [Rules.requiredInput],
name: [Rules.requiredInput],
path: [Rules.requiredInput],
});
const open = ref(false);
const loading = ref(false);
@ -74,6 +85,8 @@ const initData = (): Website.NginxAuthConfig => ({
username: '',
password: '',
remark: '',
scope: 'root',
path: '',
});
let authBasic = ref(initData());
@ -95,23 +108,36 @@ const acceptParams = (proxyParam: Website.NginxAuthConfig) => {
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
await formEl.validate(async (valid) => {
if (!valid) {
return;
}
loading.value = true;
OperateAuthConfig(authBasic.value)
.then(() => {
if (authBasic.value.operate == 'create') {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
} else {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
}
handleClose();
})
.finally(() => {
loading.value = false;
});
try {
if (authBasic.value.scope == 'root') {
await OperateAuthConfig(authBasic.value);
} else {
const req = {
websiteID: authBasic.value.websiteID,
path: authBasic.value.path,
name: authBasic.value.name,
username: authBasic.value.username,
password: authBasic.value.password,
operate: authBasic.value.operate,
remark: authBasic.value.remark,
};
await OperatePathAuthConfig(req);
}
if (authBasic.value.operate == 'create') {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
} else {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
}
handleClose();
} catch (error) {
} finally {
loading.value = false;
}
});
};

View File

@ -1,32 +1,60 @@
<template>
<el-form-item prop="enable" :label="$t('website.enableOrNot')">
<el-switch v-model="enable" @change="changeEnable" :disabled="data.length === 0"></el-switch>
</el-form-item>
<ComplexTable :data="data" @search="search" v-loading="loading" :heightDiff="420">
<template #toolbar>
<el-button type="primary" plain @click="openCreate">
{{ $t('commons.button.create') }}
</el-button>
</template>
<el-table-column :label="$t('commons.login.username')" prop="username"></el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark"></el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="buttons"
:label="$t('commons.table.operate')"
:fixed="mobile ? false : 'right'"
fix
/>
</ComplexTable>
<Create ref="createRef" @close="search()" />
<el-tabs type="border-card" @tab-change="searchAll()">
<el-tab-pane :label="$t('website.global')">
<ComplexTable :data="data" @search="search" v-loading="loading" :heightDiff="420">
<template #toolbar>
<el-button type="primary" plain @click="openCreate('root')">
{{ $t('commons.button.create') }}
</el-button>
<el-switch
class="ml-5"
v-model="enable"
@change="changeEnable"
:disabled="data.length === 0"
></el-switch>
</template>
<el-table-column :label="$t('commons.login.username')" prop="username"></el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark"></el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="buttons"
:label="$t('commons.table.operate')"
:fixed="mobile ? false : 'right'"
fix
/>
</ComplexTable>
</el-tab-pane>
<el-tab-pane :label="$t('website.path')">
<ComplexTable :data="pathData" @search="searchPath" v-loading="loading" :heightDiff="420">
<template #toolbar>
<el-button type="primary" plain @click="openCreate('path')">
{{ $t('commons.button.create') }}
</el-button>
</template>
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
<el-table-column :label="$t('website.path')" prop="path"></el-table-column>
<el-table-column :label="$t('commons.login.username')" prop="username"></el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark"></el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="pathButtons"
:label="$t('commons.table.operate')"
:fixed="mobile ? false : 'right'"
fix
/>
</ComplexTable>
</el-tab-pane>
</el-tabs>
<OpDialog ref="opRef" @search="search" />
<Create ref="createRef" @close="searchAll()" />
<OpDialog ref="opRef" @search="searchAll" />
</template>
<script lang="ts" setup name="proxy">
import { Website } from '@/api/interface/website';
import { OperateAuthConfig, GetAuthConfig } from '@/api/modules/website';
import { OperateAuthConfig, GetAuthConfig, GetPathAuthConfig, OperatePathAuthConfig } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import i18n from '@/lang';
import Create from './create/index.vue';
@ -51,6 +79,7 @@ const data = ref([]);
const createRef = ref();
const enable = ref(false);
const opRef = ref();
const pathData = ref([]);
const buttons = [
{
@ -67,16 +96,34 @@ const buttons = [
},
];
const pathButtons = [
{
label: i18n.global.t('commons.button.edit'),
click: function (row: Website.NginxAuthConfig) {
openEdit(row);
},
},
{
label: i18n.global.t('commons.button.delete'),
click: function (row: Website.NginxPathAuthConfig) {
deletePathAuth(row);
},
},
];
const initData = (id: number): Website.NginxAuthConfig => ({
websiteID: id,
operate: 'create',
username: '',
password: '',
remark: '',
scope: 'root',
});
const openCreate = () => {
createRef.value.acceptParams(initData(id.value));
const openCreate = (scope: string) => {
let req = initData(id.value);
req.scope = scope;
createRef.value.acceptParams(req);
};
const openEdit = (authConfig: Website.NginxAuthConfig) => {
@ -101,6 +148,21 @@ const deleteAuth = async (authConfig: Website.NginxAuthConfig) => {
});
};
const deletePathAuth = async (authConfig: Website.NginxPathAuthConfig) => {
authConfig.operate = 'delete';
authConfig.websiteID = id.value;
opRef.value.acceptParams({
title: i18n.global.t('commons.button.delete'),
names: [authConfig.name],
msg: i18n.global.t('commons.msg.operatorHelper', [
i18n.global.t('website.basicAuth'),
i18n.global.t('commons.button.delete'),
]),
api: OperatePathAuthConfig,
params: authConfig,
});
};
const changeEnable = () => {
const req = initData(id.value);
req.operate = enable.value ? 'enable' : 'disable';
@ -127,7 +189,24 @@ const search = async () => {
}
};
onMounted(() => {
const searchPath = async () => {
try {
loading.value = true;
const res = await GetPathAuthConfig({ websiteID: id.value });
pathData.value = res.data || [];
} catch (error) {
} finally {
loading.value = false;
}
};
const searchAll = () => {
search();
searchPath();
console.log(11111);
};
onMounted(() => {
searchAll();
});
</script>

View File

@ -99,7 +99,7 @@
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addReplaces" :disabled="replaces.length >= 5">
<el-button type="primary" @click="addReplaces">
{{ $t('website.addReplace') }}
</el-button>
<div>
@ -159,6 +159,7 @@ const initData = (): Website.ProxyConfig => ({
replaces: {},
proxyAddress: '',
proxyProtocol: 'http://',
sni: false,
});
let proxy = ref(initData());
const replaces = ref<any>([]);