diff --git a/pkg/api/authorizations.go b/pkg/api/authorizations.go index 0a4a9c7e..2f517346 100644 --- a/pkg/api/authorizations.go +++ b/pkg/api/authorizations.go @@ -50,9 +50,18 @@ func (a *AuthorizationsApi) AuthorizeHandler(c *core.Context) (interface{}, *err } if settings.Container.Current.EnableUserForceVerifyEmail && !user.EmailVerified { + hasValidEmailVerifyToken, err := a.tokens.ExistsValidTokenByType(c, user.Uid, core.USER_TOKEN_TYPE_EMAIL_VERIFY) + + if err != nil { + log.WarnfWithRequestId(c, "[authorizations.AuthorizeHandler] failed check whether user \"uid:%d\" has valid verify email token, because %s", user.Uid, err.Error()) + hasValidEmailVerifyToken = false + } + log.WarnfWithRequestId(c, "[authorizations.AuthorizeHandler] login failed for user \"%s\", because user has not verified email", credential.LoginName) - return nil, errs.NewErrorWithContext(errs.ErrEmailIsNotVerified, map[string]string{ - "email": user.Email, + + return nil, errs.NewErrorWithContext(errs.ErrEmailIsNotVerified, map[string]any{ + "email": user.Email, + "hasValidEmailVerifyToken": hasValidEmailVerifyToken, }) } diff --git a/pkg/services/tokens.go b/pkg/services/tokens.go index ca402a28..b17e57b2 100644 --- a/pkg/services/tokens.go +++ b/pkg/services/tokens.go @@ -182,6 +182,17 @@ func (s *TokenService) DeleteTokensByType(c *core.Context, uid int64, tokenType }) } +// ExistsValidTokenByType returns whether the given token type exists +func (s *TokenService) ExistsValidTokenByType(c *core.Context, uid int64, tokenType core.TokenType) (bool, error) { + if uid <= 0 { + return false, errs.ErrUserIdInvalid + } + + now := time.Now().Unix() + + return s.TokenDB(uid).NewSession(c).Cols("uid", "user_token_id", "expired_unix_time").Where("uid=? AND token_type=? AND expired_unix_time>?", uid, tokenType, now).Exist(&models.TokenRecord{}) +} + // ParseFromTokenId returns token model according to token id func (s *TokenService) ParseFromTokenId(tokenId string) (*models.TokenRecord, error) { pairs := strings.Split(tokenId, ":") diff --git a/src/locales/en.js b/src/locales/en.js index b5362ed4..40109783 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -856,6 +856,7 @@ export default { 'Verifying...': 'Verifying...', 'Account activation link has been sent to your email address:': 'Account activation link has been sent to your email address:', ', If you don\'t receive the mail, fill password and click the button below to resend the verify mail.': ', If you don\'t receive the mail, fill password and click the button below to resend the verify mail.', + 'If you don\'t receive the mail, fill password and click the button below to resend the verify mail to:': 'If you don\'t receive the mail, fill password and click the button below to resend the verify mail to:', 'Resend Validation Email': 'Resend Validation Email', 'Validation email has been sent': 'Validation email has been sent', 'Unable to verify email': 'Unable to verify email', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index 2b2ee630..110bd664 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -856,6 +856,7 @@ export default { 'Verifying...': '正在验证...', 'Account activation link has been sent to your email address:': '账号激活链接已经发送到您的邮箱地址:', ', If you don\'t receive the mail, fill password and click the button below to resend the verify mail.': ',如果您没有收到邮件,输入密码并点击下方的按钮重新发送验证邮件。', + 'If you don\'t receive the mail, fill password and click the button below to resend the verify mail to:': '如果您没有收到邮件,输入密码并点击下方的按钮重新发送验证邮件到:', 'Resend Validation Email': '重发验证邮件', 'Validation email has been sent': '验证邮件已发送', 'Unable to verify email': '无法验证邮箱', diff --git a/src/router/desktop.js b/src/router/desktop.js index 1f4bc342..2e193f95 100644 --- a/src/router/desktop.js +++ b/src/router/desktop.js @@ -165,7 +165,8 @@ const router = createRouter({ component: VerifyEmailPage, props: route => ({ email: route.query.email, - token: route.query.token + token: route.query.token, + hasValidEmailVerifyToken: route.query.emailSent === 'true' }) }, { diff --git a/src/views/desktop/LoginPage.vue b/src/views/desktop/LoginPage.vue index 194be69a..a293d6bc 100644 --- a/src/views/desktop/LoginPage.vue +++ b/src/views/desktop/LoginPage.vue @@ -320,7 +320,7 @@ export default { self.logining = false; if (self.isUserVerifyEmailEnabled && error.error && error.error.errorCode === 201020 && error.error.context && error.error.context.email) { - self.$router.push('/verify_email?email=' + encodeURIComponent(error.error.context.email)); + self.$router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`); return; } diff --git a/src/views/desktop/VerifyEmailPage.vue b/src/views/desktop/VerifyEmailPage.vue index d1592622..f7380411 100644 --- a/src/views/desktop/VerifyEmailPage.vue +++ b/src/views/desktop/VerifyEmailPage.vue @@ -28,9 +28,11 @@
{{ errorMessage }}
{{ $t('Parameter Invalid') }}
- {{ $t('Account activation link has been sent to your email address:') }} - {{ email }} - {{ $t(', If you don\'t receive the mail, fill password and click the button below to resend the verify mail.') }} + {{ $t('Account activation link has been sent to your email address:') }} + {{ email }} + {{ $t(', If you don\'t receive the mail, fill password and click the button below to resend the verify mail.') }} + {{ $t('If you don\'t receive the mail, fill password and click the button below to resend the verify mail to:') }} + {{ email }}
@@ -135,7 +137,8 @@ import { export default { props: [ 'email', - 'token' + 'token', + 'hasValidEmailVerifyToken' ], data() { return {