Newer
Older
////////////////////////////////////////////////////////////////////////////////
// //
// Use of this source code is governed by a license that can be found in the //
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
////////////////////////////////////////////////////////////////////////////////
//go:build js && wasm
package wasm
import (
"gitlab.com/elixxir/client/bindings"
"syscall/js"
)
////////////////////////////////////////////////////////////////////////////////
// Structs and Interfaces //
////////////////////////////////////////////////////////////////////////////////
// UserDiscovery wraps the [bindings.UserDiscovery] object so its methods can be
// wrapped to be Javascript compatible.
type UserDiscovery struct {
api *bindings.UserDiscovery
}
// newE2eJS creates a new Javascript compatible object (map[string]interface{})
// that matches the E2e structure.
func newUserDiscoveryJS(api *bindings.UserDiscovery) map[string]interface{} {
ud := UserDiscovery{api}
udMap := map[string]interface{}{
"GetID": js.FuncOf(ud.GetID),
"GetFacts": js.FuncOf(ud.GetFacts),
"GetContact": js.FuncOf(ud.GetContact),
"ConfirmFact": js.FuncOf(ud.ConfirmFact),
"SendRegisterFact": js.FuncOf(ud.SendRegisterFact),
"PermanentDeleteAccount": js.FuncOf(ud.PermanentDeleteAccount),
"RemoveFact": js.FuncOf(ud.RemoveFact),
}
return udMap
}
// GetID returns the ID for this UserDiscovery in the UserDiscovery tracker.
//
// Returns:
// - int
func (ud *UserDiscovery) GetID(js.Value, []js.Value) interface{} {
return ud.api.GetID()
}
// udNetworkStatus wraps Javascript callbacks to adhere to the
// [bindings.UdNetworkStatus] interface.
type udNetworkStatus struct {
udNetworkStatus func(args ...interface{}) js.Value
}
func (uns *udNetworkStatus) UdNetworkStatus() int {
return uns.udNetworkStatus().Int()
}
////////////////////////////////////////////////////////////////////////////////
// Manager functions //
////////////////////////////////////////////////////////////////////////////////
// NewOrLoadUd loads an existing Manager from storage or creates a new one if
// there is no extant storage information. Parameters need be provided to
// specify how to connect to the User Discovery service. These parameters may be
// used to contact either the UD server hosted by the xx network team or a
// custom third-party operated server. For the former, all the information may
// be pulled from the NDF using the bindings.
//
// Params
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - Javascript object that has functions that implement the
// [bindings.UdNetworkStatus] interface. This is the network follower
// function wrapped in [bindings.UdNetworkStatus].
// - args[2] - the username the user wants to register with UD. If the user is
// already registered, this field may be blank (string).
// - args[3] - the registration validation signature; a signature provided by
// the network (i.e., the client registrar). This may be nil; however, UD may
// return an error in some cases (e.g., in a production level environment)
// (Uint8Array).
// - args[4] - the TLS certificate for the UD server this call will connect
// with. You may use the UD server run by the xx network team by using
// E2e.GetUdCertFromNdf (Uint8Array).
// - args[5] - marshalled [contact.Contact]. This represents the contact file
// of the server this call will connect with. You may use the UD server run
// by the xx network team by using E2e.GetUdContactFromNdf (Uint8Array).
// - args[6] - the IP address of the UD server this call will connect with. You
// may use the UD server run by the xx network team by using
// E2e.GetUdAddressFromNdf (string).
//
// Returns:
// - Javascript representation of the UserDiscovery object that is registered
// to the specified UD service.
// - Throws a TypeError if creating or loading fails.
func NewOrLoadUd(_ js.Value, args []js.Value) interface{} {
e2eID := args[0].Int()
follower := &udNetworkStatus{WrapCB(args[1], "UdNetworkStatus")}
username := args[2].String()
registrationValidationSignature := CopyBytesToGo(args[3])
cert := CopyBytesToGo(args[4])
contactFile := CopyBytesToGo(args[5])
address := args[6].String()
api, err := bindings.NewOrLoadUd(e2eID, follower, username,
registrationValidationSignature, cert, contactFile, address)
if err != nil {
Throw(TypeError, err)
return nil
}
return newUserDiscoveryJS(api)
}
// NewUdManagerFromBackup builds a new user discover manager from a backup. It
// will construct a manager that is already registered and restore already
// registered facts into store.
//
// Note that it can take in both ane email address and a phone number or both.
// However, at least one fact must be specified; providing no facts will return
// an error.
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - Javascript object that has functions that implement the
// [bindings.UdNetworkStatus] interface. This is the network follower
// function wrapped in [bindings.UdNetworkStatus].
// - args[2] - JSON of [fact.Fact] username that is registered with UD
// - args[3] - JSON of [fact.Fact] email address that is registered with UD
// - args[4] - JSON of [fact.Fact] phone number that is registered with UD
// (Uint8Array).
// - args[5] - the TLS certificate for the UD server this call will connect
// with. You may use the UD server run by the xx network team by using
// E2e.GetUdCertFromNdf (Uint8Array).
// - args[6] - marshalled [contact.Contact]. This represents the contact file
// of the server this call will connect with. You may use the UD server run
// by the xx network team by using E2e.GetUdContactFromNdf (Uint8Array).
// - args[7] - the IP address of the UD server this call will connect with. You
// may use the UD server run by the xx network team by using
// E2e.GetUdAddressFromNdf (string).
//
// Returns:
// - Javascript representation of the UserDiscovery object that is loaded from
// backup.
// - Throws a TypeError if getting UD from backup fails.
func NewUdManagerFromBackup(_ js.Value, args []js.Value) interface{} {
e2eID := args[0].Int()
follower := &udNetworkStatus{WrapCB(args[1], "UdNetworkStatus")}
usernameFactJson := CopyBytesToGo(args[2])
emailFactJson := CopyBytesToGo(args[3])
phoneFactJson := CopyBytesToGo(args[4])
cert := CopyBytesToGo(args[5])
contactFile := CopyBytesToGo(args[6])
address := args[7].String()
api, err := bindings.NewUdManagerFromBackup(e2eID, follower, usernameFactJson, emailFactJson,
phoneFactJson, cert, contactFile, address)
if err != nil {
Throw(TypeError, err)
return nil
}
return newUserDiscoveryJS(api)
}
// GetFacts returns a JSON marshalled list of [fact.Fact] objects that exist
// within the Store's registeredFacts map.
//
// Returns:
// - JSON of [fact.FactList] (Uint8Array).
func (ud *UserDiscovery) GetFacts(js.Value, []js.Value) interface{} {
return CopyBytesToJS(ud.api.GetFacts())
}
// GetContact returns the marshalled bytes of the [contact.Contact] for UD as
// retrieved from the NDF.
//
// Returns:
// - JSON of [contact.Contact] (Uint8Array).
// - Throws TypeError if getting the contact fails.
func (ud *UserDiscovery) GetContact(js.Value, []js.Value) interface{} {
c, err := ud.api.GetContact()
if err != nil {
Throw(TypeError, err)
return nil
}
return CopyBytesToJS(c)
}
// ConfirmFact confirms a fact first registered via SendRegisterFact. The
// confirmation ID comes from SendRegisterFact while the code will come over the
// associated communications system.
//
// Parameters:
// - args[0] - confirmation ID (string).
// - args[1] - code (string).
//
// Returns:
// - Throws TypeError if confirming the fact fails.
func (ud *UserDiscovery) ConfirmFact(_ js.Value, args []js.Value) interface{} {
err := ud.api.ConfirmFact(args[0].String(), args[1].String())
if err != nil {
Throw(TypeError, err)
return nil
}
return nil
}
// SendRegisterFact adds a fact for the user to user discovery. Will only
// succeed if the user is already registered and the system does not have the
// fact currently registered for any user.
//
// This does not complete the fact registration process, it returns a
// confirmation ID instead. Over the communications system the fact is
// associated with, a code will be sent. This confirmation ID needs to be called
// along with the code to finalize the fact.
//
// Parameters:
// - args[0] - JSON of [fact.Fact] (Uint8Array).
//
// Returns:
// - The confirmation ID (string).
// - Throws TypeError if sending the fact fails.
func (ud *UserDiscovery) SendRegisterFact(_ js.Value, args []js.Value) interface{} {
confirmationID, err := ud.api.SendRegisterFact(CopyBytesToGo(args[0]))
if err != nil {
Throw(TypeError, err)
return nil
}
return confirmationID
}
// PermanentDeleteAccount removes the username associated with this user from
// the UD service. This will only take a username type fact, and the fact must
// be associated with this user.
//
// Parameters:
// - args[0] - JSON of [fact.Fact] (Uint8Array).
//
// Returns:
// - Throws TypeError if deletion fails.
func (ud *UserDiscovery) PermanentDeleteAccount(_ js.Value, args []js.Value) interface{} {
err := ud.api.PermanentDeleteAccount(CopyBytesToGo(args[0]))
if err != nil {
Throw(TypeError, err)
return nil
}
return nil
}
// RemoveFact removes a previously confirmed fact. This will fail if the fact
// passed in is not UD service does not associate this fact with this user.
//
// Parameters:
// - args[0] - JSON of [fact.Fact] (Uint8Array).
//
// Returns:
// - Throws TypeError if removing the fact fails.
func (ud *UserDiscovery) RemoveFact(_ js.Value, args []js.Value) interface{} {
err := ud.api.RemoveFact(CopyBytesToGo(args[0]))
if err != nil {
Throw(TypeError, err)
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
return nil
}
return nil
}
////////////////////////////////////////////////////////////////////////////////
// User Discovery Lookup //
////////////////////////////////////////////////////////////////////////////////
// udLookupCallback wraps Javascript callbacks to adhere to the
// [bindings.UdLookupCallback] interface.
type udLookupCallback struct {
callback func(args ...interface{}) js.Value
}
func (ulc *udLookupCallback) Callback(contactBytes []byte, err error) {
ulc.callback(CopyBytesToJS(contactBytes), err.Error())
}
// LookupUD returns the public key of the passed ID as known by the user
// discovery system or returns by the timeout.
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - JSON of User Discovery's [contact.Contact] (Uint8Array).
// - args[2] - Javascript object that has functions that implement the
// [bindings.UdLookupCallback] interface.
// - args[3] - JSON of [id.ID] for the user to look up (Uint8Array).
// - args[4] - JSON of [single.RequestParams] (Uint8Array).
//
// Returns:
// - JSON of [bindings.SingleUseSendReport], which can be passed into
// Cmix.WaitForRoundResult to see if the send succeeded.
// - Throws a TypeError if the lookup fails.
func LookupUD(_ js.Value, args []js.Value) interface{} {
e2eID := args[0].Int()
udContact := CopyBytesToGo(args[1])
cb := &udLookupCallback{WrapCB(args[2], "Callback")}
lookupId := CopyBytesToGo(args[3])
singleRequestParamsJSON := CopyBytesToGo(args[4])
report, err := bindings.LookupUD(
e2eID, udContact, cb, lookupId, singleRequestParamsJSON)
if err != nil {
Throw(TypeError, err)
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
return nil
}
return CopyBytesToJS(report)
}
////////////////////////////////////////////////////////////////////////////////
// User Discovery Search //
////////////////////////////////////////////////////////////////////////////////
// udSearchCallback wraps Javascript callbacks to adhere to the
// [bindings.UdSearchCallback] interface.
type udSearchCallback struct {
callback func(args ...interface{}) js.Value
}
func (usc *udSearchCallback) Callback(contactListJSON []byte, err error) {
usc.callback(CopyBytesToJS(contactListJSON), err.Error())
}
// SearchUD searches user discovery for the passed Facts. The searchCallback
// will return a list of contacts, each having the facts it hit against. This is
// NOT intended to be used to search for multiple users at once; that can have a
// privacy reduction. Instead, it is intended to be used to search for a user
// where multiple pieces of information is known.
//
// Parameters:
// - args[0] - ID of E2e object in tracker (int).
// - args[1] - JSON of User Discovery's [contact.Contact] (Uint8Array).
// - args[2] - JSON of [fact.FactList] (Uint8Array).
// - args[4] - JSON of [single.RequestParams] (Uint8Array).
//
// Returns:
// - JSON of [bindings.SingleUseSendReport], which can be passed into
// Cmix.WaitForRoundResult to see if the send succeeded.
// - Throws a TypeError if the search fails.
func SearchUD(_ js.Value, args []js.Value) interface{} {
e2eID := args[0].Int()
udContact := CopyBytesToGo(args[1])
cb := &udSearchCallback{WrapCB(args[2], "Callback")}
factListJSON := CopyBytesToGo(args[3])
singleRequestParamsJSON := CopyBytesToGo(args[4])
report, err := bindings.SearchUD(
e2eID, udContact, cb, factListJSON, singleRequestParamsJSON)
if err != nil {
Throw(TypeError, err)
return nil
}
return CopyBytesToJS(report)
}