Skip to content

Commit d8b1b77

Browse files
committed
fix: fallback to password login when mfa needs captcha
1 parent 24fc15b commit d8b1b77

4 files changed

Lines changed: 24 additions & 7 deletions

File tree

core/app/api/v2/auth.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/1Panel-dev/1Panel/core/buserr"
1313
"github.com/1Panel-dev/1Panel/core/constant"
1414
"github.com/1Panel-dev/1Panel/core/global"
15+
initauth "github.com/1Panel-dev/1Panel/core/init/auth"
1516
"github.com/1Panel-dev/1Panel/core/utils/captcha"
1617
"github.com/1Panel-dev/1Panel/core/utils/common"
1718
"github.com/gin-gonic/gin"
@@ -109,6 +110,12 @@ func (b *BaseApi) MFALogin(c *gin.Context) {
109110
go saveLoginLogs(c, wrapLoginErr(msgKey, err))
110111
if msgKey == "ErrMFA" {
111112
global.IPTracker.RecordFailure(ip)
113+
failures := initauth.GetMFASessionStore().RecordFailure(req.SessionID)
114+
if failures >= initauth.MFASessionMaxFailures {
115+
global.IPTracker.SetNeedCaptcha(ip)
116+
helper.BadAuth(c, "ErrCaptchaCode", nil)
117+
return
118+
}
112119
helper.BadAuth(c, msgKey, err)
113120
return
114121
}

core/app/service/auth.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance strin
114114
}
115115
success := mfa.ValidCode(info.Code, mfaInterval.Value, mfaSecret.Value)
116116
if !success {
117-
mfaSessions.RecordFailure(info.SessionID)
118117
return nil, "ErrMFA", nil
119118
}
120119
res, err := u.generateSession(c, session.Name)

core/init/auth/mfa_session.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,27 @@ func (s *mfaSessionStore) Delete(sessionID string) {
7676
delete(s.items, sessionID)
7777
}
7878

79-
func (s *mfaSessionStore) RecordFailure(sessionID string) bool {
79+
func (s *mfaSessionStore) RecordFailure(sessionID string) int {
8080
s.mu.Lock()
8181
defer s.mu.Unlock()
8282

8383
item, ok := s.items[sessionID]
8484
if !ok {
85-
return false
85+
return 0
8686
}
8787
if time.Now().After(item.ExpiresAt) {
8888
delete(s.items, sessionID)
89-
return false
89+
return 0
9090
}
9191

9292
item.Failures++
9393
if item.Failures >= MFASessionMaxFailures {
9494
delete(s.items, sessionID)
95-
return false
95+
return item.Failures
9696
}
9797

9898
s.items[sessionID] = item
99-
return true
99+
return item.Failures
100100
}
101101

102102
func (s *mfaSessionStore) cleanupExpiredLocked() {

frontend/src/views/login/components/login-form.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ const login = (formEl: FormInstance | undefined) => {
437437
mfaLoginForm.code = '';
438438
mfaShow.value = true;
439439
errMfaInfo.value = false;
440+
errCaptcha.value = false;
440441
nextTick(() => {
441442
mfaLoginRef.value?.focus();
442443
});
@@ -485,6 +486,7 @@ const mfaLogin = async (auto: boolean) => {
485486
if ((!auto && mfaLoginForm.code) || (auto && mfaLoginForm.code.length === 6)) {
486487
isLoggingIn = true;
487488
try {
489+
errMfaInfo.value = false;
488490
await mfaLoginApi(mfaLoginForm);
489491
globalStore.setLogStatus(true);
490492
menuStore.setMenuList([]);
@@ -498,14 +500,23 @@ const mfaLogin = async (auto: boolean) => {
498500
document.onkeydown = null;
499501
} catch (res) {
500502
if (res.code === 401) {
501-
if (res.message === 'ErrMFA') {
503+
if (res.message === 'ErrCaptchaCode') {
504+
globalStore.ignoreCaptcha = false;
505+
mfaLoginForm.code = '';
506+
mfaShow.value = false;
507+
loginVerify();
508+
nextTick(() => {
509+
userNameRef.value?.focus();
510+
});
511+
} else if (res.message === 'ErrMFA') {
502512
errMfaInfo.value = true;
503513
} else if (res.message) {
504514
MsgError(res.message);
505515
}
506516
isLoggingIn = false;
507517
return;
508518
}
519+
loginVerify();
509520
} finally {
510521
isLoggingIn = false;
511522
}

0 commit comments

Comments
 (0)