mirror of
https://github.com/ente-io/ente.git
synced 2025-04-30 11:35:46 +00:00
[server] Auto recovery post deletion 1/x
This commit is contained in:
parent
2e3ac8b485
commit
c6b4cba8b4
@ -519,6 +519,7 @@ func main() {
|
|||||||
privateAPI.DELETE("/users/session", userHandler.TerminateSession)
|
privateAPI.DELETE("/users/session", userHandler.TerminateSession)
|
||||||
privateAPI.GET("/users/delete-challenge", userHandler.GetDeleteChallenge)
|
privateAPI.GET("/users/delete-challenge", userHandler.GetDeleteChallenge)
|
||||||
privateAPI.DELETE("/users/delete", userHandler.DeleteUser)
|
privateAPI.DELETE("/users/delete", userHandler.DeleteUser)
|
||||||
|
publicAPI.GET("/users/recover-account", userHandler.RecoveryAccount)
|
||||||
|
|
||||||
accountsJwtAuthAPI := server.Group("/")
|
accountsJwtAuthAPI := server.Group("/")
|
||||||
accountsJwtAuthAPI.Use(rateLimiter.GlobalRateLimiter(), authMiddleware.TokenAuthMiddleware(jwt.ACCOUNTS.Ptr()), rateLimiter.APIRateLimitForUserMiddleware(urlSanitizer))
|
accountsJwtAuthAPI.Use(rateLimiter.GlobalRateLimiter(), authMiddleware.TokenAuthMiddleware(jwt.ACCOUNTS.Ptr()), rateLimiter.APIRateLimitForUserMiddleware(urlSanitizer))
|
||||||
|
@ -540,6 +540,20 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) RecoveryAccount(c *gin.Context) {
|
||||||
|
token := c.Query("token")
|
||||||
|
if token == "" {
|
||||||
|
handler.Error(c, stacktrace.Propagate(ente.NewBadRequestWithMessage("token missing"), "token is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response, err := h.UserController.SelfDeleteAccount(c, request)
|
||||||
|
if err != nil {
|
||||||
|
handler.Error(c, stacktrace.Propagate(err, ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
// GetSRPAttributes returns the SRP attributes for a user
|
// GetSRPAttributes returns the SRP attributes for a user
|
||||||
func (h *UserHandler) GetSRPAttributes(c *gin.Context) {
|
func (h *UserHandler) GetSRPAttributes(c *gin.Context) {
|
||||||
var request ente.GetSRPAttributesRequest
|
var request ente.GetSRPAttributesRequest
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
enteJWT "github.com/ente-io/museum/ente/jwt"
|
||||||
"github.com/ente-io/museum/pkg/controller/collections"
|
"github.com/ente-io/museum/pkg/controller/collections"
|
||||||
"github.com/ente-io/museum/pkg/repo/two_factor_recovery"
|
"github.com/ente-io/museum/pkg/repo/two_factor_recovery"
|
||||||
|
"github.com/ente-io/museum/pkg/utils/time"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
cache2 "github.com/ente-io/museum/ente/cache"
|
cache2 "github.com/ente-io/museum/ente/cache"
|
||||||
@ -271,7 +274,7 @@ func (c *UserController) HandleAccountDeletion(ctx *gin.Context, userID int64, l
|
|||||||
return nil, stacktrace.Propagate(err, "")
|
return nil, stacktrace.Propagate(err, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
go c.NotifyAccountDeletion(email, isSubscriptionCancelled)
|
go c.NotifyAccountDeletion(userID, email, isSubscriptionCancelled)
|
||||||
|
|
||||||
return &ente.DeleteAccountResponse{
|
return &ente.DeleteAccountResponse{
|
||||||
IsSubscriptionCancelled: isSubscriptionCancelled,
|
IsSubscriptionCancelled: isSubscriptionCancelled,
|
||||||
@ -280,23 +283,43 @@ func (c *UserController) HandleAccountDeletion(ctx *gin.Context, userID int64, l
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *UserController) NotifyAccountDeletion(userEmail string, isSubscriptionCancelled bool) {
|
func (c *UserController) NotifyAccountDeletion(userID int64, userEmail string, isSubscriptionCancelled bool) {
|
||||||
template := AccountDeletedEmailTemplate
|
template := AccountDeletedEmailTemplate
|
||||||
if !isSubscriptionCancelled {
|
if !isSubscriptionCancelled {
|
||||||
template = AccountDeletedWithActiveSubscriptionEmailTemplate
|
template = AccountDeletedWithActiveSubscriptionEmailTemplate
|
||||||
}
|
}
|
||||||
|
recoverToken, err2 := c.GetJWTTokenForClaim(&enteJWT.WebCommonJWTClaim{
|
||||||
|
UserID: userID,
|
||||||
|
ExpiryTime: time.NDaysFromNow(7),
|
||||||
|
ClaimScope: enteJWT.RestoreAccount.Ptr(),
|
||||||
|
Email: userEmail,
|
||||||
|
})
|
||||||
|
if err2 != nil {
|
||||||
|
logrus.WithError(err2).Error("failed to generate recover token")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData := make(map[string]interface{})
|
||||||
|
templateData["RecoverLink"] = fmt.Sprintf("%s/user/recover-account?token=%s", "https://api.ente.io", recoverToken)
|
||||||
err := email.SendTemplatedEmail([]string{userEmail}, "ente", "team@ente.io",
|
err := email.SendTemplatedEmail([]string{userEmail}, "ente", "team@ente.io",
|
||||||
AccountDeletedEmailSubject, template, nil, nil)
|
AccountDeletedEmailSubject, template, templateData, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Errorf("Failed to send the account deletion email to %s", userEmail)
|
logrus.WithError(err).Errorf("Failed to send the account deletion email to %s", userEmail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *UserController) HandleAccountRecovery(ctx *gin.Context, req ente.RecoverAccountRequest) error {
|
func (c *UserController) HandleAccountRecovery(ctx *gin.Context, req ente.RecoverAccountRequest) error {
|
||||||
|
logger := logrus.WithFields(logrus.Fields{
|
||||||
|
"req_id": ctx.GetString("req_id"),
|
||||||
|
"req_ctx": "account_recovery",
|
||||||
|
"email": req.EmailID,
|
||||||
|
"userID": req.UserID,
|
||||||
|
})
|
||||||
|
logger.Info("recover account request")
|
||||||
_, err := c.UserRepo.Get(req.UserID)
|
_, err := c.UserRepo.Get(req.UserID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return stacktrace.Propagate(ente.NewBadRequestError(&ente.ApiErrorParams{
|
return stacktrace.Propagate(ente.NewBadRequestError(&ente.ApiErrorParams{
|
||||||
Message: "User ID is linked to undeleted account",
|
Message: "User ID is linked to an active account account",
|
||||||
}), "")
|
}), "")
|
||||||
}
|
}
|
||||||
if !errors.Is(err, ente.ErrUserDeleted) {
|
if !errors.Is(err, ente.ErrUserDeleted) {
|
||||||
@ -304,6 +327,9 @@ func (c *UserController) HandleAccountRecovery(ctx *gin.Context, req ente.Recove
|
|||||||
}
|
}
|
||||||
// check if the user keyAttributes are still available
|
// check if the user keyAttributes are still available
|
||||||
if _, keyErr := c.UserRepo.GetKeyAttributes(req.UserID); keyErr != nil {
|
if _, keyErr := c.UserRepo.GetKeyAttributes(req.UserID); keyErr != nil {
|
||||||
|
if errors.Is(keyErr, sql.ErrNoRows) {
|
||||||
|
return stacktrace.Propagate(ente.NewBadRequestWithMessage("account can not be recovered now"), "")
|
||||||
|
}
|
||||||
return stacktrace.Propagate(keyErr, "keyAttributes missing? Account can not be recovered")
|
return stacktrace.Propagate(keyErr, "keyAttributes missing? Account can not be recovered")
|
||||||
}
|
}
|
||||||
email := strings.ToLower(req.EmailID)
|
email := strings.ToLower(req.EmailID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user