diff --git a/backend/pkg/database/gorm_common.go b/backend/pkg/database/gorm_common.go
index e6d7a8d1..a183db3d 100644
--- a/backend/pkg/database/gorm_common.go
+++ b/backend/pkg/database/gorm_common.go
@@ -107,6 +107,66 @@ func (gr *GormRepository) GetCurrentUser(ctx context.Context) (*models.User, err
return ¤tUser, nil
}
+// SECURITY: this should only be called after the user has confirmed they want to delete their account.
+func (gr *GormRepository) DeleteCurrentUser(ctx context.Context) error {
+ currentUser, err := gr.GetCurrentUser(ctx)
+ if err != nil {
+ return err
+ }
+
+ //delete all records associated with this user.
+ // - background jobs
+ // - FHIR Resources
+ // - source credentials
+ // - related resources
+ // - user settings
+ // - user
+
+ //delete background jobs
+ err = gr.GormClient.
+ Where(models.BackgroundJob{UserID: currentUser.ID}).
+ Delete(&models.BackgroundJob{}).Error
+ if err != nil {
+ return fmt.Errorf("could not delete background jobs for user: %w", err)
+ }
+
+ //delete FHIR Resources & sources
+ sources, err := gr.GetSources(ctx)
+ if err != nil {
+ return fmt.Errorf("could not get sources: %w", err)
+ }
+ for _, source := range sources {
+ _, err = gr.DeleteSource(ctx, source.ID.String())
+ if err != nil {
+ return fmt.Errorf("could not delete source (%s) & resources for user: %w", source.ID.String(), err)
+ }
+ }
+
+ //delete related resources
+ err = gr.GormClient.
+ Where(models.RelatedResource{ResourceBaseUserID: currentUser.ID}).
+ Delete(&models.RelatedResource{}).Error
+ if err != nil {
+ return fmt.Errorf("could not delete related resources for user: %w", err)
+ }
+
+ //delete user settings
+ err = gr.GormClient.
+ Where(models.UserSettingEntry{UserID: currentUser.ID}).
+ Delete(&models.UserSettingEntry{}).Error
+ if err != nil {
+ return fmt.Errorf("could not delete user settings for user: %w", err)
+ }
+ //delete user
+ err = gr.GormClient.
+ Where(models.User{ModelBase: models.ModelBase{ID: currentUser.ID}}).
+ Delete(&models.User{}).Error
+ if err != nil {
+ return fmt.Errorf("could not delete user: %w", err)
+ }
+ return nil
+}
+
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/backend/pkg/database/interface.go b/backend/pkg/database/interface.go
index a5ec4f2d..2a6109e5 100644
--- a/backend/pkg/database/interface.go
+++ b/backend/pkg/database/interface.go
@@ -17,6 +17,7 @@ type DatabaseRepository interface {
GetUserByUsername(context.Context, string) (*models.User, error)
GetCurrentUser(ctx context.Context) (*models.User, error)
+ DeleteCurrentUser(ctx context.Context) error
GetSummary(ctx context.Context) (*models.Summary, error)
diff --git a/backend/pkg/web/handler/account.go b/backend/pkg/web/handler/account.go
new file mode 100644
index 00000000..c90aad64
--- /dev/null
+++ b/backend/pkg/web/handler/account.go
@@ -0,0 +1,25 @@
+package handler
+
+import (
+ "github.com/fastenhealth/fasten-onprem/backend/pkg"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/database"
+ "github.com/gin-gonic/gin"
+ "github.com/sirupsen/logrus"
+ "net/http"
+)
+
+// SECURITY: this is a secure endpoint, and should only be called after a double confirmation
+func DeleteAccount(c *gin.Context) {
+ logger := c.MustGet(pkg.ContextKeyTypeLogger).(*logrus.Entry)
+ databaseRepo := c.MustGet(pkg.ContextKeyTypeDatabase).(database.DatabaseRepository)
+
+ err := databaseRepo.DeleteCurrentUser(c)
+
+ if err != nil {
+ logger.Errorln("An error occurred while deleting current user", err)
+ c.JSON(http.StatusInternalServerError, gin.H{"success": false})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"success": true})
+}
diff --git a/backend/pkg/web/server.go b/backend/pkg/web/server.go
index d5b2c58b..fcc55f31 100644
--- a/backend/pkg/web/server.go
+++ b/backend/pkg/web/server.go
@@ -62,6 +62,8 @@ func (ae *AppEngine) Setup() (*gin.RouterGroup, *gin.Engine) {
secure := api.Group("/secure").Use(middleware.RequireAuth())
{
+ secure.DELETE("/account/me", handler.DeleteAccount)
+
secure.GET("/summary", handler.GetSummary)
secure.POST("/source", handler.CreateReconnectSource)
diff --git a/frontend/src/app/pages/patient-profile/patient-profile.component.html b/frontend/src/app/pages/patient-profile/patient-profile.component.html
index d029af66..8cdb6e15 100644
--- a/frontend/src/app/pages/patient-profile/patient-profile.component.html
+++ b/frontend/src/app/pages/patient-profile/patient-profile.component.html
@@ -5,7 +5,7 @@
Are you sure you would like to delete your Fasten Health Account?
++ All personal and medical data on this device will be deleted. You will not be able to recover this data. +
+