feat: 修改安全入口页特征样式 (#5159)

pull/5164/head
ssongliu 2024-05-27 11:32:54 +08:00 committed by GitHub
parent 41bc8b634b
commit c39f029808
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 187 additions and 172 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/middleware"
"github.com/1Panel-dev/1Panel/backend/utils/captcha"
"github.com/1Panel-dev/1Panel/backend/utils/qqwry"
"github.com/gin-gonic/gin"
@ -113,21 +114,12 @@ func (b *BaseApi) Captcha(c *gin.Context) {
// @Router /auth/issafety [get]
func (b *BaseApi) CheckIsSafety(c *gin.Context) {
code := c.DefaultQuery("code", "")
status, err := authService.CheckIsSafety(code)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
isSafe := authService.CheckIsSafety(code)
if !isSafe {
helper.ErrResponse(c, middleware.LoadErrCode("err-entrance"))
return
}
helper.SuccessWithData(c, status)
}
func (b *BaseApi) GetResponsePage(c *gin.Context) {
pageCode, err := authService.GetResponsePage()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, pageCode)
helper.SuccessWithOutData(c)
}
// @Tags Auth

View File

@ -133,3 +133,8 @@ func CheckBind(req interface{}, c *gin.Context) error {
}
return nil
}
func ErrResponse(ctx *gin.Context, code int) {
ctx.JSON(code, nil)
ctx.Abort()
}

View File

@ -19,8 +19,7 @@ import (
type AuthService struct{}
type IAuthService interface {
CheckIsSafety(code string) (string, error)
GetResponsePage() (string, error)
CheckIsSafety(code string) bool
VerifyCode(code string) (bool, error)
Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error)
LogOut(c *gin.Context) error
@ -173,24 +172,16 @@ func (u *AuthService) VerifyCode(code string) (bool, error) {
return hmac.Equal([]byte(setting.Value), []byte(code)), nil
}
func (u *AuthService) CheckIsSafety(code string) (string, error) {
func (u *AuthService) CheckIsSafety(code string) bool {
status, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
if err != nil {
return "", err
return true
}
if len(status.Value) == 0 {
return "disable", nil
return true
}
if status.Value == code {
return "pass", nil
return true
}
return "unpass", nil
}
func (u *AuthService) GetResponsePage() (string, error) {
pageCode, err := settingRepo.Get(settingRepo.WithByKey("NoAuthSetting"))
if err != nil {
return "", err
}
return pageCode.Value, nil
return false
}

View File

@ -8,16 +8,14 @@ const (
CodeSuccess = 200
CodeErrBadRequest = 400
CodeErrUnauthorized = 401
CodeErrUnSafety = 402
CodeErrForbidden = 403
CodeErrNotFound = 404
CodePasswordExpired = 405
CodeAuth = 406
CodeGlobalLoading = 407
CodeErrIP = 408
CodeErrDomain = 409
CodeErrInternalServer = 500
CodeErrHeader = 406
CodeErrIP = 310
CodeErrDomain = 311
CodeErrEntrance = 312
CodePasswordExpired = 313
CodeErrXpack = 410
)

View File

@ -4,7 +4,6 @@ import (
"fmt"
"net/http"
v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/i18n"
"github.com/1Panel-dev/1Panel/backend/middleware"
@ -64,8 +63,6 @@ func Routers() *gin.Engine {
PublicGroup.GET("/health", func(c *gin.Context) {
c.JSON(200, "ok")
})
baseApi := v1.ApiGroupApp.BaseApi
PublicGroup.GET("/api/v1/respagecode", baseApi.GetResponsePage)
PublicGroup.Use(gzip.Gzip(gzip.DefaultCompression))
setWebStatic(PublicGroup)
}

View File

@ -1,7 +1,6 @@
package middleware
import (
"errors"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
@ -29,7 +28,7 @@ func BindDomain() gin.HandlerFunc {
}
if domains != status.Value {
helper.ErrorWithDetail(c, constant.CodeErrDomain, constant.ErrTypeInternalServer, errors.New("domain not allowed"))
helper.ErrResponse(c, LoadErrCode("err-domain"))
return
}
c.Next()

View File

@ -0,0 +1,42 @@
package middleware
import (
"net/http"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/constant"
)
func LoadErrCode(errInfo string) int {
settingRepo := repo.NewISettingRepo()
codeVal, err := settingRepo.Get(settingRepo.WithByKey("NoAuthSetting"))
if err != nil {
return 500
}
switch codeVal.Value {
case "400":
return http.StatusBadRequest
case "401":
return http.StatusUnauthorized
case "403":
return http.StatusForbidden
case "404":
return http.StatusFound
case "408":
return http.StatusRequestTimeout
case "416":
return http.StatusRequestedRangeNotSatisfiable
default:
if errInfo == "err-ip" {
return constant.CodeErrIP
}
if errInfo == "err-domain" {
return constant.CodeErrDomain
}
if errInfo == "err-entrance" {
return constant.CodeErrEntrance
}
return http.StatusOK
}
}

View File

@ -1,7 +1,6 @@
package middleware
import (
"errors"
"net"
"strings"
@ -35,7 +34,7 @@ func WhiteAllow() gin.HandlerFunc {
return
}
}
helper.ErrorWithDetail(c, constant.CodeErrIP, constant.ErrTypeInternalServer, errors.New("IP address not allowed"))
helper.ErrResponse(c, LoadErrCode("err-ip"))
}
}

View File

@ -33,11 +33,11 @@ func PasswordExpired() gin.HandlerFunc {
loc, _ := time.LoadLocation(common.LoadTimeZone())
expiredTime, err := time.ParseInLocation("2006-01-02 15:04:05", extime.Value, loc)
if err != nil {
helper.ErrorWithDetail(c, constant.CodePasswordExpired, constant.ErrTypePasswordExpired, err)
helper.ErrResponse(c, constant.CodePasswordExpired)
return
}
if time.Now().After(expiredTime) {
helper.ErrorWithDetail(c, constant.CodePasswordExpired, constant.ErrTypePasswordExpired, nil)
helper.ErrResponse(c, constant.CodePasswordExpired)
return
}
c.Next()

View File

@ -41,6 +41,7 @@ class RequestHttp {
this.service.interceptors.response.use(
(response: AxiosResponse) => {
globalStore.errStatus = '';
const { data } = response;
if (data.code == ResultEnum.OVERDUE || data.code == ResultEnum.FORBIDDEN) {
globalStore.setLogStatus(false);
@ -50,26 +51,6 @@ class RequestHttp {
});
return Promise.reject(data);
}
if (data.code == ResultEnum.EXPIRED) {
router.push({ name: 'Expired' });
return data;
}
if (data.code == ResultEnum.ERRIP) {
globalStore.setLogStatus(false);
router.push({
name: 'entrance',
params: { code: 'err-ip' },
});
return Promise.reject(data);
}
if (data.code == ResultEnum.ERRDOMAIN) {
globalStore.setLogStatus(false);
router.push({
name: 'entrance',
params: { code: 'err-domain' },
});
return Promise.reject(data);
}
if (data.code == ResultEnum.ERRXPACK) {
globalStore.isProductPro = false;
window.location.reload();
@ -94,13 +75,50 @@ class RequestHttp {
return data;
},
async (error: AxiosError) => {
globalStore.errStatus = '';
const { response } = error;
if (error.message.indexOf('timeout') !== -1) MsgError('');
if (response) {
checkStatus(
response.status,
response.data && response.data['message'] ? response.data['message'] : '',
);
switch (response.status) {
case 310:
globalStore.errStatus = 'err-ip';
router.push({
name: 'entrance',
params: { code: globalStore.entrance },
});
return;
case 311:
globalStore.errStatus = 'err-domain';
router.push({
name: 'entrance',
params: { code: globalStore.entrance },
});
return;
case 312:
globalStore.errStatus = 'err-entrance';
router.push({
name: 'entrance',
params: { code: globalStore.entrance },
});
return;
case 313:
router.push({ name: 'Expired' });
return;
case 500:
case 400:
case 407:
checkStatus(
response.status,
response.data && response.data['message'] ? response.data['message'] : '',
);
return;
default:
globalStore.errStatus = 'code-' + response.status;
router.push({
name: 'entrance',
params: { code: globalStore.entrance },
});
}
}
if (!window.navigator.onLine) router.replace({ path: '/500' });
return Promise.reject(error);

View File

@ -21,10 +21,6 @@ export const checkIsSafety = (code: string) => {
return http.get<string>(`/auth/issafety?code=${code}`);
};
export const getResponsePage = () => {
return http.get<string>(`/respagecode`);
};
export const checkIsDemo = () => {
return http.get<boolean>('/auth/demo');
};

View File

@ -1,10 +1,16 @@
<template>
<div class="not-container">
<img src="@/assets/images/error.svg" class="not-img" :alt="props.code" />
<div class="not-detail">
<h2>{{ props.code }}</h2>
<h4>{{ $t('setting.' + 'error' + props.code) }}</h4>
</div>
<div>
<body>
<div>
<el-row type="flex" justify="center">
<h1>{{ loadErrInfo() }}</h1>
</el-row>
</div>
<hr />
<div>
<el-row type="flex" justify="center"><span>nginx</span></el-row>
</div>
</body>
</div>
</template>
@ -12,37 +18,24 @@
const props = defineProps({
code: String,
});
const loadErrInfo = () => {
switch (props.code) {
case '401':
return '401 Unauthorized';
case '403':
return '403 Forbidden';
case '404':
return '403 Not Found';
case '408':
return '408 Request Timeout';
case '416':
return '408 Requested Not Satisfiable';
}
};
</script>
<style scoped lang="scss">
.not-container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
.not-img {
margin-top: 300px;
}
.not-detail {
margin-top: 300px;
display: flex;
flex-direction: column;
h2,
h4 {
padding: 0;
margin: 0;
}
h2 {
font-size: 60px;
color: #434e59;
}
h4 {
margin: 30px 0 20px;
font-size: 19px;
font-weight: normal;
color: #848587;
}
}
.container {
margin-left: 40%;
}
</style>

View File

@ -1,14 +1,15 @@
export enum ResultEnum {
SUCCESS = 200,
ERRIP = 310,
ERRDOMAIN = 311,
UNSAFETY = 312,
EXPIRED = 313,
ERROR = 500,
OVERDUE = 401,
UNSAFETY = 402,
FORBIDDEN = 403,
EXPIRED = 405,
ERRAUTH = 406,
ERRGLOBALLOADDING = 407,
ERRIP = 408,
ERRDOMAIN = 409,
ERRXPACK = 410,
TIMEOUT = 20000,
TYPE = 'success',

View File

@ -34,6 +34,8 @@ export interface GlobalState {
isProductPro: boolean;
productProExpires: number;
errStatus: string;
}
export interface MenuState {

View File

@ -38,6 +38,8 @@ const GlobalStore = defineStore({
isProductPro: false,
productProExpires: 0,
errStatus: '',
}),
getters: {
isDarkTheme: (state) => state.themeConfig.theme === 'dark' || state.themeConfig.theme === 'dark-gold',

View File

@ -18,22 +18,20 @@
</div>
<div v-else>
<div v-if="!pageCode || pageCode === '200'">
<div v-if="errStatus === 'err-unsafe'">
<UnSafe />
</div>
<div v-if="errStatus === 'err-ip'">
<ErrIP />
</div>
<div v-if="errStatus === 'err-domain'">
<ErrDomain />
</div>
<div v-if="errStatus === 'not-found'">
<ErrFound />
</div>
<div v-if="errStatus === 'err-unsafe'">
<UnSafe />
</div>
<div v-else>
<ErrCode :code="pageCode" />
<div v-if="errStatus === 'err-ip'">
<ErrIP />
</div>
<div v-if="errStatus === 'err-domain'">
<ErrDomain />
</div>
<div v-if="errStatus.indexOf('code-') !== -1">
<ErrCode :code="errStatus.replaceAll('code-', '')" />
</div>
<div v-if="errStatus === 'not-found'">
<ErrFound />
</div>
</div>
</div>
@ -41,7 +39,7 @@
</template>
<script setup lang="ts" name="login">
import { checkIsSafety, getResponsePage } from '@/api/modules/auth';
import { checkIsSafety } from '@/api/modules/auth';
import LoginForm from '../components/login-form.vue';
import UnSafe from '@/components/error-message/unsafe.vue';
import ErrIP from '@/components/error-message/err_ip.vue';
@ -54,8 +52,7 @@ import { getXpackSetting, initFavicon } from '@/utils/xpack';
const globalStore = GlobalStore();
const screenWidth = ref(null);
const errStatus = ref();
const pageCode = ref('');
const errStatus = ref('');
const loading = ref();
const mySafetyCode = defineProps({
@ -66,52 +63,35 @@ const mySafetyCode = defineProps({
});
const getStatus = async () => {
let info = globalStore.errStatus;
if (info?.startsWith('err-') || info?.startsWith('code-')) {
errStatus.value = info;
return;
}
let code = mySafetyCode.code;
globalStore.entrance = code;
loading.value = true;
await getResponsePage()
.then(async (res) => {
pageCode.value = res.data;
if (code === 'err-ip' || code === 'err-domain') {
errStatus.value = code;
loading.value = false;
return;
}
await checkIsSafety(code)
.then((safeRes) => {
if (safeRes.data === 'unpass') {
loading.value = false;
errStatus.value = 'err-unsafe';
return;
}
if (safeRes.data === 'disable') {
if (code !== '') {
errStatus.value = 'not-found';
loading.value = false;
return;
}
}
globalStore.entrance = code;
errStatus.value = '';
loadDataFromXDB();
})
.catch((errRes) => {
pageCode.value = pageCode.value || '200';
loading.value = false;
if (errRes?.code === 408) {
errStatus.value = 'err-ip';
return;
}
if (errRes?.code === 409) {
errStatus.value = 'err-domain';
return;
}
errStatus.value = 'err-unsafe';
});
})
.catch(() => {
pageCode.value = '200';
errStatus.value = 'err-found';
await checkIsSafety(code)
.then(() => {
loading.value = false;
errStatus.value = '';
loadDataFromXDB();
})
.catch((err) => {
loading.value = false;
switch (err.response.status) {
case 310:
errStatus.value = 'err-ip';
return;
case 311:
errStatus.value = 'err-domain';
return;
case 312:
errStatus.value = 'err-entrance';
return;
default:
errStatus.value = 'code-' + err.response.status;
}
});
};