Skip to content
Snippets Groups Projects
Commit 1f920df8 authored by Jono Wenger's avatar Jono Wenger
Browse files

Implement backup.go

parent bbd19c36
No related branches found
No related tags found
1 merge request!60Revert "Fail a test to be sure it works"
......@@ -74,9 +74,14 @@ func main() {
js.Global().Set("NewDummyTrafficManager",
js.FuncOf(wasm.NewDummyTrafficManager))
// bindings/broadcast
// bindings/broadcast.go
js.Global().Set("NewBroadcastChannel", js.FuncOf(wasm.NewBroadcastChannel))
// bindings/backup.go
js.Global().Set("NewCmixFromBackup", js.FuncOf(wasm.NewCmixFromBackup))
js.Global().Set("InitializeBackup", js.FuncOf(wasm.InitializeBackup))
js.Global().Set("ResumeBackup", js.FuncOf(wasm.ResumeBackup))
<-make(chan bool)
os.Exit(0)
}
......@@ -39,10 +39,9 @@ func (ac *AuthenticatedConnection) IsAuthenticated(js.Value, []js.Value) interfa
// ConnectWithAuthentication is called by the client (i.e., the one establishing
// connection with the server). Once a connect.Connection has been established
// with the server, it then authenticates their identity to the server.
// accepts a marshalled ReceptionIdentity and contact.Contact object
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int)
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - marshalled recipient [contact.Contact] (Uint8Array).
// - args[3] - JSON of [xxdk.E2EParams] (Uint8Array).
//
......
......@@ -5,6 +5,8 @@
// LICENSE file //
////////////////////////////////////////////////////////////////////////////////
//go:build js && wasm
package wasm
import (
......
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2020 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
////////////////////////////////////////////////////////////////////////////////
package wasm
import (
"gitlab.com/elixxir/client/bindings"
"syscall/js"
)
////////////////////////////////////////////////////////////////////////////////
// Structs and Interfaces //
////////////////////////////////////////////////////////////////////////////////
// Backup wraps the [bindings.Backup] object so its methods can be wrapped to be
// Javascript compatible.
type Backup struct {
api *bindings.Backup
}
// newBackupJS creates a new Javascript compatible object
// (map[string]interface{}) that matches the Backup structure.
func newBackupJS(api *bindings.Backup) map[string]interface{} {
b := Backup{api}
backupMap := map[string]interface{}{
"StopBackup": js.FuncOf(b.StopBackup),
"IsBackupRunning": js.FuncOf(b.IsBackupRunning),
"AddJson": js.FuncOf(b.AddJson),
}
return backupMap
}
// updateBackupFunc wraps Javascript callbacks to adhere to the
// [bindings.UpdateBackupFunc] interface.
type updateBackupFunc struct {
updateBackup func(args ...interface{}) js.Value
}
func (ubf *updateBackupFunc) UpdateBackup(encryptedBackup []byte) {
ubf.updateBackup(CopyBytesToJS(encryptedBackup))
}
////////////////////////////////////////////////////////////////////////////////
// Client functions //
////////////////////////////////////////////////////////////////////////////////
// NewCmixFromBackup initializes a new e2e storage from an encrypted
// backup. Users of this function should delete the storage directory on error.
// Users of this function should call LoadCmix as normal once this call succeeds.
//
// Parameters:
// - args[0] - JSON of the NDF (string).
// - args[1] - storage directory (string).
// - args[2] - backup passphrase (string).
// - args[3] - session password (Uint8Array).
// - args[4] - backup file contents (Uint8Array).
//
// Returns:
// - JSON of [bindings.BackupReport] (Uint8Array).
// - throws a TypeError if creating Cmix from backup fails.
func NewCmixFromBackup(_ js.Value, args []js.Value) interface{} {
ndfJSON := args[0].String()
storageDir := args[1].String()
backupPassphrase := args[2].String()
sessionPassword := CopyBytesToGo(args[3])
backupFileContents := CopyBytesToGo(args[4])
report, err := bindings.NewCmixFromBackup(ndfJSON, storageDir,
backupPassphrase, sessionPassword, backupFileContents)
if err != nil {
Throw(TypeError, err.Error())
return nil
}
return CopyBytesToJS(report)
}
////////////////////////////////////////////////////////////////////////////////
// Backup functions //
////////////////////////////////////////////////////////////////////////////////
// InitializeBackup creates a bindings-layer Backup object.
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - ID of UserDiscovery object in tracker (int).
// - args[2] - backup passphrase provided by the user (string). Used to decrypt
// backup.
// - args[3] - the callback to be called when a backup is triggered. Must be
// Javascript object that has functions that implement the
// [bindings.UpdateBackupFunc] interface.
//
// Returns:
// - Javascript representation of the Backup object
// - Throws a TypeError if initializing the Backup fails.
func InitializeBackup(_ js.Value, args []js.Value) interface{} {
cb := &updateBackupFunc{args[3].Get("UpdateBackup").Invoke}
api, err := bindings.InitializeBackup(
args[0].Int(), args[1].Int(), args[2].String(), cb)
if err != nil {
Throw(TypeError, err.Error())
return nil
}
return newBackupJS(api)
}
// ResumeBackup resumes the backup processes with a new callback.
// Call this function only when resuming a backup that has already been
// initialized or to replace the callback.
// To start the backup for the first time or to use a new password, use
// InitializeBackup.
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - ID of UserDiscovery object in tracker (int).
// - args[2] - the callback to be called when a backup is triggered. Must be
// Javascript object that has functions that implement the
// [bindings.UpdateBackupFunc] interface. This will replace any callback that
// has been passed into InitializeBackup.
//
// Returns:
// - Javascript representation of the Backup object
// - Throws a TypeError if initializing the Backup fails.
func ResumeBackup(_ js.Value, args []js.Value) interface{} {
cb := &updateBackupFunc{args[2].Get("UpdateBackup").Invoke}
api, err := bindings.ResumeBackup(args[0].Int(), args[1].Int(), cb)
if err != nil {
Throw(TypeError, err.Error())
return nil
}
return newBackupJS(api)
}
// StopBackup stops the backup processes and deletes the user's password from
// storage. To enable backups again, call InitializeBackup.
//
// Returns:
// - Throws a TypeError if stopping the backup fails.
func (b *Backup) StopBackup(js.Value, []js.Value) interface{} {
err := b.api.StopBackup()
if err != nil {
Throw(TypeError, err.Error())
return nil
}
return nil
}
// IsBackupRunning returns true if the backup has been initialized and is
// running. Returns false if it has been stopped.
//
// Returns:
// - boolean
func (b *Backup) IsBackupRunning(js.Value, []js.Value) interface{} {
return b.api.IsBackupRunning()
}
// AddJson stores the argument within the Backup structure.
//
// Parameters:
// - args[0] - JSON to store (string).
func (b *Backup) AddJson(_ js.Value, args []js.Value) interface{} {
b.api.AddJson(args[0].String())
return nil
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2020 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
////////////////////////////////////////////////////////////////////////////////
package wasm
import (
"gitlab.com/elixxir/client/bindings"
"reflect"
"testing"
)
// Tests that the map representing Backup returned by newBackupJS contains all
// of the methods on Backup.
func Test_newBackupJS(t *testing.T) {
buType := reflect.TypeOf(&Backup{})
b := newBackupJS(&bindings.Backup{})
if len(b) != buType.NumMethod() {
t.Errorf("Backup JS object does not have all methods."+
"\nexpected: %d\nreceived: %d", buType.NumMethod(), len(b))
}
for i := 0; i < buType.NumMethod(); i++ {
method := buType.Method(i)
if _, exists := b[method.Name]; !exists {
t.Errorf("Method %s does not exist.", method.Name)
}
}
}
......@@ -66,13 +66,13 @@ func newCmixJS(api *bindings.Cmix) map[string]interface{} {
// Users of this function should delete the storage directory on error.
//
// Parameters:
// - args[0] - NDF JSON (string)
// - args[1] - storage directory path (string)
// - args[2] - password used for storage (Uint8Array)
// - args[3] - registration code (string)
// - args[0] - NDF JSON (string).
// - args[1] - storage directory path (string).
// - args[2] - password used for storage (Uint8Array).
// - args[3] - registration code (string).
//
// Returns:
// - throws a TypeError if creating new Cmix fails
// - throws a TypeError if creating new Cmix fails.
func NewCmix(_ js.Value, args []js.Value) interface{} {
password := CopyBytesToGo(args[2])
......
......@@ -17,14 +17,14 @@ import (
// Connection wraps the [bindings.Connection] object so its methods can be
// wrapped to be Javascript compatible.
type Connection struct {
c *bindings.Connection
api *bindings.Connection
}
// newConnectJS creates a new Javascript compatible object
// (map[string]interface{}) that matches the Connection structure.
func newConnectJS(api *bindings.Connection) map[string]interface{} {
c := Connection{api}
connection := map[string]interface{}{
connectionMap := map[string]interface{}{
// connect.go
"GetID": js.FuncOf(c.GetID),
"SendE2E": js.FuncOf(c.SendE2E),
......@@ -33,7 +33,7 @@ func newConnectJS(api *bindings.Connection) map[string]interface{} {
"RegisterListener": js.FuncOf(c.RegisterListener),
}
return connection
return connectionMap
}
// GetID returns the ID for this [bindings.Connection] in the connectionTracker.
......@@ -41,7 +41,7 @@ func newConnectJS(api *bindings.Connection) map[string]interface{} {
// Returns:
// - int of the ID
func (c *Connection) GetID(js.Value, []js.Value) interface{} {
return c.c.GetId()
return c.api.GetId()
}
// Connect performs auth key negotiation with the given recipient and returns a
......@@ -86,7 +86,7 @@ func (c *Cmix) Connect(_ js.Value, args []js.Value) interface{} {
// cmix.WaitForRoundResult to see if the send succeeded (Uint8Array)
// - throws a TypeError if sending fails
func (c *Connection) SendE2E(_ js.Value, args []js.Value) interface{} {
sendReport, err := c.c.SendE2E(args[0].Int(), CopyBytesToGo(args[1]))
sendReport, err := c.api.SendE2E(args[0].Int(), CopyBytesToGo(args[1]))
if err != nil {
Throw(TypeError, err.Error())
return nil
......@@ -99,7 +99,7 @@ func (c *Connection) SendE2E(_ js.Value, args []js.Value) interface{} {
// Returns:
// - throws a TypeError if closing fails
func (c *Connection) Close(js.Value, []js.Value) interface{} {
err := c.c.Close()
err := c.api.Close()
if err != nil {
Throw(TypeError, err.Error())
return nil
......@@ -113,7 +113,7 @@ func (c *Connection) Close(js.Value, []js.Value) interface{} {
// Returns:
// - bytes of the partner's [id.ID] (Uint8Array)
func (c *Connection) GetPartner(js.Value, []js.Value) interface{} {
return CopyBytesToJS(c.c.GetPartner())
return CopyBytesToJS(c.api.GetPartner())
}
// listener adheres to the [bindings.Listener] interface.
......@@ -136,7 +136,7 @@ func (l *listener) Name() string { return l.name().String() }
// Returns:
// - throws a TypeError is registering the listener fails
func (c *Connection) RegisterListener(_ js.Value, args []js.Value) interface{} {
err := c.c.RegisterListener(args[0].Int(),
err := c.api.RegisterListener(args[0].Int(),
&listener{args[1].Get("Hear").Invoke, args[1].Get("Name").Invoke})
if err != nil {
Throw(TypeError, err.Error())
......
......@@ -80,11 +80,11 @@ func (e *E2e) GetID(js.Value, []js.Value) interface{} {
// default [auth.Callbacks] will be used.
//
// Parameters:
// - args[0] - ID of Cmix object in tracker (int)
// - args[0] - ID of Cmix object in tracker (int).
// - args[1] - Javascript object that has functions that implement the
// [bindings.AuthCallbacks] interface
// - args[2] - JSON of the [xxdk.ReceptionIdentity] object (Uint8Array)
// - args[3] - JSON of [xxdk.E2EParams] (Uint8Array)
// [bindings.AuthCallbacks] interface.
// - args[2] - JSON of the [xxdk.ReceptionIdentity] object (Uint8Array).
// - args[3] - JSON of [xxdk.E2EParams] (Uint8Array).
//
// Returns:
// - Javascript representation of the E2e object
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment