diff --git a/pkg/api/authorizations.go b/pkg/api/authorizations.go
index 8189716e..e6989e9e 100644
--- a/pkg/api/authorizations.go
+++ b/pkg/api/authorizations.go
@@ -190,5 +190,11 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeByRecoveryCodeHandler(c *core.Cont
c.SetTokenClaims(claims)
log.InfofWithRequestId(c, "[authorizations.TwoFactorAuthorizeByRecoveryCodeHandler] user \"uid:%d\" has authorized two factor via recovery code \"%s\", token will be expired at %d", user.Uid, credential.RecoveryCode, claims.ExpiresAt)
- return token, nil
+
+ authResp := &models.AuthResponse{
+ Token : token,
+ Need2FA: false,
+ }
+
+ return authResp, nil
}
diff --git a/pkg/errs/twofactor_authorization.go b/pkg/errs/twofactor_authorization.go
index 6511c44d..368228e8 100644
--- a/pkg/errs/twofactor_authorization.go
+++ b/pkg/errs/twofactor_authorization.go
@@ -4,8 +4,8 @@ import "net/http"
var (
ErrPasscodeInvalid = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 0, http.StatusUnauthorized, "passcode is invalid")
- ErrTwoFactorRecoveryCodeInvalid = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 1, http.StatusUnauthorized, "two factor recovery code is invalid")
+ ErrTwoFactorRecoveryCodeInvalid = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 1, http.StatusUnauthorized, "two factor backup code is invalid")
ErrTwoFactorIsNotEnabled = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 2, http.StatusBadRequest, "two factor is not enabled")
ErrTwoFactorAlreadyEnabled = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 3, http.StatusBadRequest, "two factor has already been enabled")
- ErrTwoFactorRecoveryCodeNotExist = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 4, http.StatusUnauthorized, "two factor recovery code does not exist")
+ ErrTwoFactorRecoveryCodeNotExist = NewNormalError(NORMAL_SUBCATEGORY_TWOFACTOR, 4, http.StatusUnauthorized, "two factor backup code does not exist")
)
diff --git a/src/lib/services.js b/src/lib/services.js
index b4cfed65..bb6e3f73 100644
--- a/src/lib/services.js
+++ b/src/lib/services.js
@@ -49,6 +49,15 @@ export default {
}
});
},
+ authorize2FAByBackupCode: ({ recoveryCode, token }) => {
+ return axios.post('2fa/recovery.json', {
+ recoveryCode
+ }, {
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ });
+ },
logout: () => {
return axios.get('v1/logout.json');
},
diff --git a/src/locales/en.js b/src/locales/en.js
index c783f552..952bb681 100644
--- a/src/locales/en.js
+++ b/src/locales/en.js
@@ -5,6 +5,7 @@ export default {
}
},
'error': {
+ 'system error': 'System Error',
'unauthorized access': 'Unauthorized access',
'token is expired': 'Token is expired',
'token is invalid': 'Token is invalid',
@@ -26,10 +27,10 @@ export default {
'login name or password is invalid': 'Login name or password is invalid',
'login name or password is wrong': 'Login name or password is wrong',
'passcode is invalid': 'Passcode is invalid',
- 'two factor recovery code is invalid': 'Two factor recovery code is invalid',
+ 'two factor backup code is invalid': 'Two factor backup code is invalid',
'two factor is not enabled': 'Two factor is not enabled',
'two factor has already been enabled': 'Two factor has already been enabled',
- 'two factor recovery code does not exist': 'Two factor recovery code does not exist',
+ 'two factor backup code does not exist': 'Two factor backup code does not exist',
},
'OK': 'OK',
'Cancel': 'Cancel',
@@ -53,10 +54,13 @@ export default {
'Unable to login': 'Unable to login',
'Two-Factor Authentication': 'Two-Factor Authentication',
'Passcode': 'Passcode',
+ 'Backup Code': 'Backup Code',
'Verify': 'Verify',
'Please input passcode': 'Please input passcode',
+ 'Please input backup code': 'Please input backup code',
'Unable to verify': 'Unable to verify',
'Use a backup code': 'Use a backup code',
+ 'Use a passcode': 'Use a passcode',
'Language': 'Language',
'Log Out': 'Log Out',
'Are you sure you want to log out?': 'Are you sure you want to log out?',
diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js
index 8f3d0f22..8a1a1fff 100644
--- a/src/locales/zh_Hans.js
+++ b/src/locales/zh_Hans.js
@@ -5,6 +5,7 @@ export default {
}
},
'error': {
+ 'system error': '系统错误',
'unauthorized access': '未授权的登录',
'token is expired': '认证令牌已过期',
'token is invalid': '认证令牌无效',
@@ -26,10 +27,10 @@ export default {
'login name or password is invalid': '登录名或密码无效',
'login name or password is wrong': '登录名或密码错误',
'passcode is invalid': '验证码无效',
- 'two factor recovery code is invalid': '两步验证恢复口令无效',
+ 'two factor backup code is invalid': '两步验证备用码无效',
'two factor is not enabled': '两步验证没有启用',
'two factor has already been enabled': '两步验证已经启用',
- 'two factor recovery code does not exist': '两步验证恢复口令不存在',
+ 'two factor backup code does not exist': '两步验证备用码不存在',
},
'OK': '确定',
'Cancel': '取消',
@@ -53,10 +54,13 @@ export default {
'Unable to login': '无法登录',
'Two-Factor Authentication': '两步验证',
'Passcode': '验证码',
+ 'Backup Code': '备用码',
'Verify': '验证',
'Please input passcode': '请输入验证码',
+ 'Please input backup code': '请输入备用码',
'Unable to verify': '无法验证',
'Use a backup code': '使用备用码',
+ 'Use a passcode': '使用验证码',
'Language': '语言',
'Log Out': '退出登录',
'Are you sure you want to log out?': '您确定是否要退出登录?',
diff --git a/src/views/mobile/Login.vue b/src/views/mobile/Login.vue
index f9b805d9..ceb9aae4 100644
--- a/src/views/mobile/Login.vue
+++ b/src/views/mobile/Login.vue
@@ -57,14 +57,23 @@
type="number"
outline
clear-button
+ v-if="twoFAVerifyType === 'passcode'"
:placeholder="$t('Passcode')"
:value="passcode"
@input="passcode = $event.target.value"
>
+