this repo has no description
1package server 2 3import ( 4 "context" 5 "time" 6 7 "github.com/Azure/go-autorest/autorest/to" 8 "github.com/bluesky-social/indigo/api/atproto" 9 "github.com/bluesky-social/indigo/events" 10 "github.com/bluesky-social/indigo/util" 11 "github.com/haileyok/cocoon/internal/helpers" 12 "github.com/labstack/echo/v4" 13 "golang.org/x/crypto/bcrypt" 14) 15 16type ComAtprotoServerDeleteAccountRequest struct { 17 Did string `json:"did" validate:"required"` 18 Password string `json:"password" validate:"required"` 19 Token string `json:"token" validate:"required"` 20} 21 22func (s *Server) handleServerDeleteAccount(e echo.Context) error { 23 ctx := e.Request().Context() 24 25 var req ComAtprotoServerDeleteAccountRequest 26 if err := e.Bind(&req); err != nil { 27 s.logger.Error("error binding", "error", err) 28 return helpers.ServerError(e, nil) 29 } 30 31 if err := e.Validate(&req); err != nil { 32 s.logger.Error("error validating", "error", err) 33 return helpers.ServerError(e, nil) 34 } 35 36 urepo, err := s.getRepoActorByDid(ctx, req.Did) 37 if err != nil { 38 s.logger.Error("error getting repo", "error", err) 39 return echo.NewHTTPError(400, "account not found") 40 } 41 42 if err := bcrypt.CompareHashAndPassword([]byte(urepo.Repo.Password), []byte(req.Password)); err != nil { 43 s.logger.Error("password mismatch", "error", err) 44 return echo.NewHTTPError(401, "Invalid did or password") 45 } 46 47 if urepo.Repo.AccountDeleteCode == nil || urepo.Repo.AccountDeleteCodeExpiresAt == nil { 48 s.logger.Error("no deletion token found for account") 49 return echo.NewHTTPError(400, map[string]interface{}{ 50 "error": "InvalidToken", 51 "message": "Token is invalid", 52 }) 53 } 54 55 if *urepo.Repo.AccountDeleteCode != req.Token { 56 s.logger.Error("deletion token mismatch") 57 return echo.NewHTTPError(400, map[string]interface{}{ 58 "error": "InvalidToken", 59 "message": "Token is invalid", 60 }) 61 } 62 63 if time.Now().UTC().After(*urepo.Repo.AccountDeleteCodeExpiresAt) { 64 s.logger.Error("deletion token expired") 65 return echo.NewHTTPError(400, map[string]interface{}{ 66 "error": "ExpiredToken", 67 "message": "Token is expired", 68 }) 69 } 70 71 tx := s.db.BeginDangerously(ctx) 72 if tx.Error != nil { 73 s.logger.Error("error starting transaction", "error", tx.Error) 74 return helpers.ServerError(e, nil) 75 } 76 77 if err := tx.Exec("DELETE FROM blocks WHERE did = ?", nil, req.Did).Error; err != nil { 78 tx.Rollback() 79 s.logger.Error("error deleting blocks", "error", err) 80 return helpers.ServerError(e, nil) 81 } 82 83 if err := tx.Exec("DELETE FROM records WHERE did = ?", nil, req.Did).Error; err != nil { 84 tx.Rollback() 85 s.logger.Error("error deleting records", "error", err) 86 return helpers.ServerError(e, nil) 87 } 88 89 if err := tx.Exec("DELETE FROM blobs WHERE did = ?", nil, req.Did).Error; err != nil { 90 tx.Rollback() 91 s.logger.Error("error deleting blobs", "error", err) 92 return helpers.ServerError(e, nil) 93 } 94 95 if err := tx.Exec("DELETE FROM tokens WHERE did = ?", nil, req.Did).Error; err != nil { 96 tx.Rollback() 97 s.logger.Error("error deleting tokens", "error", err) 98 return helpers.ServerError(e, nil) 99 } 100 101 if err := tx.Exec("DELETE FROM refresh_tokens WHERE did = ?", nil, req.Did).Error; err != nil { 102 tx.Rollback() 103 s.logger.Error("error deleting refresh tokens", "error", err) 104 return helpers.ServerError(e, nil) 105 } 106 107 if err := tx.Exec("DELETE FROM reserved_keys WHERE did = ?", nil, req.Did).Error; err != nil { 108 tx.Rollback() 109 s.logger.Error("error deleting reserved keys", "error", err) 110 return helpers.ServerError(e, nil) 111 } 112 113 if err := tx.Exec("DELETE FROM invite_codes WHERE did = ?", nil, req.Did).Error; err != nil { 114 tx.Rollback() 115 s.logger.Error("error deleting invite codes", "error", err) 116 return helpers.ServerError(e, nil) 117 } 118 119 if err := tx.Exec("DELETE FROM actors WHERE did = ?", nil, req.Did).Error; err != nil { 120 tx.Rollback() 121 s.logger.Error("error deleting actor", "error", err) 122 return helpers.ServerError(e, nil) 123 } 124 125 if err := tx.Exec("DELETE FROM repos WHERE did = ?", nil, req.Did).Error; err != nil { 126 tx.Rollback() 127 s.logger.Error("error deleting repo", "error", err) 128 return helpers.ServerError(e, nil) 129 } 130 131 if err := tx.Commit().Error; err != nil { 132 s.logger.Error("error committing transaction", "error", err) 133 return helpers.ServerError(e, nil) 134 } 135 136 s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{ 137 RepoAccount: &atproto.SyncSubscribeRepos_Account{ 138 Active: false, 139 Did: req.Did, 140 Status: to.StringPtr("deleted"), 141 Seq: time.Now().UnixMicro(), 142 Time: time.Now().Format(util.ISO8601), 143 }, 144 }) 145 146 return e.NoContent(200) 147}