diff --git a/api/errors.go b/api/errors.go index 14b0d7c..2d6b5cc 100644 --- a/api/errors.go +++ b/api/errors.go @@ -47,3 +47,5 @@ var errorNoSuchUnsubscribeSecretHex = errors.New("Invalid unsubscribe link.") var errorEmptyPaths = errors.New("Empty paths field.") var errorInvalidDomain = errors.New("Invalid domain name. Do not include the URL path after the forward slash.") var errorInvalidEntity = errors.New("That entity does not exist.") +var errorCannotDeleteOwnerWithActiveDomains = errors.New("You cannot delete your account until all domains associated with your account are deleted.") +var errorNoSuchOwner = errors.New("No such owner.") diff --git a/api/owner_delete.go b/api/owner_delete.go new file mode 100644 index 0000000..882d1de --- /dev/null +++ b/api/owner_delete.go @@ -0,0 +1,79 @@ +package main + +import ( + "net/http" +) + +func ownerDelete(ownerHex string, deleteDomains bool) error { + domains, err := domainList(ownerHex) + if err != nil { + return err + } + + if len(domains) > 0 { + if !deleteDomains { + return errorCannotDeleteOwnerWithActiveDomains + } + for _, d := range domains { + if err := domainDelete(d.Domain); err != nil { + return err + } + } + } + + statement := ` + DELETE FROM owners + WHERE ownerHex = $1; + ` + _, err = db.Exec(statement, ownerHex) + if err != nil { + return errorNoSuchOwner + } + + statement = ` + DELETE FROM ownersessions + WHERE ownerHex = $1; + ` + _, err = db.Exec(statement, ownerHex) + if err != nil { + logger.Errorf("cannot delete from ownersessions: %v", err) + return errorInternal + } + + statement = ` + DELETE FROM resethexes + WHERE hex = $1; + ` + _, err = db.Exec(statement, ownerHex) + if err != nil { + logger.Errorf("cannot delete from resethexes: %v", err) + return errorInternal + } + + return nil +} + +func ownerDeleteHandler(w http.ResponseWriter, r *http.Request) { + type request struct { + OwnerToken *string `json:"ownerToken"` + } + + var x request + if err := bodyUnmarshal(r, &x); err != nil { + bodyMarshal(w, response{"success": false, "message": err.Error()}) + return + } + + o, err := ownerGetByOwnerToken(*x.OwnerToken) + if err != nil { + bodyMarshal(w, response{"success": false, "message": err.Error()}) + return + } + + if err = ownerDelete(o.OwnerHex, false); err != nil { + bodyMarshal(w, response{"success": false, "message": err.Error()}) + return + } + + bodyMarshal(w, response{"success": true}) +} diff --git a/api/owner_new.go b/api/owner_new.go index 82c417d..4e4e540 100644 --- a/api/owner_new.go +++ b/api/owner_new.go @@ -92,10 +92,8 @@ func ownerNewHandler(w http.ResponseWriter, r *http.Request) { return } - if _, err := commenterNew(*x.Email, *x.Name, "undefined", "undefined", "commento", *x.Password); err != nil { - bodyMarshal(w, response{"success": false, "message": err.Error()}) - return - } + // Errors in creating a commenter account should not hold this up. + _, _ = commenterNew(*x.Email, *x.Name, "undefined", "undefined", "commento", *x.Password) bodyMarshal(w, response{"success": true, "confirmEmail": smtpConfigured}) } diff --git a/api/router_api.go b/api/router_api.go index aed7c6a..98ecf28 100644 --- a/api/router_api.go +++ b/api/router_api.go @@ -9,6 +9,7 @@ func apiRouterInit(router *mux.Router) error { router.HandleFunc("/api/owner/confirm-hex", ownerConfirmHexHandler).Methods("GET") router.HandleFunc("/api/owner/login", ownerLoginHandler).Methods("POST") router.HandleFunc("/api/owner/self", ownerSelfHandler).Methods("POST") + router.HandleFunc("/api/owner/delete", ownerDeleteHandler).Methods("POST") router.HandleFunc("/api/domain/new", domainNewHandler).Methods("POST") router.HandleFunc("/api/domain/delete", domainDeleteHandler).Methods("POST") diff --git a/api/router_static.go b/api/router_static.go index 984d433..6d0f9af 100644 --- a/api/router_static.go +++ b/api/router_static.go @@ -101,6 +101,7 @@ func staticRouterInit(router *mux.Router) error { "/confirm-email", "/unsubscribe", "/dashboard", + "/settings", "/logout", "/profile", } diff --git a/frontend/dashboard.html b/frontend/dashboard.html index b0425b0..6d9c958 100644 --- a/frontend/dashboard.html +++ b/frontend/dashboard.html @@ -14,6 +14,7 @@