From a387ff2f575b033a7542589ac909521f7e08a47e Mon Sep 17 00:00:00 2001
From: Jono Wenger <jono@elixxir.io>
Date: Thu, 12 Jan 2023 18:08:19 +0000
Subject: [PATCH] Hotfix/version update check

---
 main.go            |  2 ++
 storage/version.go | 54 +++++++++++++++++++++++++++++++++++++---
 wasm/version.go    | 62 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 4 deletions(-)

diff --git a/main.go b/main.go
index de379dbd..80fea11e 100644
--- a/main.go
+++ b/main.go
@@ -196,6 +196,8 @@ func main() {
 	js.Global().Set("GetClientVersion", js.FuncOf(wasm.GetClientVersion))
 	js.Global().Set("GetClientGitVersion", js.FuncOf(wasm.GetClientGitVersion))
 	js.Global().Set("GetClientDependencies", js.FuncOf(wasm.GetClientDependencies))
+	js.Global().Set("GetWasmSemanticVersion", js.FuncOf(wasm.GetWasmSemanticVersion))
+	js.Global().Set("GetXXDKSemanticVersion", js.FuncOf(wasm.GetXXDKSemanticVersion))
 
 	<-make(chan bool)
 	os.Exit(0)
diff --git a/storage/version.go b/storage/version.go
index d5130928..7d39cb94 100644
--- a/storage/version.go
+++ b/storage/version.go
@@ -11,9 +11,11 @@ package storage
 
 import (
 	"os"
+	"sync"
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+
 	"gitlab.com/elixxir/client/v4/bindings"
 )
 
@@ -38,17 +40,23 @@ func CheckAndStoreVersions() error {
 
 func checkAndStoreVersions(
 	currentWasmVer, currentClientVer string, ls *LocalStorage) error {
-	// Get the stored client and WASM versions, if they exists
-	storedClientVer, err := initOrLoadStoredSemver(
-		clientVerKey, currentClientVer, ls)
+	// Get the stored client version, if it exists
+	storedClientVer, err :=
+		initOrLoadStoredSemver(clientVerKey, currentClientVer, ls)
 	if err != nil {
 		return err
 	}
+
+	// Get the stored WASM versions, if it exists
 	storedWasmVer, err := initOrLoadStoredSemver(semverKey, currentWasmVer, ls)
 	if err != nil {
 		return err
 	}
 
+	// Store old versions to memory
+	setOldClientSemVersion(storedClientVer)
+	setOldWasmSemVersion(storedWasmVer)
+
 	// Check if client needs an update
 	if storedClientVer != currentClientVer {
 		jww.INFO.Printf("xxDK client out of date; upgrading version: v%s → v%s",
@@ -96,3 +104,43 @@ func initOrLoadStoredSemver(
 	// Return the stored version
 	return string(storedVersion), nil
 }
+
+// oldVersions contains the old versions of xxdk WASM and xxdk client that were
+// stored in storage before being overwritten on update.
+var oldVersions struct {
+	wasm   string
+	client string
+	sync.Mutex
+}
+
+// GetOldWasmSemVersion returns the old version of xxdk WASM before being
+// updated.
+func GetOldWasmSemVersion() string {
+	oldVersions.Lock()
+	defer oldVersions.Unlock()
+	return oldVersions.wasm
+}
+
+// GetOldClientSemVersion returns the old version of xxdk client before being
+// updated.
+func GetOldClientSemVersion() string {
+	oldVersions.Lock()
+	defer oldVersions.Unlock()
+	return oldVersions.client
+}
+
+// setOldWasmSemVersion sets the old version of xxdk WASM. This should be called
+// before it is updated.
+func setOldWasmSemVersion(v string) {
+	oldVersions.Lock()
+	defer oldVersions.Unlock()
+	oldVersions.wasm = v
+}
+
+// setOldClientSemVersion sets the old version of xxdk client. This should be
+// called before it is updated.
+func setOldClientSemVersion(v string) {
+	oldVersions.Lock()
+	defer oldVersions.Unlock()
+	oldVersions.client = v
+}
diff --git a/wasm/version.go b/wasm/version.go
index 528641b6..ee1a921c 100644
--- a/wasm/version.go
+++ b/wasm/version.go
@@ -10,9 +10,12 @@
 package wasm
 
 import (
+	"encoding/json"
+	"syscall/js"
+
 	"gitlab.com/elixxir/client/v4/bindings"
 	"gitlab.com/elixxir/xxdk-wasm/storage"
-	"syscall/js"
+	"gitlab.com/elixxir/xxdk-wasm/utils"
 )
 
 // GetVersion returns the current xxDK WASM semantic version.
@@ -49,3 +52,60 @@ func GetClientGitVersion(js.Value, []js.Value) any {
 func GetClientDependencies(js.Value, []js.Value) any {
 	return bindings.GetDependencies()
 }
+
+// VersionInfo contains information about the current and old version of the
+// API.
+type VersionInfo struct {
+	Current string `json:"current"`
+	Updated bool   `json:"updated"`
+	Old     string `json:"old"`
+}
+
+// GetWasmSemanticVersion returns the current version of the WASM client, it's
+// old version before being updated, and if it has been updated.
+//
+// Returns:
+//   - JSON of [VersionInfo] (Uint8Array).
+//   - Throws a TypeError if getting the version failed.
+func GetWasmSemanticVersion(js.Value, []js.Value) any {
+	vi := VersionInfo{
+		Current: storage.SEMVER,
+		Updated: false,
+		Old:     storage.GetOldWasmSemVersion(),
+	}
+
+	if vi.Current != vi.Old {
+		vi.Updated = true
+	}
+
+	data, err := json.Marshal(vi)
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+	}
+
+	return utils.CopyBytesToJS(data)
+}
+
+// GetXXDKSemanticVersion returns the current version of the xxdk client, it's
+// old version before being updated, and if it has been updated.
+//
+// Returns:
+//   - JSON of [VersionInfo] (Uint8Array).
+//   - Throws a TypeError if getting the version failed.
+func GetXXDKSemanticVersion(js.Value, []js.Value) any {
+	vi := VersionInfo{
+		Current: bindings.GetVersion(),
+		Updated: false,
+		Old:     storage.GetOldClientSemVersion(),
+	}
+	if vi.Current != vi.Old {
+		vi.Updated = true
+	}
+
+	data, err := json.Marshal(vi)
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+	}
+
+	return utils.CopyBytesToJS(data)
+}
-- 
GitLab