mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-13 17:24:44 +08:00
feat: 网站 HTTPS 逻辑优化 (#6074)
This commit is contained in:
parent
a225d2d79a
commit
e003d74506
@ -71,3 +71,25 @@ func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// 写一个 update website domain 的接口
|
||||
// @Tags Website Domain
|
||||
// @Summary Update website domain
|
||||
// @Description 更新网站域名
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteDomainUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/domains/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"更新域名 [domain]","formatEN":"Update domain [domain]"}
|
||||
func (b *BaseApi) UpdateWebDomain(c *gin.Context) {
|
||||
var req request.WebsiteDomainUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateWebsiteDomain(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
@ -127,10 +127,15 @@ type WebsiteDomainCreate struct {
|
||||
Domains []WebsiteDomain `json:"domains" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteDomainUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
SSL bool `json:"ssl"`
|
||||
}
|
||||
|
||||
type WebsiteDomain struct {
|
||||
Domain string `json:"domain" validate:"required"`
|
||||
Port int `json:"port"`
|
||||
SSL bool `json:"SSL"`
|
||||
SSL bool `json:"ssl"`
|
||||
}
|
||||
|
||||
type WebsiteDomainDelete struct {
|
||||
|
@ -4,7 +4,7 @@ type WebsiteDomain struct {
|
||||
BaseModel
|
||||
WebsiteID uint `gorm:"column:website_id;type:varchar(64);not null;" json:"websiteId"`
|
||||
Domain string `gorm:"type:varchar(256);not null" json:"domain"`
|
||||
SSL bool `json:"SSL"`
|
||||
SSL bool `json:"ssl"`
|
||||
Port int `gorm:"type:integer" json:"port"`
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ type IWebsiteService interface {
|
||||
CreateWebsiteDomain(create request.WebsiteDomainCreate) ([]model.WebsiteDomain, error)
|
||||
GetWebsiteDomain(websiteId uint) ([]model.WebsiteDomain, error)
|
||||
DeleteWebsiteDomain(domainId uint) error
|
||||
UpdateWebsiteDomain(req request.WebsiteDomainUpdate) error
|
||||
|
||||
GetNginxConfigByScope(req request.NginxScopeReq) (*response.WebsiteNginxConfig, error)
|
||||
UpdateNginxConfigByScope(req request.NginxConfigUpdate) error
|
||||
@ -594,6 +595,42 @@ func (w WebsiteService) DeleteWebsite(req request.WebsiteDelete) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) UpdateWebsiteDomain(req request.WebsiteDomainUpdate) error {
|
||||
domain, err := websiteDomainRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
domain.SSL = req.SSL
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(domain.WebsiteID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if website.Protocol == constant.ProtocolHTTPS {
|
||||
nginxFull, err := getNginxFull(&website)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
nginxConfig := nginxFull.SiteConfig
|
||||
config := nginxFull.SiteConfig.Config
|
||||
server := config.FindServers()[0]
|
||||
var params []string
|
||||
if domain.SSL {
|
||||
params = append(params, "ssl", "http2")
|
||||
}
|
||||
server.UpdateListen(strconv.Itoa(domain.Port), false, params...)
|
||||
if website.IPV6 {
|
||||
server.UpdateListen("[::]:"+strconv.Itoa(domain.Port), false, params...)
|
||||
}
|
||||
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxFull.Install.ContainerName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return websiteDomainRepo.Save(context.TODO(), &domain)
|
||||
}
|
||||
|
||||
func (w WebsiteService) CreateWebsiteDomain(create request.WebsiteDomainCreate) ([]model.WebsiteDomain, error) {
|
||||
var (
|
||||
domainModels []model.WebsiteDomain
|
||||
@ -929,17 +966,25 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
||||
if !req.Enable {
|
||||
website.Protocol = constant.ProtocolHTTP
|
||||
website.WebsiteSSLID = 0
|
||||
//httpsPort := req.HttpsPort
|
||||
//if len(httpsPort) == 0 {
|
||||
// _, httpsPort, err = getAppInstallPort(constant.AppOpenresty)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//}
|
||||
//httpsPortStr := strconv.Itoa(httpsPort)
|
||||
//if err = deleteListenAndServerName(website, []string{httpsPortStr, "[::]:" + httpsPortStr}, []string{}); err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
httpsPorts, err := getHttpsPort(&website)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(httpsPorts) == 1 && httpsPorts[0] == nginxInstall.HttpsPort {
|
||||
httpsPortStr := strconv.Itoa(httpsPorts[0])
|
||||
if err = deleteListenAndServerName(website, []string{httpsPortStr, "[::]:" + httpsPortStr}, []string{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
for _, port := range httpsPorts {
|
||||
httpsPortStr := strconv.Itoa(port)
|
||||
if err = removeSSLListen(website, []string{httpsPortStr}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nginxParams := getNginxParamsFromStaticFile(dto.SSL, nil)
|
||||
nginxParams = append(nginxParams,
|
||||
dto.NginxParam{
|
||||
|
@ -460,7 +460,7 @@ func addListenAndServerName(website model.Website, domains []model.WebsiteDomain
|
||||
if website.Protocol == constant.ProtocolHTTPS && domain.SSL {
|
||||
params = append(params, "ssl", "http2")
|
||||
}
|
||||
server.AddListen(strconv.Itoa(domain.Port), false, params...)
|
||||
server.UpdateListen(strconv.Itoa(domain.Port), false, params...)
|
||||
if website.IPV6 {
|
||||
server.UpdateListen("[::]:"+strconv.Itoa(domain.Port), false, params...)
|
||||
}
|
||||
@ -495,6 +495,26 @@ func deleteListenAndServerName(website model.Website, binds []string, domains []
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxFull.Install.ContainerName)
|
||||
}
|
||||
|
||||
func removeSSLListen(website model.Website, binds []string) error {
|
||||
nginxFull, err := getNginxFull(&website)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
nginxConfig := nginxFull.SiteConfig
|
||||
config := nginxFull.SiteConfig.Config
|
||||
server := config.FindServers()[0]
|
||||
for _, bind := range binds {
|
||||
server.UpdateListen(bind, false)
|
||||
if website.IPV6 {
|
||||
server.UpdateListen("[::]:"+bind, false)
|
||||
}
|
||||
}
|
||||
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxFull.Install.ContainerName)
|
||||
}
|
||||
|
||||
func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
|
||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey(constant.AppOpenresty))
|
||||
if err != nil {
|
||||
|
@ -28,6 +28,7 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
websiteRouter.GET("/domains/:websiteId", baseApi.GetWebDomains)
|
||||
websiteRouter.POST("/domains/del", baseApi.DeleteWebDomain)
|
||||
websiteRouter.POST("/domains", baseApi.CreateWebDomain)
|
||||
websiteRouter.POST("/domains/update", baseApi.UpdateWebDomain)
|
||||
|
||||
websiteRouter.GET("/:id/config/:type", baseApi.GetWebsiteNginx)
|
||||
websiteRouter.POST("/config", baseApi.GetNginxConfig)
|
||||
|
@ -123,6 +123,7 @@ export namespace Website {
|
||||
port: number;
|
||||
id: number;
|
||||
domain: string;
|
||||
ssl: boolean;
|
||||
}
|
||||
|
||||
export interface DomainCreate {
|
||||
@ -130,6 +131,11 @@ export namespace Website {
|
||||
domains: SubDomain[];
|
||||
}
|
||||
|
||||
export interface DomainUpdate {
|
||||
id: number;
|
||||
ssl: boolean;
|
||||
}
|
||||
|
||||
interface SubDomain {
|
||||
domain: string;
|
||||
port: number;
|
||||
|
@ -62,6 +62,10 @@ export const CreateDomain = (req: Website.DomainCreate) => {
|
||||
return http.post<any>(`/websites/domains`, req);
|
||||
};
|
||||
|
||||
export const UpdateDomain = (req: Website.DomainUpdate) => {
|
||||
return http.post<any>(`/websites/domains/update`, req);
|
||||
};
|
||||
|
||||
export const GetNginxConfig = (req: Website.NginxScopeReq) => {
|
||||
return http.post<Website.NginxScopeConfig>(`/websites/config`, req);
|
||||
};
|
||||
|
@ -2132,6 +2132,8 @@ const message = {
|
||||
enableSSLHelper: 'Failure to enable will not affect the creation of the website',
|
||||
batchAdd: 'Batch Add Domains',
|
||||
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',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Short tag support',
|
||||
|
@ -1982,6 +1982,7 @@ const message = {
|
||||
enableSSLHelper: '開啟失敗不會影響網站創建',
|
||||
batchAdd: '批量添加域名',
|
||||
generateDomain: '生成',
|
||||
domainSSLHelper: '非 443 端口開啟 SSL 會導致 443 端口移除監聽,如需 443 端口繼續監聽,請添加域名:443',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短標簽支持',
|
||||
|
@ -1984,6 +1984,7 @@ const message = {
|
||||
enableSSLHelper: '开启失败不会影响网站创建',
|
||||
batchAdd: '批量添加域名',
|
||||
generateDomain: '生成',
|
||||
domainSSLHelper: '非 443 端口开启 SSL 会导致 443 端口去掉监听,如需 443 端口继续监听,请添加域名:443',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短标签支持',
|
||||
|
@ -2,6 +2,7 @@
|
||||
<ComplexTable :data="data" @search="search" v-loading="loading" :heightDiff="400">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain @click="openCreate">{{ $t('website.addDomain') }}</el-button>
|
||||
<el-text type="info" class="!ml-2">{{ $t('website.domainSSLHelper') }}</el-text>
|
||||
</template>
|
||||
<el-table-column width="30px">
|
||||
<template #default="{ row }">
|
||||
@ -10,6 +11,11 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('website.domain')" prop="domain"></el-table-column>
|
||||
<el-table-column :label="$t('commons.table.port')" prop="port"></el-table-column>
|
||||
<el-table-column :label="'SSL'" prop="ssl">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.ssl" @change="update(row)" :disabled="row.port == 80" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:buttons="buttons"
|
||||
@ -25,12 +31,13 @@
|
||||
<script lang="ts" setup>
|
||||
import Domain from './create/index.vue';
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { DeleteDomain, GetWebsite, ListDomains } from '@/api/modules/website';
|
||||
import { DeleteDomain, GetWebsite, ListDomains, UpdateDomain } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { Promotion } from '@element-plus/icons-vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { CheckAppInstalled } from '@/api/modules/app';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const props = defineProps({
|
||||
@ -126,6 +133,16 @@ const onCheck = async () => {
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
const update = async (row: Website.Domain) => {
|
||||
try {
|
||||
await UpdateDomain({
|
||||
id: row.id,
|
||||
ssl: row.ssl,
|
||||
});
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
} catch {}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search(id.value);
|
||||
getWebsite(id.value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user