This commit is contained in:
parent
20d30d5f23
commit
f6566c7aa9
@ -36,12 +36,12 @@ func GetAttachments(ctx *context.Context, w http.ResponseWriter, req *http.Reque
|
||||
|
||||
func Download(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
urlInfos := strings.Split(strings.Trim(req.URL.Path, "/"), "/")
|
||||
if len(urlInfos) != 5 {
|
||||
if len(urlInfos) != 4 || urlInfos[0] != "attachments" || urlInfos[1] != "download" {
|
||||
response.NewErrorResponse(response.ParamsError, "", "").FPrint(w)
|
||||
return
|
||||
}
|
||||
emailId := cast.ToInt(urlInfos[3])
|
||||
index := cast.ToInt(urlInfos[4])
|
||||
emailId := cast.ToInt(urlInfos[2])
|
||||
index := cast.ToInt(urlInfos[3])
|
||||
|
||||
fileName, content, err := attachments.GetAttachmentsByIndex(ctx, emailId, index)
|
||||
if err != nil {
|
||||
|
||||
@ -3,6 +3,7 @@ package controllers
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -12,6 +13,7 @@ import (
|
||||
"git.pcux.cn/xuans/Smail/config"
|
||||
"git.pcux.cn/xuans/Smail/db"
|
||||
"git.pcux.cn/xuans/Smail/dto/response"
|
||||
"git.pcux.cn/xuans/Smail/models"
|
||||
"git.pcux.cn/xuans/Smail/services/access"
|
||||
"git.pcux.cn/xuans/Smail/services/credentials"
|
||||
"git.pcux.cn/xuans/Smail/services/externalemail"
|
||||
@ -633,11 +635,31 @@ func BindExternalEmail(ctx *context.Context, w http.ResponseWriter, req *http.Re
|
||||
writeSecurityError(w, response.NeedLogin, "请先登录")
|
||||
return
|
||||
}
|
||||
if !ctx.RecentAuth {
|
||||
writeSecurityError(w, response.NoAccessPrivileges, "此操作需要最近十分钟内完成登录,请重新登录后再试")
|
||||
return
|
||||
}
|
||||
var input externalEmailRequest
|
||||
if err := decodeJSONRequest(w, req, &input); err != nil {
|
||||
writeSecurityError(w, response.ParamsError, "请求无效")
|
||||
return
|
||||
}
|
||||
normalizedEmail, err := externalemail.NormalizeEmail(input.Email)
|
||||
if err != nil {
|
||||
writeSecurityError(w, response.ParamsError, "外部邮箱绑定失败")
|
||||
return
|
||||
}
|
||||
owned, err := currentUserPrimaryEmail(ctx.UserID, normalizedEmail)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("check current user primary email failed")
|
||||
writeSecurityError(w, response.ServerError, "外部邮箱绑定失败")
|
||||
return
|
||||
}
|
||||
if owned {
|
||||
writeSecurityError(w, response.ParamsError, "不能将当前邮箱绑定为外部安全邮箱")
|
||||
return
|
||||
}
|
||||
input.Email = normalizedEmail
|
||||
item, err := securityRuntime.external.Bind(externalemail.BindRequest{UserID: ctx.UserID, Email: input.Email, Type: input.Type})
|
||||
if err != nil {
|
||||
writeSecurityError(w, response.ParamsError, "外部邮箱绑定失败")
|
||||
@ -652,6 +674,14 @@ func BindExternalEmail(ctx *context.Context, w http.ResponseWriter, req *http.Re
|
||||
response.NewSuccessResponse(map[string]any{"id": item.ID, "challenge_id": challenge.ID, "status": item.Status, "email": maskEmail(input.Email), "expires_at": challenge.ExpiresAt.UTC()}).FPrint(w)
|
||||
}
|
||||
|
||||
func currentUserPrimaryEmail(userID int, email string) (bool, error) {
|
||||
if db.Instance == nil || userID <= 0 {
|
||||
return false, errors.New("database is unavailable")
|
||||
}
|
||||
var binding models.UserEmail
|
||||
return db.Instance.Where("user_id = ? AND verified_at IS NOT NULL AND status != ? AND is_primary = 1 AND (address_canonical = ? OR LOWER(address) = ?)", userID, 3, email, email).Limit(1).Get(&binding)
|
||||
}
|
||||
|
||||
func VerifyExternalEmail(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
if ctx == nil || ctx.UserID <= 0 || securityRuntime.external == nil || securityRuntime.verification == nil {
|
||||
writeSecurityError(w, response.NeedLogin, "请先登录")
|
||||
|
||||
@ -193,7 +193,7 @@ func mustChangePasswordAllowedPath(path string) bool {
|
||||
|
||||
func publicSecurityPath(path string) bool {
|
||||
switch normalizedAPIPath(path) {
|
||||
case "/api/ping", "/api/login", "/api/security/login/verify", "/api/security/recovery/begin", "/api/security/recovery/verify", "/api/security/recovery/complete", "/api/security/recovery/webauthn/begin", "/api/security/recovery/webauthn/verify", "/api/security/webauthn/login/begin", "/api/security/webauthn/login/finish":
|
||||
case "/api/ping", "/api/login", "/api/security/login/verify", "/api/security/login/resend", "/api/security/recovery/begin", "/api/security/recovery/verify", "/api/security/recovery/complete", "/api/security/recovery/webauthn/begin", "/api/security/recovery/webauthn/verify", "/api/security/webauthn/login/begin", "/api/security/webauthn/login/finish":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
Loading…
Reference in New Issue
Block a user