From 5ddc38cb33d2197b4d103284e76b5359ab27ceee Mon Sep 17 00:00:00 2001
From: Jono Wenger <jono@elixxir.io>
Date: Thu, 20 Oct 2022 14:44:45 -0700
Subject: [PATCH] Add Purge function to clear all storage used by wasm

---
 main.go       |  3 +++
 wasm/purge.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/main.go b/main.go
index 5da0d86b..46ad9d8c 100644
--- a/main.go
+++ b/main.go
@@ -141,6 +141,9 @@ func main() {
 	js.Global().Set("GetDefaultE2eFileTransferParams",
 		js.FuncOf(wasm.GetDefaultE2eFileTransferParams))
 
+	// wasm/purge.go
+	js.Global().Set("Purge", js.FuncOf(wasm.Purge))
+
 	// wasm/restlike.go
 	js.Global().Set("RestlikeRequest", js.FuncOf(wasm.RestlikeRequest))
 	js.Global().Set("RestlikeRequestAuth", js.FuncOf(wasm.RestlikeRequestAuth))
diff --git a/wasm/purge.go b/wasm/purge.go
index 25c3664c..24bbef13 100644
--- a/wasm/purge.go
+++ b/wasm/purge.go
@@ -7,9 +7,74 @@
 
 package wasm
 
+import (
+	"github.com/hack-pad/go-indexeddb/idb"
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/xxdk-wasm/creds"
+	"gitlab.com/elixxir/xxdk-wasm/utils"
+	"sync/atomic"
+	"syscall/js"
+)
+
 // NumClientsRunning is an atomic that tracks the current number of Cmix
 // followers that have been started. Every time one is started, this counter
 // must be incremented and every time one is stopped, it must be decremented.
 //
 // This variable is an atomic. Only access it with atomic functions
 var NumClientsRunning uint64
+
+// Purge clears all local storage and indexedDb databases saved by this WASM
+// binary. All Cmix followers must be closed and the user's password is
+// required.
+//
+// Warning: This deletes all storage local to the webpage running this WASM.
+// Only use if you want to destroy everything.
+//
+// Parameters:
+//  - args[0] - Storage directory path (string).
+//  - args[1] - Password used for storage (Uint8Array).
+//
+// Returns:
+//  - Throws a TypeError if the password is incorrect or if not all Cmix
+//    followers have been stopped.
+func Purge(_ js.Value, args []js.Value) interface{} {
+	// Check the password
+	if !creds.VerifyPassword(js.Value{}, []js.Value{args[1]}).(bool) {
+		utils.Throw(utils.TypeError, errors.New("invalid password"))
+		return nil
+	}
+
+	// Verify all Cmix followers are stopped
+	if n := atomic.LoadUint64(&NumClientsRunning); n != 0 {
+		utils.Throw(
+			utils.TypeError, errors.Errorf("%d Cmix followers running", n))
+		return nil
+	}
+
+	// Get all indexedDb database names
+	databaseList, err := utils.GetIndexedDbList()
+	if err != nil {
+		utils.Throw(
+			utils.TypeError, errors.Errorf(
+				"failed to get list of indexedDb database names: %+v", err))
+		return nil
+	}
+
+	// Delete each database
+	for _, dbName := range databaseList {
+		_, err = idb.Global().DeleteDatabase(dbName)
+		if err != nil {
+			utils.Throw(
+				utils.TypeError, errors.Errorf(
+					"failed to delete indexedDb database %q: %+v", dbName, err))
+			return nil
+		}
+	}
+
+	// Clear WASM local storage and EKV
+	ls := utils.GetLocalStorage()
+	ls.ClearWASM()
+	ls.ClearPrefix(args[0].String())
+
+	return nil
+}
-- 
GitLab