@@ -643,6 +643,8 @@ func main() {
|
||||
adminAPI.POST("/user/disable-2fa", adminHandler.DisableTwoFactor)
|
||||
adminAPI.POST("/user/update-referral", adminHandler.UpdateReferral)
|
||||
adminAPI.POST("/user/disable-passkeys", adminHandler.RemovePasskeys)
|
||||
adminAPI.POST("/user/update-email-mfa", adminHandler.UpdateEmailMFA)
|
||||
adminAPI.POST("/user/add-ott", adminHandler.AddOtt)
|
||||
adminAPI.POST("/user/close-family", adminHandler.CloseFamily)
|
||||
adminAPI.PUT("/user/change-email", adminHandler.ChangeEmail)
|
||||
adminAPI.DELETE("/user/delete", adminHandler.DeleteUser)
|
||||
|
||||
@@ -3,6 +3,7 @@ package ente
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetEmailsFromHashesRequest represents a request to convert hashes
|
||||
@@ -23,8 +24,29 @@ type UpdateReferralCodeRequest struct {
|
||||
Code string `json:"code" binding:"required"`
|
||||
}
|
||||
|
||||
type AdminOttReq struct {
|
||||
Email string `json:"email" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
App App `json:"app" binding:"required"`
|
||||
ExpiryTime int64 `json:"expiryTime" binding:"required"`
|
||||
}
|
||||
|
||||
func (a AdminOttReq) Validate() error {
|
||||
if !a.App.IsValid() {
|
||||
return errors.New("invalid app")
|
||||
}
|
||||
if a.ExpiryTime < time.Now().UnixMicro() {
|
||||
return errors.New("expiry time should be in future")
|
||||
}
|
||||
if len(a.Code) < 6 {
|
||||
return errors.New("invalid code length, should be at least 6 digit")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AdminOpsForUserRequest struct {
|
||||
UserID int64 `json:"userID" binding:"required"`
|
||||
UserID int64 `json:"userID" binding:"required"`
|
||||
EmailMFA *bool `json:"emailMFA"`
|
||||
}
|
||||
|
||||
// ReQueueItemRequest puts an item back into the queue for processing.
|
||||
|
||||
@@ -281,6 +281,67 @@ func (h *AdminHandler) RemovePasskeys(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
}
|
||||
|
||||
func (h *AdminHandler) UpdateEmailMFA(c *gin.Context) {
|
||||
var request ente.AdminOpsForUserRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
handler.Error(c, stacktrace.Propagate(ente.ErrBadRequest, "Bad request"))
|
||||
return
|
||||
}
|
||||
if request.EmailMFA == nil {
|
||||
handler.Error(c, stacktrace.Propagate(ente.NewBadRequestWithMessage("emailMFA is required"), ""))
|
||||
return
|
||||
}
|
||||
|
||||
go h.DiscordController.NotifyAdminAction(
|
||||
fmt.Sprintf("Admin (%d) updating email mfa (%v) for account %d", auth.GetUserID(c.Request.Header), request.EmailMFA, request.UserID))
|
||||
logger := logrus.WithFields(logrus.Fields{
|
||||
"user_id": request.UserID,
|
||||
"admin_id": auth.GetUserID(c.Request.Header),
|
||||
"req_id": requestid.Get(c),
|
||||
"req_ctx": "disable_email_mfa",
|
||||
})
|
||||
logger.Info("Initiate remove passkeys")
|
||||
err := h.UserController.UpdateEmailMFA(c, request.UserID, *request.EmailMFA)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Failed to update email mfa")
|
||||
handler.Error(c, stacktrace.Propagate(err, ""))
|
||||
return
|
||||
}
|
||||
logger.Info("Email MFA successfully updated")
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
}
|
||||
|
||||
func (h *AdminHandler) AddOtt(c *gin.Context) {
|
||||
var request ente.AdminOttReq
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
handler.Error(c, stacktrace.Propagate(ente.ErrBadRequest, "Bad request"))
|
||||
return
|
||||
}
|
||||
if err := request.Validate(); err != nil {
|
||||
handler.Error(c, stacktrace.Propagate(ente.NewBadRequestWithMessage(err.Error()), "Bad request"))
|
||||
return
|
||||
}
|
||||
|
||||
go h.DiscordController.NotifyAdminAction(
|
||||
fmt.Sprintf("Admin (%d) adding custom ott", auth.GetUserID(c.Request.Header)))
|
||||
logger := logrus.WithFields(logrus.Fields{
|
||||
"user_id": request.Email,
|
||||
"code": request.Code,
|
||||
"admin_id": auth.GetUserID(c.Request.Header),
|
||||
"req_id": requestid.Get(c),
|
||||
"req_ctx": "custom_ott",
|
||||
})
|
||||
|
||||
err := h.UserController.AddAdminOtt(request)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Failed to add ott")
|
||||
handler.Error(c, stacktrace.Propagate(err, ""))
|
||||
return
|
||||
}
|
||||
logger.Info("Success added ott")
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
}
|
||||
|
||||
func (h *AdminHandler) UpdateFeatureFlag(c *gin.Context) {
|
||||
var request ente.AdminUpdateKeyValueRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
|
||||
@@ -134,6 +134,20 @@ func (c *UserController) SendEmailOTT(context *gin.Context, email string, purpos
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *UserController) AddAdminOtt(req ente.AdminOttReq) error {
|
||||
emailHash, err := crypto.GetHash(req.Email, c.HashingKey)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to get hash")
|
||||
return nil
|
||||
}
|
||||
err = c.UserAuthRepo.AddOTT(emailHash, req.App, req.Code, req.ExpiryTime)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to add ott")
|
||||
return stacktrace.Propagate(err, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// verifyEmailOtt should be deprecated in favor of verifyEmailOttWithSession once clients are updated.
|
||||
func (c *UserController) verifyEmailOtt(context *gin.Context, email string, ott string) error {
|
||||
ott = strings.TrimSpace(ott)
|
||||
|
||||
@@ -98,8 +98,8 @@ func sendViaSMTP(toEmails []string, fromName string, fromEmail string, subject s
|
||||
err := smtp.SendMail(smtpServer+":"+smtpPort, auth, fromEmail, []string{toEmail}, []byte(emailMessage))
|
||||
if err != nil {
|
||||
errMsg := err.Error()
|
||||
for _, knownError := range knownInvalidEmailErrors {
|
||||
if strings.Contains(errMsg, knownError) {
|
||||
for i := range knownInvalidEmailErrors {
|
||||
if strings.Contains(errMsg, knownInvalidEmailErrors[i]) {
|
||||
return stacktrace.Propagate(ente.NewBadRequestWithMessage(fmt.Sprintf("Invalid email %s", toEmail)), errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user