diff --git a/Makefile b/Makefile index cd183023d09da89d457b2f7a4ec08d33ab75db15..693d4c626a8ceecb85204819f36ccca46e203d3c 100644 --- a/Makefile +++ b/Makefile @@ -11,20 +11,20 @@ build: GOOS=js GOARCH=wasm go build ./... update_release: - GOFLAGS="" go get gitlab.com/elixxir/wasm-utils@release GOFLAGS="" go get gitlab.com/xx_network/primitives@release GOFLAGS="" go get gitlab.com/elixxir/primitives@release GOFLAGS="" go get gitlab.com/xx_network/crypto@release GOFLAGS="" go get gitlab.com/elixxir/crypto@release - GOFLAGS="" go get -d gitlab.com/elixxir/client/v4@project/HavenBeta + GOFLAGS="" go get -d gitlab.com/elixxir/client/v4@release + GOFLAGS="" go get gitlab.com/elixxir/wasm-utils@release update_master: - GOFLAGS="" go get gitlab.com/elixxir/wasm-utils@master GOFLAGS="" go get gitlab.com/xx_network/primitives@master GOFLAGS="" go get gitlab.com/elixxir/primitives@master GOFLAGS="" go get gitlab.com/xx_network/crypto@master GOFLAGS="" go get gitlab.com/elixxir/crypto@master GOFLAGS="" go get -d gitlab.com/elixxir/client/v4@master + GOFLAGS="" go get gitlab.com/elixxir/wasm-utils@master binary: GOOS=js GOARCH=wasm go build -ldflags '-w -s' -trimpath -o xxdk.wasm main.go diff --git a/go.mod b/go.mod index cfd6919d47ca27219deda0a5f53c7ee8f7e302fe..36c45b73c8a414b387ac213eed919af54b8822d5 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,10 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/jwalterweatherman v1.1.0 github.com/stretchr/testify v1.8.2 - gitlab.com/elixxir/client/v4 v4.6.4-0.20230608163043-96d0be74ffb0 - gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235 + gitlab.com/elixxir/client/v4 v4.6.4-0.20230608170359-6f802c11e487 + gitlab.com/elixxir/crypto v0.0.7-0.20230607170539-92d9508c78f9 gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c - gitlab.com/elixxir/wasm-utils v0.0.0-20230522231408-a43b2c1481b2 + gitlab.com/elixxir/wasm-utils v0.0.0-20230607204433-22c46f9d680f gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd gitlab.com/xx_network/primitives v0.0.4-0.20230522171102-940cdd68e516 golang.org/x/crypto v0.5.0 @@ -21,6 +21,7 @@ require ( require ( filippo.io/edwards25519 v1.0.0 // indirect git.xx.network/elixxir/grpc-web-go-client v0.0.0-20230214175953-5b5a8c33d28a // indirect + github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/badoux/checkmail v1.2.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect diff --git a/go.sum b/go.sum index 9a7a679c0ec3004200d135bd386af7c1e2dc3bea..e2d036e83fd8a7a6ac0ede5fbe27536029efd132 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ git.xx.network/elixxir/grpc-web-go-client v0.0.0-20230214175953-5b5a8c33d28a/go. github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd h1:nzE1YQBdx1bq9IlZinHa+HVffy+NmVRoKr+wHN8fpLE= +github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd/go.mod h1:C8yoIfvESpM3GD07OCHU7fqI7lhwyZ2Td1rbNbTAhnc= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -513,76 +515,22 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= gitlab.com/elixxir/bloomfilter v0.0.0-20230322223210-fa84f6842de8 h1:uAFCyBkXprQoPkcDDfxXtaMyL5x+xSGrAWzR907xROQ= gitlab.com/elixxir/bloomfilter v0.0.0-20230322223210-fa84f6842de8/go.mod h1:1X8gRIAPDisS3W6Vtr/ymiUmZMJUIwDV1o5DEOo/pzw= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230525191042-3795029e4315 h1:rOgY9KPwq0wCQGM2VWzHQLidUwo/igqEbHvrfrX14NE= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230525191042-3795029e4315/go.mod h1:1+FU4spF6kwSA84AnFq0i6j4jsAICuvVfp6ACh00K0U= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230526074923-c0fb2a45c312 h1:yUyz1L/rzodZxUU45CeH7mfMfmKAs706+s2j2ZGUSwE= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230526074923-c0fb2a45c312/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530165750-f6ea41bc69e4 h1:dgq4fwLdVzsPGdk1E7vLZI1gWk/QB/K7Rntg+DrxAjY= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530165750-f6ea41bc69e4/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530170051-243baab3da48 h1:2HP8w4HOlqjg0FcvSnhMmpwUa1pcU0WbvWMOUNiy/hE= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530170051-243baab3da48/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530182422-d12ab437257f h1:8TJwqKjeD0eZSvWIlPwjgIwfgdzcHhTzGwaiUJCwwuI= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530182422-d12ab437257f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530201605-ba087da90ba2 h1:sxAgLmG2RLarBuXtcH8g5ZcQbAF9PmS3wrnlwZVFrLA= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530201605-ba087da90ba2/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530211720-a1bc89986df8 h1:XTklpI9leJYgZ4bYZLQUOzzgoxlYUz7xDmcl2Fy7knc= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530211720-a1bc89986df8/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530220505-726d2194d278 h1:etC7c2JeKbykuSHIm8jvb3cpMUdJGlyMsBQbImXlIK8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530220505-726d2194d278/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530222715-a0c0ea0de57f h1:67k1pJg8w6bGfDLex3/e4rdm8Cb2m43qjrryKjVo/UE= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230530222715-a0c0ea0de57f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531180314-040f2bf4bc9f h1:KJQjb0WfOtrJo1vKGeISwlmdQTwtV3CmCg4nbP6bzlM= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531180314-040f2bf4bc9f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531193105-0f398d814565 h1:kBbMa8AdCD/0KaLY7jIMk8yWsrRYSMb4zrdGRT4xZ6w= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531193105-0f398d814565/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531195028-ad25aee27c19 h1:OLZTJAqRm1hqGeeHs+aYZ9v3ojgiv+6qykC8+9pFBVM= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531195028-ad25aee27c19/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531195851-a65797612a21 h1:u4H7ITaOwO4aQoSJCo8zpfRpenaqgHuvjqF3GAe8RrE= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531195851-a65797612a21/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531212217-e21b55fbf23c h1:6OTyW9U/ntZ41Xry+8qDkOH4LoxhlyWTwKpAxi2fvZY= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531212217-e21b55fbf23c/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531224642-b24cd3f5e4a4 h1:YacWU7IJUfixfZyckdXEWPwhix7sq+STK+8Vz8DzVO4= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230531224642-b24cd3f5e4a4/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230601191407-1b0289b33708 h1:wNIKci4XuDfzAJM8+4awP5CgY0jlOEaVbHgp+BkEtz4= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230601191407-1b0289b33708/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230602201618-11b41b04386f h1:jwXyq/17fo5VxdQUDQiIfUHqr8m6Df1bV8wRjV4ssyw= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230602201618-11b41b04386f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230602205033-94b7a8f73adf h1:n9P9trdEGTBQBhraTI800+ZTrNeahmb01uFtfuyaga0= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230602205033-94b7a8f73adf/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605163131-05f3396132b7 h1:10vkqej0JYCBYgJqjclTBnfVpc3//SY015O69HbTaVA= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605163131-05f3396132b7/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605225443-4ab5e5b32c16 h1:OEiENhrAHDgSG5ZI3GLCgYr+e7sLKmYr/6AC+HBHdsc= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605225443-4ab5e5b32c16/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605230916-3e5554db4b70 h1:8GTmUVLfPasdreToIgnoduhwVvUeAnUnUs2btzgBr+0= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230605230916-3e5554db4b70/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606161714-339cef753b8d h1:o7PqwDJ8fSoHc+AYX1InCD1uI2SmMkawwdJMvaxKjmY= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606161714-339cef753b8d/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606201910-fe9f57e3141f h1:JTPDrf4MsaYIuUOFTawEQLZ9rNbCA/SBENPUMFNFijY= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606201910-fe9f57e3141f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606202433-a9136c29d24d h1:bh4tINZyGSZPS9TSOd9exPymYA9shMSvAqeslMGZFH0= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606202433-a9136c29d24d/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606205101-cc748980feed h1:UOrzm9I7ZwKSxl+3NKf3hyqHLfKlneE9ifx533bXMSg= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606205101-cc748980feed/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606205543-83a88c354a91 h1:7+XixtLZdt9jnDFKsOovfIFQ9Z3/hKNtxNOn3ixLhGQ= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230606205543-83a88c354a91/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230607192055-bb48aae366c4 h1:65ivQ2uhBNYPuxZAC9vMIH+4Sljzu2GD9tQpqcOkphk= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230607192055-bb48aae366c4/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230607195322-23fc4942a31f h1:bH4KKrsoMbIR0nga2F2kIVuTyAGfKvNtV8wd5JIbric= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230607195322-23fc4942a31f/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230608163043-96d0be74ffb0 h1:jkdITfmmBH8ou6ip43OvyplXrmZfnVrP+5Y6ZI0R2L0= -gitlab.com/elixxir/client/v4 v4.6.4-0.20230608163043-96d0be74ffb0/go.mod h1:fegbuF1/6a+H3QgsoMG8teLnyuKtDxkELMw8pn5WlZ8= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230607172502-b56996e764f5 h1:TbuQ5a0HJifvNaUey1AnqpX8v/OPdb2GvNmHPy2hm9g= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230607172502-b56996e764f5/go.mod h1:LmbxL4WIT2qiDN7wzpcJG+U13jn3pSqUHtT1+uxN4VI= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230607204847-4a74a5fe2066 h1:NxTd/+AjbVkg+uzf1dIRF23AoDBDDI83jQ2lMJzdEcw= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230607204847-4a74a5fe2066/go.mod h1:GyXpu03l8AybmrGSq+AiKTuB+oJI5of78MdvdqFo29U= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230608170359-6f802c11e487 h1:th4mIU968ZuTd0ZhX6RakJKwgQ3zUESENXdlsWe9jco= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230608170359-6f802c11e487/go.mod h1:GyXpu03l8AybmrGSq+AiKTuB+oJI5of78MdvdqFo29U= gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938 h1:f27+QUFiGWrprKm+fstOg3ABkYLpWcZi3+8Lf5eDnqY= gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938/go.mod h1:z+qW0D9VpY5QKTd7wRlb5SK4kBNqLYsa4DXBcUXue9Q= -gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235 h1:0BySdXTzRWxzH8k5RiNNMmmn2lpuQWLVcDDA/7ehyqc= -gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235/go.mod h1:IYInxKr5Q7EH3oNhg1QX1/sTTRNi7L0JkcyfdRegoio= -gitlab.com/elixxir/ekv v0.3.1-0.20230525165450-f444c687504b h1:hf28yepO93tCacx1bUAh8vVFkBUEuBaJhOjifBxEQK4= -gitlab.com/elixxir/ekv v0.3.1-0.20230525165450-f444c687504b/go.mod h1:EMaUQrsOxvEPQ0/8V/PSkGqFmEC2axBG/uqY0oW2uJM= +gitlab.com/elixxir/crypto v0.0.7-0.20230607170539-92d9508c78f9 h1:+RZcoU7NOPXCenkKM/ImYyLcNDdG4vsWrJyKqoAAv8k= +gitlab.com/elixxir/crypto v0.0.7-0.20230607170539-92d9508c78f9/go.mod h1:lAib0KO9TeTLWbwgFk2uszRxPkHeu843xqnYdkzdEB0= gitlab.com/elixxir/ekv v0.3.1-0.20230525213559-f9da13f4fce1 h1:8XBo6QQBXXGCTrgXHFuqPL21mROLKLAoO3X9xR5TwA0= gitlab.com/elixxir/ekv v0.3.1-0.20230525213559-f9da13f4fce1/go.mod h1:UStTZ9d1UVn9Ahyb49lrbPKyr/Wb8xFWqMXbDgIqQhE= gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c h1:muG8ff95woeVVwQoJHCEclxBFB22lc7EixPylEkYDRU= gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c/go.mod h1:phun4PLkHJA6wcL4JIhhxZztrmCyJHWPNppBP3DUD2Y= -gitlab.com/elixxir/wasm-utils v0.0.0-20230522231408-a43b2c1481b2 h1:GQb350yPBkWRkPRgNSVFF0ZZDOAlXWIKQBI/1Ff6biU= -gitlab.com/elixxir/wasm-utils v0.0.0-20230522231408-a43b2c1481b2/go.mod h1:wB7Vh/7LWUm8wYRBSd+6lxfpk4CnDaHTkLCIVKfL2TA= +gitlab.com/elixxir/wasm-utils v0.0.0-20230607204433-22c46f9d680f h1:Nz87zyNu85uxCI+fiS7dJl6HHxPoGUzyec4FpZy7Vv8= +gitlab.com/elixxir/wasm-utils v0.0.0-20230607204433-22c46f9d680f/go.mod h1:wB7Vh/7LWUm8wYRBSd+6lxfpk4CnDaHTkLCIVKfL2TA= gitlab.com/xx_network/comms v0.0.4-0.20230214180029-5387fb85736d h1:AZf2h0fxyO1KxhZPP9//jG3Swb2BcuKbxtNXJgooLss= gitlab.com/xx_network/comms v0.0.4-0.20230214180029-5387fb85736d/go.mod h1:8cwPyH6G8C4qf/U5KDghn1ksOh79MrNqthjKDrfvbXY= gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd h1:IleH6U5D/c2zF6YL/z3cBKqBPnI5ApNMCtU7ia4t228= diff --git a/indexedDb/impl/channels/callbacks.go b/indexedDb/impl/channels/callbacks.go index 2a901597117fac367e360ee2f80a2567fcab036f..7fe0a8a13385c5984ccc005853231634a9d4a8d6 100644 --- a/indexedDb/impl/channels/callbacks.go +++ b/indexedDb/impl/channels/callbacks.go @@ -18,8 +18,8 @@ import ( "gitlab.com/elixxir/client/v4/channels" "gitlab.com/elixxir/client/v4/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" - cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/crypto/fastRNG" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/crypto/message" wChannels "gitlab.com/elixxir/xxdk-wasm/indexedDb/worker/channels" "gitlab.com/elixxir/xxdk-wasm/worker" @@ -64,7 +64,7 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) { // Create new encryption cipher rng := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG) - encryption, err := cryptoChannel.NewCipherFromJSON( + encryption, err := idbCrypto.NewCipherFromJSON( []byte(msg.EncryptionJSON), rng.GetStream()) if err != nil { return []byte{}, errors.Errorf( diff --git a/indexedDb/impl/channels/implementation.go b/indexedDb/impl/channels/implementation.go index e755acbafb3f750e577305fb9e241c537f30febe..dfc000eba4476870a38b3e6dbd7c8181f55fb5f3 100644 --- a/indexedDb/impl/channels/implementation.go +++ b/indexedDb/impl/channels/implementation.go @@ -25,7 +25,7 @@ import ( "gitlab.com/elixxir/client/v4/channels" "gitlab.com/elixxir/client/v4/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/crypto/message" "gitlab.com/elixxir/wasm-utils/utils" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" @@ -37,7 +37,7 @@ import ( // caller to ensure that its methods are called sequentially. type wasmModel struct { db *idb.Database - cipher cryptoChannel.Cipher + cipher idbCrypto.Cipher eventUpdate func(eventType int64, jsonMarshallable any) } @@ -145,12 +145,11 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID, nickname, text string, pubKey ed25519.PublicKey, dmToken uint32, codeset uint8, timestamp time.Time, lease time.Duration, round rounds.Round, mType channels.MessageType, status channels.SentStatus, hidden bool) uint64 { - textBytes := []byte(text) var err error // Handle encryption, if it is present if w.cipher != nil { - textBytes, err = w.cipher.Encrypt([]byte(text)) + text, err = w.cipher.Encrypt([]byte(text)) if err != nil { jww.ERROR.Printf("Failed to encrypt Message: %+v", err) return 0 @@ -161,7 +160,7 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID, msgToInsert := buildMessage( channelIDBytes, messageID.Bytes(), nil, nickname, - textBytes, pubKey, dmToken, codeset, timestamp, lease, round.ID, mType, + text, pubKey, dmToken, codeset, timestamp, lease, round.ID, mType, false, hidden, status) uuid, err := w.upsertMessage(msgToInsert) @@ -189,12 +188,11 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID, dmToken uint32, codeset uint8, timestamp time.Time, lease time.Duration, round rounds.Round, mType channels.MessageType, status channels.SentStatus, hidden bool) uint64 { - textBytes := []byte(text) var err error // Handle encryption, if it is present if w.cipher != nil { - textBytes, err = w.cipher.Encrypt([]byte(text)) + text, err = w.cipher.Encrypt([]byte(text)) if err != nil { jww.ERROR.Printf("Failed to encrypt Message: %+v", err) return 0 @@ -204,7 +202,7 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID, channelIDBytes := channelID.Marshal() msgToInsert := buildMessage(channelIDBytes, messageID.Bytes(), - replyTo.Bytes(), nickname, textBytes, pubKey, dmToken, codeset, + replyTo.Bytes(), nickname, text, pubKey, dmToken, codeset, timestamp, lease, round.ID, mType, hidden, false, status) uuid, err := w.upsertMessage(msgToInsert) @@ -232,12 +230,11 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, dmToken uint32, codeset uint8, timestamp time.Time, lease time.Duration, round rounds.Round, mType channels.MessageType, status channels.SentStatus, hidden bool) uint64 { - textBytes := []byte(reaction) var err error // Handle encryption, if it is present if w.cipher != nil { - textBytes, err = w.cipher.Encrypt([]byte(reaction)) + reaction, err = w.cipher.Encrypt([]byte(reaction)) if err != nil { jww.ERROR.Printf("Failed to encrypt Message: %+v", err) return 0 @@ -247,7 +244,7 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, channelIDBytes := channelID.Marshal() msgToInsert := buildMessage( channelIDBytes, messageID.Bytes(), reactionTo.Bytes(), nickname, - textBytes, pubKey, dmToken, codeset, timestamp, lease, round.ID, mType, + reaction, pubKey, dmToken, codeset, timestamp, lease, round.ID, mType, false, hidden, status) uuid, err := w.upsertMessage(msgToInsert) @@ -349,8 +346,8 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, // NOTE: ID is not set inside this function because we want to use the // autoincrement key by default. If you are trying to overwrite an existing // message, then you need to set it manually yourself. -func buildMessage(channelID, messageID, parentID []byte, nickname string, - text []byte, pubKey ed25519.PublicKey, dmToken uint32, codeset uint8, +func buildMessage(channelID, messageID, parentID []byte, nickname, + text string, pubKey ed25519.PublicKey, dmToken uint32, codeset uint8, timestamp time.Time, lease time.Duration, round id.Round, mType channels.MessageType, pinned, hidden bool, status channels.SentStatus) *Message { @@ -499,7 +496,7 @@ func (w *wasmModel) GetMessage( Status: channels.SentStatus(lookupResult.Status), Hidden: lookupResult.Hidden, Pinned: lookupResult.Pinned, - Content: lookupResult.Text, + Content: []byte(lookupResult.Text), Type: channels.MessageType(lookupResult.Type), Round: id.Round(lookupResult.Round), PubKey: lookupResult.Pubkey, diff --git a/indexedDb/impl/channels/implementation_test.go b/indexedDb/impl/channels/implementation_test.go index f596065dcc47aa39e3b5aeda7b97a1f389071977..58cd04a1c6d346a02d0073ef33e9e5e292c8607e 100644 --- a/indexedDb/impl/channels/implementation_test.go +++ b/indexedDb/impl/channels/implementation_test.go @@ -27,8 +27,8 @@ import ( cft "gitlab.com/elixxir/client/v4/channelsFileTransfer" "gitlab.com/elixxir/client/v4/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" - cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/crypto/fileTransfer" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/crypto/message" "gitlab.com/elixxir/wasm-utils/storage" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" @@ -120,12 +120,12 @@ func TestWasmModel_ReceiveFile(t *testing.T) { // Happy path, insert message and look it up func TestWasmModel_GetMessage(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -142,7 +142,7 @@ func TestWasmModel_GetMessage(t *testing.T) { } testMsg := buildMessage(id.NewIdFromBytes([]byte(testString), t).Marshal(), - testMsgId.Bytes(), nil, testString, []byte(testString), + testMsgId.Bytes(), nil, testString, testString, []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) _, err = eventModel.upsertMessage(testMsg) @@ -173,7 +173,7 @@ func TestWasmModel_DeleteMessage(t *testing.T) { // Insert a message testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, - testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), + testString, testString, []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) _, err = eventModel.upsertMessage(testMsg) if err != nil { @@ -207,12 +207,12 @@ func TestWasmModel_DeleteMessage(t *testing.T) { // Test wasmModel.UpdateSentStatus happy path and ensure fields don't change. func Test_wasmModel_UpdateSentStatus(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -234,7 +234,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { // Store a test message testMsg := buildMessage(cid.Bytes(), testMsgId.Bytes(), nil, - testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, + testString, testString, []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) uuid, err2 := eventModel.upsertMessage(testMsg) if err2 != nil { @@ -282,12 +282,12 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { // Smoke test wasmModel.JoinChannel/wasmModel.LeaveChannel happy paths. func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -334,12 +334,12 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { // Test UUID gets returned when different messages are added. func Test_wasmModel_UUIDTest(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -381,12 +381,12 @@ func Test_wasmModel_UUIDTest(t *testing.T) { // Tests if the same message ID being sent always returns the same UUID. func Test_wasmModel_DuplicateReceives(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -428,12 +428,12 @@ func Test_wasmModel_DuplicateReceives(t *testing.T) { // Happy path: Inserts many messages, deletes some, and checks that the final // result is as expected. func Test_wasmModel_deleteMsgByChannel(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for _, c := range []cryptoChannel.Cipher{nil, cipher} { + for _, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -501,12 +501,12 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { // This test is designed to prove the behavior of unique indexes. // Inserts will not fail, they simply will not happen. func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { - cipher, err := cryptoChannel.NewCipher( + cipher, err := idbCrypto.NewCipher( []byte("testPass"), []byte("testSalt"), 128, csprng.NewSystemRNG()) if err != nil { t.Fatalf("Failed to create cipher") } - for i, c := range []cryptoChannel.Cipher{nil, cipher} { + for i, c := range []idbCrypto.Cipher{nil, cipher} { cs := "" if c != nil { cs = "_withCipher" @@ -542,12 +542,12 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString)) testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, - testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, + testString, testString, []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) testMsgId2 := message.DeriveChannelMessageID(&id.ID{2}, 0, []byte(testString)) testMsg2 := buildMessage([]byte(testString), testMsgId2.Bytes(), nil, - testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, + testString, testString, []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) // First message insert should succeed diff --git a/indexedDb/impl/channels/init.go b/indexedDb/impl/channels/init.go index 48f5359f9b61c67b42533a42fa37cec4c3c917e7..e604b666636e0953a0a9e19947c53550972d1e76 100644 --- a/indexedDb/impl/channels/init.go +++ b/indexedDb/impl/channels/init.go @@ -18,7 +18,7 @@ import ( "gitlab.com/elixxir/client/v4/bindings" "gitlab.com/elixxir/client/v4/channels" - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" ) @@ -29,13 +29,13 @@ const currentVersion uint = 1 // NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // The name should be a base64 encoding of the users public key. Returns the // EventModel based on IndexedDb and the database name as reported by IndexedDb. -func NewWASMEventModel(databaseName string, encryption cryptoChannel.Cipher, +func NewWASMEventModel(databaseName string, encryption idbCrypto.Cipher, uiCallbacks bindings.ChannelUICallbacks) (channels.EventModel, error) { return newWASMModel(databaseName, encryption, uiCallbacks) } // newWASMModel creates the given [idb.Database] and returns a wasmModel. -func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, +func newWASMModel(databaseName string, encryption idbCrypto.Cipher, uiCallbacks bindings.ChannelUICallbacks) (*wasmModel, error) { // Attempt to open database object ctx, cancel := impl.NewContext() diff --git a/indexedDb/impl/channels/model.go b/indexedDb/impl/channels/model.go index e5d3e00aa5209985de60a77f5330a53208b1af88..702d489b04d4eb6bfac510a5b9e77f753f411cee 100644 --- a/indexedDb/impl/channels/model.go +++ b/indexedDb/impl/channels/model.go @@ -56,7 +56,7 @@ type Message struct { Status uint8 `json:"status"` Hidden bool `json:"hidden"` Pinned bool `json:"pinned"` // Index - Text []byte `json:"text"` + Text string `json:"text"` Type uint16 `json:"type"` Round uint64 `json:"round"` diff --git a/indexedDb/impl/dm/callbacks.go b/indexedDb/impl/dm/callbacks.go index 380f04d9953fdda65c4b0d80a66e7b40a7edc2b1..061c46a31b5667dd6c04303def1b3b1bab57a66a 100644 --- a/indexedDb/impl/dm/callbacks.go +++ b/indexedDb/impl/dm/callbacks.go @@ -17,8 +17,8 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/dm" - cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/crypto/fastRNG" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" wDm "gitlab.com/elixxir/xxdk-wasm/indexedDb/worker/dm" "gitlab.com/elixxir/xxdk-wasm/worker" "gitlab.com/xx_network/crypto/csprng" @@ -61,7 +61,7 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) { // Create new encryption cipher rng := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG) - encryption, err := cryptoChannel.NewCipherFromJSON( + encryption, err := idbCrypto.NewCipherFromJSON( []byte(msg.EncryptionJSON), rng.GetStream()) if err != nil { return []byte{}, errors.Errorf("failed to JSON unmarshal channel "+ diff --git a/indexedDb/impl/dm/implementation.go b/indexedDb/impl/dm/implementation.go index a92691878ebc4b6c21cd1d38297aca23e4109920..f40791ece46d05b397dadd6766ec455045168452 100644 --- a/indexedDb/impl/dm/implementation.go +++ b/indexedDb/impl/dm/implementation.go @@ -24,7 +24,7 @@ import ( "gitlab.com/elixxir/client/v4/cmix/rounds" "gitlab.com/elixxir/client/v4/dm" - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/crypto/message" "gitlab.com/elixxir/wasm-utils/utils" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" @@ -36,7 +36,7 @@ import ( // caller to ensure that its methods are called sequentially. type wasmModel struct { db *idb.Database - cipher cryptoChannel.Cipher + cipher idbCrypto.Cipher receivedMessageCB MessageReceivedCallback } @@ -81,7 +81,7 @@ func (w *wasmModel) upsertConversation(nickname string, // NOTE: ID is not set inside this function because we want to use the // autoincrement key by default. If you are trying to overwrite an existing // message, then you need to set it manually yourself. -func buildMessage(messageID, parentID, text []byte, partnerKey, +func buildMessage(messageID, parentID []byte, text string, partnerKey []byte, senderKey ed25519.PublicKey, timestamp time.Time, round id.Round, mType dm.MessageType, codeset uint8, status dm.Status) *Message { return &Message{ @@ -276,9 +276,8 @@ func (w *wasmModel) receiveWrapper(messageID message.ID, parentID *message.ID, n } // Handle encryption, if it is present - textBytes := []byte(data) if w.cipher != nil { - textBytes, err = w.cipher.Encrypt(textBytes) + data, err = w.cipher.Encrypt([]byte(data)) if err != nil { return 0, err } @@ -289,7 +288,7 @@ func (w *wasmModel) receiveWrapper(messageID message.ID, parentID *message.ID, n parentIdBytes = parentID.Marshal() } - msgToInsert := buildMessage(messageID.Bytes(), parentIdBytes, textBytes, + msgToInsert := buildMessage(messageID.Bytes(), parentIdBytes, data, partnerKey, senderKey, timestamp, round.ID, mType, codeset, status) uuid, err := w.upsertMessage(msgToInsert) diff --git a/indexedDb/impl/dm/init.go b/indexedDb/impl/dm/init.go index 8332866b95055e7d322308cdf8669d1be78a95ac..aabad5c593eaca751ada0e364893aa6382135f35 100644 --- a/indexedDb/impl/dm/init.go +++ b/indexedDb/impl/dm/init.go @@ -17,7 +17,7 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/dm" - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" ) @@ -35,13 +35,13 @@ type MessageReceivedCallback func( // NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // The name should be a base64 encoding of the users public key. Returns the // EventModel based on IndexedDb and the database name as reported by IndexedDb. -func NewWASMEventModel(databaseName string, encryption cryptoChannel.Cipher, +func NewWASMEventModel(databaseName string, encryption idbCrypto.Cipher, cb MessageReceivedCallback) (dm.EventModel, error) { return newWASMModel(databaseName, encryption, cb) } // newWASMModel creates the given [idb.Database] and returns a wasmModel. -func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, +func newWASMModel(databaseName string, encryption idbCrypto.Cipher, cb MessageReceivedCallback) (*wasmModel, error) { // Attempt to open database object ctx, cancel := impl.NewContext() diff --git a/indexedDb/impl/dm/model.go b/indexedDb/impl/dm/model.go index 774d011fe4987078808febd74a1657839e06dc8a..6893fc3a6a7fffd95eb31e389e8352040e797b9f 100644 --- a/indexedDb/impl/dm/model.go +++ b/indexedDb/impl/dm/model.go @@ -46,7 +46,7 @@ type Message struct { SenderPubKey []byte `json:"sender_pub_key"` // Index CodesetVersion uint8 `json:"codeset_version"` Status uint8 `json:"status"` - Text []byte `json:"text"` + Text string `json:"text"` Type uint16 `json:"type"` Round uint64 `json:"round"` } diff --git a/indexedDb/impl/state/callbacks.go b/indexedDb/impl/state/callbacks.go index fbeb674ad08e8ab9c6f0ef95fff05e96d178a7d5..73dbc2a50ec2e45237803259a50066e239acc0ef 100644 --- a/indexedDb/impl/state/callbacks.go +++ b/indexedDb/impl/state/callbacks.go @@ -12,8 +12,8 @@ package main import ( "encoding/json" "github.com/pkg/errors" + "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" - "gitlab.com/elixxir/client/v4/storage/utility" stateWorker "gitlab.com/elixxir/xxdk-wasm/indexedDb/worker/state" "gitlab.com/elixxir/xxdk-wasm/worker" ) @@ -22,7 +22,7 @@ import ( // send information between the model and the main thread. type manager struct { wtm *worker.ThreadManager - model utility.WebState + model impl.WebState } // registerCallbacks registers all the reception callbacks to manage messages diff --git a/indexedDb/impl/state/init.go b/indexedDb/impl/state/init.go index e5ba9f9add4bd0f55c092a8ddd40ce97d936ebf0..14aab3a896ea8dc248f8d7f8b9f7c2bf6b42b87d 100644 --- a/indexedDb/impl/state/init.go +++ b/indexedDb/impl/state/init.go @@ -12,7 +12,6 @@ package main import ( "github.com/hack-pad/go-indexeddb/idb" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/client/v4/storage/utility" "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" "syscall/js" ) @@ -23,7 +22,7 @@ const currentVersion uint = 1 // NewState returns a [utility.WebState] backed by IndexedDb. // The name should be a base64 encoding of the users public key. -func NewState(databaseName string) (utility.WebState, error) { +func NewState(databaseName string) (impl.WebState, error) { return newState(databaseName) } diff --git a/indexedDb/impl/utils.go b/indexedDb/impl/utils.go index 7dbf631c9deee97f3ef79b731832aab142820fbc..d9c2fa8ed1eeb32ee7a71a879e5ae2e405f01e69 100644 --- a/indexedDb/impl/utils.go +++ b/indexedDb/impl/utils.go @@ -32,6 +32,13 @@ const ( ErrDoesNotExist = "result is undefined" ) +// WebState defines an interface for setting persistent state in a KV format +// specifically for web-based implementations. +type WebState interface { + Get(key string) ([]byte, error) + Set(key string, value []byte) error +} + // NewContext builds a context for indexedDb operations. func NewContext() (context.Context, context.CancelFunc) { return context.WithTimeout(context.Background(), dbTimeout) diff --git a/indexedDb/worker/channels/init.go b/indexedDb/worker/channels/init.go index d24120aa445d6c161bf148a242439f4a6bf05eb1..d14a80ebfc5d91dd3e100e58d7ec2cb45f7d281e 100644 --- a/indexedDb/worker/channels/init.go +++ b/indexedDb/worker/channels/init.go @@ -18,8 +18,7 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/bindings" "gitlab.com/elixxir/client/v4/channels" - - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/xxdk-wasm/storage" "gitlab.com/elixxir/xxdk-wasm/worker" ) @@ -36,7 +35,7 @@ type eventUpdateCallback func(eventType int64, jsonData []byte) // the channel manager to define the path but the callback is the same // across the board. func NewWASMEventModelBuilder(wasmJsPath string, - encryption cryptoChannel.Cipher, + encryption idbCrypto.Cipher, channelCbs bindings.ChannelUICallbacks) channels.EventModelBuilder { fn := func(path string) (channels.EventModel, error) { return NewWASMEventModel(path, wasmJsPath, encryption, @@ -54,7 +53,7 @@ type NewWASMEventModelMessage struct { // NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // The name should be a base64 encoding of the users public key. -func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher, +func NewWASMEventModel(path, wasmJsPath string, encryption idbCrypto.Cipher, channelCbs bindings.ChannelUICallbacks) ( channels.EventModel, error) { databaseName := path + databaseSuffix diff --git a/indexedDb/worker/dm/init.go b/indexedDb/worker/dm/init.go index 3fd1cd13897bdc8684e2efc13750e1fed20ff000..b7afc2b2237c2258feb91084e644402e775c45f1 100644 --- a/indexedDb/worker/dm/init.go +++ b/indexedDb/worker/dm/init.go @@ -18,7 +18,7 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/dm" - cryptoChannel "gitlab.com/elixxir/crypto/channel" + idbCrypto "gitlab.com/elixxir/crypto/indexedDb" "gitlab.com/elixxir/xxdk-wasm/storage" "gitlab.com/elixxir/xxdk-wasm/worker" ) @@ -42,7 +42,7 @@ type NewWASMEventModelMessage struct { // NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // The name should be a base64 encoding of the users public key. -func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher, +func NewWASMEventModel(path, wasmJsPath string, encryption idbCrypto.Cipher, cb MessageReceivedCallback) (dm.EventModel, error) { databaseName := path + databaseSuffix diff --git a/indexedDb/worker/state/init.go b/indexedDb/worker/state/init.go index b4842ae5ca954e1bfead70a483690b88fbf1974d..3ed7ac513204b26912f17a298d320b089d1fbf4e 100644 --- a/indexedDb/worker/state/init.go +++ b/indexedDb/worker/state/init.go @@ -11,11 +11,11 @@ package dm import ( "encoding/json" + "gitlab.com/elixxir/xxdk-wasm/indexedDb/impl" "time" "github.com/pkg/errors" - "gitlab.com/elixxir/client/v4/storage/utility" "gitlab.com/elixxir/xxdk-wasm/storage" "gitlab.com/elixxir/xxdk-wasm/worker" ) @@ -29,9 +29,16 @@ type NewStateMessage struct { DatabaseName string `json:"databaseName"` } +// WebState defines an interface for setting persistent state in a KV format +// specifically for web-based implementations. +type WebState interface { + Get(key string) ([]byte, error) + Set(key string, value []byte) error +} + // NewState returns a [utility.WebState] backed by indexeddb. // The name should be a base64 encoding of the users public key. -func NewState(path, wasmJsPath string) (utility.WebState, error) { +func NewState(path, wasmJsPath string) (impl.WebState, error) { databaseName := path + databaseSuffix wh, err := worker.NewManager(wasmJsPath, "stateIndexedDb", true) diff --git a/main.go b/main.go index 5315e3738a2c8825791ac725026aa5c828a5ea44..b2a964719718eb79e9a006ec3e8b225c0e075b17 100644 --- a/main.go +++ b/main.go @@ -136,8 +136,12 @@ func setGlobals() { js.FuncOf(wasm.GetChannelNotificationReportsForMe)) js.Global().Set("GetNoMessageErr", js.FuncOf(wasm.GetNoMessageErr)) js.Global().Set("CheckNoMessageErr", js.FuncOf(wasm.CheckNoMessageErr)) - js.Global().Set("NewChannelsDatabaseCipher", - js.FuncOf(wasm.NewChannelsDatabaseCipher)) + js.Global().Set("GetNotificationReportsForMe", + js.FuncOf(wasm.GetChannelNotificationReportsForMe)) + + // wasm/cipher.go + js.Global().Set("NewDatabaseCipher", + js.FuncOf(wasm.NewDatabaseCipher)) // wasm/dm.go js.Global().Set("InitChannelsFileTransfer", @@ -150,7 +154,7 @@ func setGlobals() { js.Global().Set("NewDMClientWithIndexedDbUnsafe", js.FuncOf(wasm.NewDMClientWithIndexedDbUnsafe)) js.Global().Set("NewDMsDatabaseCipher", - js.FuncOf(wasm.NewDMsDatabaseCipher)) + js.FuncOf(wasm.NewDatabaseCipher)) // wasm/cmix.go js.Global().Set("NewCmix", js.FuncOf(wasm.NewCmix)) diff --git a/storage/password.go b/storage/password.go index 5dec9055907b819c3290be05cd07454ddd312036..95abcb4fc940890f9682ec9413bfc9eddb63295b 100644 --- a/storage/password.go +++ b/storage/password.go @@ -195,7 +195,7 @@ func verifyPassword(externalPassword string) bool { // initInternalPassword generates a new internal password, stores an encrypted // version in local storage, and returns it. func initInternalPassword(externalPassword string, - localStorage *storage.LocalStorage, csprng io.Reader, + localStorage storage.LocalStorage, csprng io.Reader, params argonParams) ([]byte, error) { internalPassword := make([]byte, internalPasswordLen) @@ -250,7 +250,7 @@ func initInternalPassword(externalPassword string, // getInternalPassword retrieves the internal password from local storage, // decrypts it, and returns it. func getInternalPassword( - externalPassword string, localStorage *storage.LocalStorage) ([]byte, error) { + externalPassword string, localStorage storage.LocalStorage) ([]byte, error) { encryptedInternalPassword, err := localStorage.Get(passwordKey) if err != nil { return nil, errors.WithMessage(err, getPasswordStorageErr) diff --git a/storage/purge.go b/storage/purge.go index df75cebf9175251d53c722565e7c1111d6d9262f..a7b7f64f6dca64d8ef69b2b84cbf976db1569675 100644 --- a/storage/purge.go +++ b/storage/purge.go @@ -16,7 +16,6 @@ import ( "github.com/hack-pad/go-indexeddb/idb" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/client/v4/storage/utility" "gitlab.com/elixxir/wasm-utils/exception" "gitlab.com/elixxir/wasm-utils/storage" ) @@ -45,17 +44,14 @@ func DecrementNumClientsRunning() { // password is required. // // Parameters: -// - args[0] - Storage directory path (string). This is the same directory -// path passed into [wasm.NewCmix]. -// - args[1] - The user-supplied password (string). This is the same password +// - args[0] - The user-supplied password (string). This is the same password // passed into [wasm.NewCmix]. // // Returns: -// - Throws an error if the password is incorrect or if not all cMix -// followers have been stopped. +// - Throws an error if the password is incorrect or if not all cMix followers +// have been stopped. func Purge(_ js.Value, args []js.Value) any { - storageDirectory := args[0].String() - userPassword := args[1].String() + userPassword := args[0].String() // Check the password if !verifyPassword(userPassword) { @@ -96,23 +92,5 @@ func Purge(_ js.Value, args []js.Value) any { n := ls.Clear() jww.DEBUG.Printf("[PURGE] Cleared %d WASM keys in local storage", n) - // Clear all EKV from local storage - keys := ls.LocalStorageUNSAFE().KeysPrefix(storageDirectory) - n = len(keys) - for _, keyName := range keys { - ls.LocalStorageUNSAFE().RemoveItem(keyName) - } - jww.DEBUG.Printf("[PURGE] Cleared %d keys with the prefix %q (for EKV)", - n, storageDirectory) - - // Clear all NDFs saved to local storage - keys = ls.LocalStorageUNSAFE().KeysPrefix(utility.NdfStorageKeyNamePrefix) - n = len(keys) - for _, keyName := range keys { - ls.LocalStorageUNSAFE().RemoveItem(keyName) - } - jww.DEBUG.Printf("[PURGE] Cleared %d keys with the prefix %q (for NDF)", - n, utility.NdfStorageKeyNamePrefix) - return nil } diff --git a/storage/version.go b/storage/version.go index 5fa7e439af29a96c66b22c92b86db42c384c121f..3a35edfd31eda105afa5e1583dcf891b511b62f8 100644 --- a/storage/version.go +++ b/storage/version.go @@ -40,7 +40,7 @@ func CheckAndStoreVersions() error { } func checkAndStoreVersions( - currentWasmVer, currentClientVer string, ls *storage.LocalStorage) error { + currentWasmVer, currentClientVer string, ls storage.LocalStorage) error { // Get the stored client version, if it exists storedClientVer, err := initOrLoadStoredSemver(clientVerKey, currentClientVer, ls) @@ -91,7 +91,7 @@ func checkAndStoreVersions( // local storage. If no version is stored, then the current version is stored // and returned. func initOrLoadStoredSemver( - key, currentVersion string, ls *storage.LocalStorage) (string, error) { + key, currentVersion string, ls storage.LocalStorage) (string, error) { storedVersion, err := ls.Get(key) if err != nil { if errors.Is(err, os.ErrNotExist) { diff --git a/wasm/channels.go b/wasm/channels.go index 13562a200cef571cad1f3d881ee172e6c5f6d399..b3535c9c8be609ab9cf992c8de440797d3ee4723 100644 --- a/wasm/channels.go +++ b/wasm/channels.go @@ -369,9 +369,9 @@ func LoadChannelsManager(_ js.Value, args []js.Value) any { // [bindings.ChannelUICallbacks]. It is a callback that informs the UI about // various events. The entire interface can be nil, but if defined, each // method must be implemented. -// - args[6] - ID of [ChannelDbCipher] object in tracker (int). Create this -// object with [NewChannelsDatabaseCipher] and get its id with -// [ChannelDbCipher.GetID]. +// - args[6] - ID of [DbCipher] object in tracker (int). Create this +// object with [NewDatabaseCipher] and get its id with +// [DbCipher.GetID]. // // Returns a promise: // - Resolves to a Javascript representation of the [ChannelsManager] object. @@ -386,7 +386,7 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any { cUI := newChannelUI(args[5]) cipherID := args[6].Int() - cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID) + cipher, err := dbCipherTrackerSingleton.get(cipherID) if err != nil { exception.ThrowTrace(err) } @@ -444,10 +444,10 @@ func NewChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) any { func newChannelsManagerWithIndexedDb(cmixID int, wasmJsPath string, privateIdentity, extensionBuilderIDsJSON []byte, notificationsID int, channelsCbs bindings.ChannelUICallbacks, - cipher *bindings.ChannelDbCipher) any { + cipher *DbCipher) any { model := channelsDb.NewWASMEventModelBuilder( - wasmJsPath, cipher, channelsCbs) + wasmJsPath, cipher.api, channelsCbs) promiseFn := func(resolve, reject func(args ...any) js.Value) { cm, err := bindings.NewChannelsManagerGoEventModel(cmixID, @@ -487,9 +487,9 @@ func newChannelsManagerWithIndexedDb(cmixID int, wasmJsPath string, // [bindings.ChannelUICallbacks]. It is a callback that informs the UI about // various events. The entire interface can be nil, but if defined, each // method must be implemented. -// - args[6] - ID of [ChannelDbCipher] object in tracker (int). Create this -// object with [NewChannelsDatabaseCipher] and get its id with -// [ChannelDbCipher.GetID]. +// - args[6] - ID of [DbCipher] object in tracker (int). Create this +// object with [NewDatabaseCipher] and get its id with +// [DbCipher.GetID]. // // Returns a promise: // - Resolves to a Javascript representation of the [ChannelsManager] object. @@ -504,7 +504,7 @@ func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any { channelsCbs := newChannelUI(args[5]) cipherID := args[6].Int() - cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID) + cipher, err := dbCipherTrackerSingleton.get(cipherID) if err != nil { exception.ThrowTrace(err) } @@ -557,10 +557,10 @@ func LoadChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) any { func loadChannelsManagerWithIndexedDb(cmixID int, wasmJsPath, storageTag string, extensionBuilderIDsJSON []byte, notificationsID int, channelsCbs bindings.ChannelUICallbacks, - cipher *bindings.ChannelDbCipher) any { + cipher *DbCipher) any { model := channelsDb.NewWASMEventModelBuilder( - wasmJsPath, cipher, channelsCbs) + wasmJsPath, cipher.api, channelsCbs) promiseFn := func(resolve, reject func(args ...any) js.Value) { cm, err := bindings.LoadChannelsManagerGoEventModel( @@ -2315,145 +2315,6 @@ type MessageAndError struct { Error string } -//////////////////////////////////////////////////////////////////////////////// -// Channel Cipher // -//////////////////////////////////////////////////////////////////////////////// - -// ChannelDbCipher wraps the [bindings.ChannelDbCipher] object so its methods -// can be wrapped to be Javascript compatible. -type ChannelDbCipher struct { - api *bindings.ChannelDbCipher -} - -// newChannelDbCipherJS creates a new Javascript compatible object -// (map[string]any) that matches the [ChannelDbCipher] structure. -func newChannelDbCipherJS(api *bindings.ChannelDbCipher) map[string]any { - c := ChannelDbCipher{api} - channelDbCipherMap := map[string]any{ - "GetID": js.FuncOf(c.GetID), - "Encrypt": js.FuncOf(c.Encrypt), - "Decrypt": js.FuncOf(c.Decrypt), - "MarshalJSON": js.FuncOf(c.MarshalJSON), - "UnmarshalJSON": js.FuncOf(c.UnmarshalJSON), - } - - return channelDbCipherMap -} - -// NewChannelsDatabaseCipher constructs a [ChannelDbCipher] object. -// -// Parameters: -// - args[0] - The tracked [Cmix] object ID (int). -// - args[1] - The password for storage. This should be the same password -// passed into [NewCmix] (Uint8Array). -// - args[2] - The maximum size of a payload to be encrypted. A payload passed -// into [ChannelDbCipher.Encrypt] that is larger than this value will result -// in an error (int). -// -// Returns: -// - JavaScript representation of the [ChannelDbCipher] object. -// - Throws an error if creating the cipher fails. -func NewChannelsDatabaseCipher(_ js.Value, args []js.Value) any { - cmixId := args[0].Int() - password := utils.CopyBytesToGo(args[1]) - plaintTextBlockSize := args[2].Int() - - cipher, err := bindings.NewChannelsDatabaseCipher( - cmixId, password, plaintTextBlockSize) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return newChannelDbCipherJS(cipher) -} - -// GetID returns the ID for this [bindings.ChannelDbCipher] in the -// channelDbCipherTracker. -// -// Returns: -// - Tracker ID (int). -func (c *ChannelDbCipher) GetID(js.Value, []js.Value) any { - return c.api.GetID() -} - -// Encrypt will encrypt the raw data. It will return a ciphertext. Padding is -// done on the plaintext so all encrypted data looks uniform at rest. -// -// Parameters: -// - args[0] - The data to be encrypted (Uint8Array). This must be smaller -// than the block size passed into [NewChannelsDatabaseCipher]. If it is -// larger, this will return an error. -// -// Returns: -// - The ciphertext of the plaintext passed in (Uint8Array). -// - Throws an error if it fails to encrypt the plaintext. -func (c *ChannelDbCipher) Encrypt(_ js.Value, args []js.Value) any { - ciphertext, err := c.api.Encrypt(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(ciphertext) -} - -// Decrypt will decrypt the passed in encrypted value. The plaintext will be -// returned by this function. Any padding will be discarded within this -// function. -// -// Parameters: -// - args[0] - the encrypted data returned by [ChannelDbCipher.Encrypt] -// (Uint8Array). -// -// Returns: -// - The plaintext of the ciphertext passed in (Uint8Array). -// - Throws an error if it fails to encrypt the plaintext. -func (c *ChannelDbCipher) Decrypt(_ js.Value, args []js.Value) any { - plaintext, err := c.api.Decrypt(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(plaintext) -} - -// MarshalJSON marshals the cipher into valid JSON. -// -// Returns: -// - JSON of the cipher (Uint8Array). -// - Throws an error if marshalling fails. -func (c *ChannelDbCipher) MarshalJSON(js.Value, []js.Value) any { - data, err := c.api.MarshalJSON() - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(data) -} - -// UnmarshalJSON unmarshalls JSON into the cipher. -// -// Note that this function does not transfer the internal RNG. Use -// [channel.NewCipherFromJSON] to properly reconstruct a cipher from JSON. -// -// Parameters: -// - args[0] - JSON data to unmarshal (Uint8Array). -// -// Returns: -// - JSON of the cipher (Uint8Array). -// - Throws an error if marshalling fails. -func (c *ChannelDbCipher) UnmarshalJSON(_ js.Value, args []js.Value) any { - err := c.api.UnmarshalJSON(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - return nil -} - // newChannelUI maps the methods on the Javascript object to the // channelUI callbacks implementation struct. func newChannelUI(cbImpl js.Value) *channelUI { diff --git a/wasm/channels_test.go b/wasm/channels_test.go index 1b4d9eb555177951ea66e9fb81ed7420418f2b22..9ebbc691debd6d330a9cadc3a4aa4c9c62d342ad 100644 --- a/wasm/channels_test.go +++ b/wasm/channels_test.go @@ -60,47 +60,6 @@ func Test_ChannelsManagerMethods(t *testing.T) { } } -// Tests that the map representing ChannelDbCipher returned by -// newChannelDbCipherJS contains all of the methods on ChannelDbCipher. -func Test_newChannelDbCipherJS(t *testing.T) { - cipherType := reflect.TypeOf(&ChannelDbCipher{}) - - cipher := newChannelDbCipherJS(&bindings.ChannelDbCipher{}) - if len(cipher) != cipherType.NumMethod() { - t.Errorf("ChannelDbCipher JS object does not have all methods."+ - "\nexpected: %d\nreceived: %d", cipherType.NumMethod(), len(cipher)) - } - - for i := 0; i < cipherType.NumMethod(); i++ { - method := cipherType.Method(i) - - if _, exists := cipher[method.Name]; !exists { - t.Errorf("Method %s does not exist.", method.Name) - } - } -} - -// Tests that ChannelDbCipher has all the methods that -// [bindings.ChannelDbCipher] has. -func Test_ChannelDbCipherMethods(t *testing.T) { - cipherType := reflect.TypeOf(&ChannelDbCipher{}) - binCipherType := reflect.TypeOf(&bindings.ChannelDbCipher{}) - - if binCipherType.NumMethod() != cipherType.NumMethod() { - t.Errorf("WASM ChannelDbCipher object does not have all methods from "+ - "bindings.\nexpected: %d\nreceived: %d", - binCipherType.NumMethod(), cipherType.NumMethod()) - } - - for i := 0; i < binCipherType.NumMethod(); i++ { - method := binCipherType.Method(i) - - if _, exists := cipherType.MethodByName(method.Name); !exists { - t.Errorf("Method %s does not exist.", method.Name) - } - } -} - type jsIdentity struct { pubKey js.Value codeset js.Value diff --git a/wasm/cipher.go b/wasm/cipher.go new file mode 100644 index 0000000000000000000000000000000000000000..5504d2f3a426c78640ff1611e025103e91fb876e --- /dev/null +++ b/wasm/cipher.go @@ -0,0 +1,232 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file. // +//////////////////////////////////////////////////////////////////////////////// + +//go:build js && wasm + +package wasm + +import ( + "github.com/pkg/errors" + "gitlab.com/elixxir/client/v4/bindings" + "gitlab.com/elixxir/client/v4/storage/utility" + "gitlab.com/elixxir/crypto/indexedDb" + "gitlab.com/elixxir/wasm-utils/exception" + "gitlab.com/elixxir/wasm-utils/utils" + "sync" + "syscall/js" +) + +// dbCipherTrackerSingleton is used to track DbCipher objects +// so that they can be referenced by ID back over the bindings. +var dbCipherTrackerSingleton = &DbCipherTracker{ + tracked: make(map[int]*DbCipher), + count: 0, +} + +// DbCipherTracker is a singleton used to keep track of extant +// DbCipher objects, preventing race conditions created by passing it +// over the bindings. +type DbCipherTracker struct { + tracked map[int]*DbCipher + count int + mux sync.RWMutex +} + +// create creates a DbCipher from a [indexedDb.Cipher], assigns it a unique +// ID, and adds it to the DbCipherTracker. +func (ct *DbCipherTracker) create(c indexedDb.Cipher) *DbCipher { + ct.mux.Lock() + defer ct.mux.Unlock() + + chID := ct.count + ct.count++ + + ct.tracked[chID] = &DbCipher{ + api: c, + id: chID, + } + + return ct.tracked[chID] +} + +// get an DbCipher from the DbCipherTracker given its ID. +func (ct *DbCipherTracker) get(id int) (*DbCipher, error) { + ct.mux.RLock() + defer ct.mux.RUnlock() + + c, exist := ct.tracked[id] + if !exist { + return nil, errors.Errorf( + "Cannot get DbCipher for ID %d, does not exist", id) + } + + return c, nil +} + +// delete removes a DbCipherTracker from the DbCipherTracker. +func (ct *DbCipherTracker) delete(id int) { + ct.mux.Lock() + defer ct.mux.Unlock() + + delete(ct.tracked, id) +} + +// DbCipher wraps the [indexedDb.Cipher] object so its methods +// can be wrapped to be Javascript compatible. +type DbCipher struct { + api indexedDb.Cipher + salt []byte + id int +} + +// newDbCipherJS creates a new Javascript compatible object +// (map[string]any) that matches the [DbCipher] structure. +func newDbCipherJS(c *DbCipher) map[string]any { + DbCipherMap := map[string]any{ + "GetID": js.FuncOf(c.GetID), + "Encrypt": js.FuncOf(c.Encrypt), + "Decrypt": js.FuncOf(c.Decrypt), + "MarshalJSON": js.FuncOf(c.MarshalJSON), + "UnmarshalJSON": js.FuncOf(c.UnmarshalJSON), + } + + return DbCipherMap +} + +// NewDatabaseCipher constructs a [DbCipher] object. +// +// Parameters: +// - args[0] - The tracked [Cmix] object ID (int). +// - args[1] - The password for storage. This should be the same password +// passed into [NewCmix] (Uint8Array). +// - args[2] - The maximum size of a payload to be encrypted. A payload passed +// into [DbCipher.Encrypt] that is larger than this value will result +// in an error (int). +// +// Returns: +// - JavaScript representation of the [DbCipher] object. +// - Throws an error if creating the cipher fails. +func NewDatabaseCipher(_ js.Value, args []js.Value) any { + cmixId := args[0].Int() + password := utils.CopyBytesToGo(args[1]) + plaintTextBlockSize := args[2].Int() + + // Get user from singleton + user, err := bindings.GetCMixInstance(cmixId) + if err != nil { + exception.ThrowTrace(err) + return nil + } + + // Generate RNG + stream := user.GetRng().GetStream() + + // Load or generate a salt + salt, err := utility.NewOrLoadSalt( + user.GetStorage().GetKV(), stream) + if err != nil { + exception.ThrowTrace(err) + return nil + } + + // Construct a cipher + c, err := indexedDb.NewCipher( + password, salt, plaintTextBlockSize, stream) + if err != nil { + exception.ThrowTrace(err) + return nil + } + + // Add to singleton and return + return newDbCipherJS(dbCipherTrackerSingleton.create(c)) +} + +// GetID returns the ID for this [DbCipher] in the +// DbCipherTracker. +// +// Returns: +// - Tracker ID (int). +func (c *DbCipher) GetID(js.Value, []js.Value) any { + return c.id +} + +// Encrypt will encrypt the raw data. It will return a ciphertext. Padding is +// done on the plaintext so all encrypted data looks uniform at rest. +// +// Parameters: +// - args[0] - The data to be encrypted (Uint8Array). This must be smaller +// than the block size passed into [NewDatabaseCipher]. If it is +// larger, this will return an error. +// +// Returns: +// - The ciphertext of the plaintext passed in (String). +// - Throws an error if it fails to encrypt the plaintext. +func (c *DbCipher) Encrypt(_ js.Value, args []js.Value) any { + ciphertext, err := c.api.Encrypt(utils.CopyBytesToGo(args[0])) + if err != nil { + exception.ThrowTrace(err) + return nil + } + + return ciphertext +} + +// Decrypt will decrypt the passed in encrypted value. The plaintext will be +// returned by this function. Any padding will be discarded within this +// function. +// +// Parameters: +// - args[0] - the encrypted data returned by [DbCipher.Encrypt] +// (String). +// +// Returns: +// - The plaintext of the ciphertext passed in (Uint8Array). +// - Throws an error if it fails to encrypt the plaintext. +func (c *DbCipher) Decrypt(_ js.Value, args []js.Value) any { + plaintext, err := c.api.Decrypt(args[0].String()) + if err != nil { + exception.ThrowTrace(err) + return nil + } + + return utils.CopyBytesToJS(plaintext) +} + +// MarshalJSON marshals the cipher into valid JSON. +// +// Returns: +// - JSON of the cipher (Uint8Array). +// - Throws an error if marshalling fails. +func (c *DbCipher) MarshalJSON(js.Value, []js.Value) any { + data, err := c.api.MarshalJSON() + if err != nil { + exception.ThrowTrace(err) + return nil + } + + return utils.CopyBytesToJS(data) +} + +// UnmarshalJSON unmarshalls JSON into the cipher. +// +// Note that this function does not transfer the internal RNG. Use +// [indexedDb.NewCipherFromJSON] to properly reconstruct a cipher from JSON. +// +// Parameters: +// - args[0] - JSON data to unmarshal (Uint8Array). +// +// Returns: +// - JSON of the cipher (Uint8Array). +// - Throws an error if marshalling fails. +func (c *DbCipher) UnmarshalJSON(_ js.Value, args []js.Value) any { + err := c.api.UnmarshalJSON(utils.CopyBytesToGo(args[0])) + if err != nil { + exception.ThrowTrace(err) + return nil + } + return nil +} diff --git a/wasm/cipher_test.go b/wasm/cipher_test.go new file mode 100644 index 0000000000000000000000000000000000000000..0f83461509bc0f70ff5afd7104de9ab5fb3e6e11 --- /dev/null +++ b/wasm/cipher_test.go @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file. // +//////////////////////////////////////////////////////////////////////////////// + +//go:build js && wasm + +package wasm + +import ( + "reflect" + "testing" +) + +// Tests that the map representing DbCipher returned by +// newDbCipherJS contains all the methods on DbCipher. +func Test_newChannelDbCipherJS(t *testing.T) { + cipherType := reflect.TypeOf(&DbCipher{}) + + cipher := newDbCipherJS(&DbCipher{}) + if len(cipher) != cipherType.NumMethod() { + t.Errorf("DbCipher JS object does not have all methods."+ + "\nexpected: %d\nreceived: %d", cipherType.NumMethod(), len(cipher)) + } + + for i := 0; i < cipherType.NumMethod(); i++ { + method := cipherType.Method(i) + + if _, exists := cipher[method.Name]; !exists { + t.Errorf("Method %s does not exist.", method.Name) + } + } +} diff --git a/wasm/dm.go b/wasm/dm.go index 53d123a26c3f92743f9868e03017e7c1858ca9bb..3786b0df32a68b9b0b70c09a9d5664263df3792f 100644 --- a/wasm/dm.go +++ b/wasm/dm.go @@ -128,8 +128,8 @@ func NewDMClient(_ js.Value, args []js.Value) any { // The row in the database that was updated can be found using the UUID. // messageUpdate is true if the message already exists and was edited. // conversationUpdate is true if the Conversation was created or modified. -// - args[4] - ID of [DMDbCipher] object in tracker (int). Create this object -// with [NewDMsDatabaseCipher] and get its id with [DMDbCipher.GetID]. +// - args[4] - ID of [DbCipher] object in tracker (int). Create this object +// with [NewDatabaseCipher] and get its id with [DbCipher.GetID]. // // Returns: // - Resolves to a Javascript representation of the [DMClient] object. @@ -142,7 +142,7 @@ func NewDMClientWithIndexedDb(_ js.Value, args []js.Value) any { messageReceivedCB := args[3] cipherID := args[4].Int() - cipher, err := bindings.GetDMDbCipherTrackerFromID(cipherID) + cipher, err := dbCipherTrackerSingleton.get(cipherID) if err != nil { exception.ThrowTrace(err) } @@ -190,7 +190,7 @@ func NewDMClientWithIndexedDbUnsafe(_ js.Value, args []js.Value) any { } func newDMClientWithIndexedDb(cmixID int, wasmJsPath string, - privateIdentity []byte, cb js.Value, cipher *bindings.DMDbCipher) any { + privateIdentity []byte, cb js.Value, cipher *DbCipher) any { messageReceivedCB := func(uuid uint64, pubKey ed25519.PublicKey, messageUpdate, conversationUpdate bool) { @@ -206,7 +206,7 @@ func newDMClientWithIndexedDb(cmixID int, wasmJsPath string, } dmPath := base64.RawStdEncoding.EncodeToString(pi.PubKey[:]) model, err := indexDB.NewWASMEventModel( - dmPath, wasmJsPath, cipher, messageReceivedCB) + dmPath, wasmJsPath, cipher.api, messageReceivedCB) if err != nil { reject(exception.NewTrace(err)) } @@ -671,35 +671,6 @@ func DecodeDMShareURL(_ js.Value, args []js.Value) any { return utils.CopyBytesToJS(report) } -//////////////////////////////////////////////////////////////////////////////// -// Channel Receiving Logic and Callback Registration // -//////////////////////////////////////////////////////////////////////////////// - -// channelMessageReceptionCallback wraps Javascript callbacks to adhere to the -// [bindings.ChannelMessageReceptionCallback] interface. -type dmReceptionCallback struct { - callback func(args ...any) js.Value -} - -// Callback returns the context for a channel message. -// -// Parameters: -// - receivedChannelMessageReport - Returns the JSON of -// [bindings.ReceivedChannelMessageReport] (Uint8Array). -// - err - Returns an error on failure (Error). -// -// Returns: -// - It must return a unique UUID for the message that it can be referenced by -// later (int). -func (cmrCB *dmReceptionCallback) Callback( - receivedChannelMessageReport []byte, err error) int { - uuid := cmrCB.callback( - utils.CopyBytesToJS(receivedChannelMessageReport), - exception.NewTrace(err)) - - return uuid.Int() -} - //////////////////////////////////////////////////////////////////////////////// // Event Model Logic // //////////////////////////////////////////////////////////////////////////////// @@ -990,146 +961,6 @@ func (em *dmReceiver) GetConversations() []byte { return conversationsBytes } -//////////////////////////////////////////////////////////////////////////////// -// DM DB Cipher // -//////////////////////////////////////////////////////////////////////////////// - -// DMDbCipher wraps the [bindings.DMDbCipher] object so its methods -// can be wrapped to be Javascript compatible. -type DMDbCipher struct { - api *bindings.DMDbCipher -} - -// newDMDbCipherJS creates a new Javascript compatible object -// (map[string]any) that matches the [DMDbCipher] structure. -func newDMDbCipherJS(api *bindings.DMDbCipher) map[string]any { - c := DMDbCipher{api} - channelDbCipherMap := map[string]any{ - "GetID": js.FuncOf(c.GetID), - "Encrypt": js.FuncOf(c.Encrypt), - "Decrypt": js.FuncOf(c.Decrypt), - "MarshalJSON": js.FuncOf(c.MarshalJSON), - "UnmarshalJSON": js.FuncOf(c.UnmarshalJSON), - } - - return channelDbCipherMap -} - -// NewDMsDatabaseCipher constructs a [DMDbCipher] object. -// -// Parameters: -// - args[0] - The tracked [Cmix] object ID (int). -// - args[1] - The password for storage. This should be the same password -// passed into [NewCmix] (Uint8Array). -// - args[2] - The maximum size of a payload to be encrypted. A payload passed -// into [DMDbCipher.Encrypt] that is larger than this value will result -// in an error (int). -// -// Returns: -// - JavaScript representation of the [DMDbCipher] object. -// - Throws an error if creating the cipher fails. -func NewDMsDatabaseCipher(_ js.Value, args []js.Value) any { - cmixId := args[0].Int() - password := utils.CopyBytesToGo(args[1]) - plaintTextBlockSize := args[2].Int() - - cipher, err := bindings.NewDMsDatabaseCipher( - cmixId, password, plaintTextBlockSize) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return newDMDbCipherJS(cipher) -} - -// GetID returns the ID for this [bindings.DMDbCipher] in the -// channelDbCipherTracker. -// -// Returns: -// - Tracker ID (int). -func (c *DMDbCipher) GetID(js.Value, []js.Value) any { - return c.api.GetID() -} - -// Encrypt will encrypt the raw data. It will return a ciphertext. Padding is -// done on the plaintext so all encrypted data looks uniform at rest. -// -// Parameters: -// - args[0] - The data to be encrypted (Uint8Array). This must be smaller -// than the block size passed into [NewDMsDatabaseCipher]. If it is -// larger, this will return an error. -// -// Returns: -// - The ciphertext of the plaintext passed in (Uint8Array). -// - Throws an error if it fails to encrypt the plaintext. -func (c *DMDbCipher) Encrypt(_ js.Value, args []js.Value) any { - ciphertext, err := c.api.Encrypt(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(ciphertext) -} - -// Decrypt will decrypt the passed in encrypted value. The plaintext will be -// returned by this function. Any padding will be discarded within this -// function. -// -// Parameters: -// - args[0] - the encrypted data returned by [DMDbCipher.Encrypt] -// (Uint8Array). -// -// Returns: -// - The plaintext of the ciphertext passed in (Uint8Array). -// - Throws an error if it fails to encrypt the plaintext. -func (c *DMDbCipher) Decrypt(_ js.Value, args []js.Value) any { - plaintext, err := c.api.Decrypt(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(plaintext) -} - -// MarshalJSON marshals the cipher into valid JSON. -// -// Returns: -// - JSON of the cipher (Uint8Array). -// - Throws an error if marshalling fails. -func (c *DMDbCipher) MarshalJSON(js.Value, []js.Value) any { - data, err := c.api.MarshalJSON() - if err != nil { - exception.ThrowTrace(err) - return nil - } - - return utils.CopyBytesToJS(data) -} - -// UnmarshalJSON unmarshalls JSON into the cipher. This function adheres to the -// json.Unmarshaler interface. -// -// Note that this function does not transfer the internal RNG. Use -// [channel.NewCipherFromJSON] to properly reconstruct a cipher from JSON. -// -// Parameters: -// - args[0] - JSON data to unmarshal (Uint8Array). -// -// Returns: -// - JSON of the cipher (Uint8Array). -// - Throws an error if marshalling fails. -func (c *DMDbCipher) UnmarshalJSON(_ js.Value, args []js.Value) any { - err := c.api.UnmarshalJSON(utils.CopyBytesToGo(args[0])) - if err != nil { - exception.ThrowTrace(err) - return nil - } - return nil -} - // truncate truncates the string to length n. If the string is trimmed, then // ellipses (...) are appended. func truncate(s string, n int) string { diff --git a/wasm/dm_test.go b/wasm/dm_test.go index 58f837ea0bb857deaede29fd9f5c37f4cd936e34..f959c9463fe793d7cac78927dcdc8eba5980d5f7 100644 --- a/wasm/dm_test.go +++ b/wasm/dm_test.go @@ -62,43 +62,3 @@ func Test_DMClientMethods(t *testing.T) { } } } - -// Tests that the map representing DMDbCipher returned by newDMDbCipherJS -// contains all of the methods on DMDbCipher. -func Test_newDMDbCipherJS(t *testing.T) { - cipherType := reflect.TypeOf(&DMDbCipher{}) - - cipher := newDMDbCipherJS(&bindings.DMDbCipher{}) - if len(cipher) != cipherType.NumMethod() { - t.Errorf("DMDbCipher JS object does not have all methods."+ - "\nexpected: %d\nreceived: %d", cipherType.NumMethod(), len(cipher)) - } - - for i := 0; i < cipherType.NumMethod(); i++ { - method := cipherType.Method(i) - - if _, exists := cipher[method.Name]; !exists { - t.Errorf("Method %s does not exist.", method.Name) - } - } -} - -// Tests that DMDbCipher has all the methods that [bindings.DMDbCipher] has. -func Test_DMDbCipherMethods(t *testing.T) { - cipherType := reflect.TypeOf(&DMDbCipher{}) - binCipherType := reflect.TypeOf(&bindings.DMDbCipher{}) - - if binCipherType.NumMethod() != cipherType.NumMethod() { - t.Errorf("WASM DMDbCipher object does not have all methods from "+ - "bindings.\nexpected: %d\nreceived: %d", - binCipherType.NumMethod(), cipherType.NumMethod()) - } - - for i := 0; i < binCipherType.NumMethod(); i++ { - method := binCipherType.Method(i) - - if _, exists := cipherType.MethodByName(method.Name); !exists { - t.Errorf("Method %s does not exist.", method.Name) - } - } -} diff --git a/wasm_test.go b/wasm_test.go index b415ece5623aa4e235511fb1f9cb24058e02e384..1e0494dbe4f6e08ec9276aa3b984b5c245cfa7e8 100644 --- a/wasm_test.go +++ b/wasm_test.go @@ -42,7 +42,7 @@ func TestPublicFunctions(t *testing.T) { "NewEventModel": {}, "NewChannelsManagerGoEventModel": {}, "LoadChannelsManagerGoEventModel": {}, - "GetChannelDbCipherTrackerFromID": {}, + "GetDbCipherTrackerFromID": {}, // Version functions were renamed to differentiate between WASM and // client versions