mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-08 20:38:04 -05:00
checkpoint identity encryption and decryption works fully now
This commit is contained in:
421
package-lock.json
generated
421
package-lock.json
generated
@@ -13,10 +13,11 @@
|
||||
"@ethersproject/keccak256": "^5.7.0",
|
||||
"@ethersproject/strings": "^5.7.0",
|
||||
"@floating-ui/dom": "^1.5.3",
|
||||
"@personaelabs/spartan-ecdsa": "^2.3.0",
|
||||
"@rainbow-me/rainbowkit": "^1.1.1",
|
||||
"@semaphore-protocol/group": "^3.10.1",
|
||||
"@semaphore-protocol/identity": "^3.10.1",
|
||||
"@wagmi/core": "^1.4.3",
|
||||
"@web3modal/wagmi": "^3.1.0",
|
||||
"autolinker": "^4.0.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"discreetly-interfaces": "^0.1.39",
|
||||
@@ -29,6 +30,7 @@
|
||||
"qrcode": "^1.5.3",
|
||||
"socket.io-client": "^4.7.1",
|
||||
"svelte-material-icons": "^3.0.5",
|
||||
"viem": "^1.16.5",
|
||||
"wagmi": "^1.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -288,6 +290,18 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||
@@ -745,30 +759,6 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ethereumjs/rlp": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz",
|
||||
"integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==",
|
||||
"bin": {
|
||||
"rlp": "bin/rlp"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@ethereumjs/util": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz",
|
||||
"integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==",
|
||||
"dependencies": {
|
||||
"@ethereumjs/rlp": "^4.0.1",
|
||||
"ethereum-cryptography": "^2.0.0",
|
||||
"micro-ftch": "^0.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@ethersproject/bignumber": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz",
|
||||
@@ -1221,17 +1211,6 @@
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz",
|
||||
"integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz",
|
||||
@@ -1278,17 +1257,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@personaelabs/spartan-ecdsa": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@personaelabs/spartan-ecdsa/-/spartan-ecdsa-2.3.1.tgz",
|
||||
"integrity": "sha512-svnU2vx6eEhndNOcVxCMpFec1ubEg2VAqGBEMI/QB/eWD11VdFYEmb4boRqr1HzxHMAf8H/gJzg13stATYzJRQ==",
|
||||
"dependencies": {
|
||||
"@ethereumjs/util": "^8.0.3",
|
||||
"@zk-kit/incremental-merkle-tree": "^1.0.0",
|
||||
"elliptic": "^6.5.4",
|
||||
"snarkjs": "^0.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz",
|
||||
@@ -1393,19 +1361,6 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz",
|
||||
"integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==",
|
||||
"dependencies": {
|
||||
"@noble/curves": "~1.1.0",
|
||||
"@noble/hashes": "~1.3.1",
|
||||
"@scure/base": "~1.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz",
|
||||
@@ -2454,6 +2409,136 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.21.3",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
|
||||
"integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.20.15",
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/compiler-ssr": "3.3.4",
|
||||
"@vue/reactivity-transform": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.0",
|
||||
"postcss": "^8.1.10",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
|
||||
"integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
|
||||
"integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity-transform": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
|
||||
"integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.20.15",
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity-transform/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
|
||||
"integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/runtime-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"csstype": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
|
||||
"integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@wagmi/connectors": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@wagmi/connectors/-/connectors-3.1.2.tgz",
|
||||
@@ -3089,6 +3174,145 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/@web3modal/core": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web3modal/core/-/core-3.1.0.tgz",
|
||||
"integrity": "sha512-gXzUCVr4QkgkwxYgu7PBZIUsv3MEJRsYXUDSCU0LZz5BLXnMVSj0+YPhQ1msZLPCo0el/MTPtAzwu0VEOMijTQ==",
|
||||
"dependencies": {
|
||||
"valtio": "1.11.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/polyfills": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web3modal/polyfills/-/polyfills-3.1.0.tgz",
|
||||
"integrity": "sha512-y830qGJW16k7EZe6N2LIhcLWsHv+TkgC4FuARCSQzJPvVsKi/XsKXGk4Fbrv75nETF7AqCiFrEFQVGnAc7mg8A==",
|
||||
"dependencies": {
|
||||
"buffer": "6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/scaffold": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web3modal/scaffold/-/scaffold-3.1.0.tgz",
|
||||
"integrity": "sha512-jxCsvkGvVTSds/ezwrX27Xkhlr4IPVeewKAiGxPNZKg9ZGkZ8c+7I2XZnTCKB5XQZvLgqIpGmSYhy4OqAKbHVg==",
|
||||
"dependencies": {
|
||||
"@web3modal/core": "3.1.0",
|
||||
"@web3modal/ui": "3.1.0",
|
||||
"lit": "3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/scaffold/node_modules/@lit/reactive-element": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.0.tgz",
|
||||
"integrity": "sha512-wn+2+uDcs62ROBmVAwssO4x5xue/uKD3MGGZOXL2sMxReTRIT0JXKyMXeu7gh0aJ4IJNEIG/3aOnUaQvM7BMzQ==",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.1.2-pre.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/scaffold/node_modules/lit": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-3.0.0.tgz",
|
||||
"integrity": "sha512-nQ0teRzU1Kdj++VdmttS2WvIen8M79wChJ6guRKIIym2M3Ansg3Adj9O6yuQh2IpjxiUXlNuS81WKlQ4iL3BmA==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^2.0.0",
|
||||
"lit-element": "^4.0.0",
|
||||
"lit-html": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/scaffold/node_modules/lit-element": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.0.tgz",
|
||||
"integrity": "sha512-N6+f7XgusURHl69DUZU6sTBGlIN+9Ixfs3ykkNDfgfTkDYGGOWwHAYBhDqVswnFGyWgQYR2KiSpu4J76Kccs/A==",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.1.2-pre.0",
|
||||
"@lit/reactive-element": "^2.0.0",
|
||||
"lit-html": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/scaffold/node_modules/lit-html": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.0.0.tgz",
|
||||
"integrity": "sha512-DNJIE8dNY0dQF2Gs0sdMNUppMQT2/CvV4OVnSdg7BXAsGqkVwsE5bqQ04POfkYH5dBIuGnJYdFz5fYYyNnOxiA==",
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/ui": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web3modal/ui/-/ui-3.1.0.tgz",
|
||||
"integrity": "sha512-8Av6psGG/rO5M+5s+I7l2ESUWfeKkeXMIz/Bp2pP3a3yJ+EfO3V4kN1lO/bnbquMYvO+ETmvUXprvcBPMizSBQ==",
|
||||
"dependencies": {
|
||||
"lit": "3.0.0",
|
||||
"qrcode": "1.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/ui/node_modules/@lit/reactive-element": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.0.tgz",
|
||||
"integrity": "sha512-wn+2+uDcs62ROBmVAwssO4x5xue/uKD3MGGZOXL2sMxReTRIT0JXKyMXeu7gh0aJ4IJNEIG/3aOnUaQvM7BMzQ==",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.1.2-pre.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/ui/node_modules/lit": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-3.0.0.tgz",
|
||||
"integrity": "sha512-nQ0teRzU1Kdj++VdmttS2WvIen8M79wChJ6guRKIIym2M3Ansg3Adj9O6yuQh2IpjxiUXlNuS81WKlQ4iL3BmA==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^2.0.0",
|
||||
"lit-element": "^4.0.0",
|
||||
"lit-html": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/ui/node_modules/lit-element": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.0.tgz",
|
||||
"integrity": "sha512-N6+f7XgusURHl69DUZU6sTBGlIN+9Ixfs3ykkNDfgfTkDYGGOWwHAYBhDqVswnFGyWgQYR2KiSpu4J76Kccs/A==",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.1.2-pre.0",
|
||||
"@lit/reactive-element": "^2.0.0",
|
||||
"lit-html": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/ui/node_modules/lit-html": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.0.0.tgz",
|
||||
"integrity": "sha512-DNJIE8dNY0dQF2Gs0sdMNUppMQT2/CvV4OVnSdg7BXAsGqkVwsE5bqQ04POfkYH5dBIuGnJYdFz5fYYyNnOxiA==",
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@web3modal/wagmi": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web3modal/wagmi/-/wagmi-3.1.0.tgz",
|
||||
"integrity": "sha512-PSzhHtj2GTY+36d6lbfzl4EVeuzA4XcMOW7+/CyLFzUDpG4BI5fsKrDbc7NqZU6L6BjN9dPi/oZO/Q+PM8MrPw==",
|
||||
"dependencies": {
|
||||
"@web3modal/polyfills": "3.1.0",
|
||||
"@web3modal/scaffold": "3.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"react": ">=17",
|
||||
"react-dom": ">=17",
|
||||
"vue": ">=3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@wagmi/core": ">=1",
|
||||
"react": ">=17",
|
||||
"react-dom": ">=17",
|
||||
"viem": ">=1",
|
||||
"vue": ">=3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@zk-kit/incremental-merkle-tree": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@zk-kit/incremental-merkle-tree/-/incremental-merkle-tree-1.1.0.tgz",
|
||||
@@ -3557,11 +3781,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
|
||||
@@ -4380,25 +4599,6 @@
|
||||
"integrity": "sha512-HiRdtyKS2+VhiXvjhMvvxiMC33FJJqTA5EB2YHgFZW6v7HkK4Q9Ahv2V7O2ZPgAjw+MyCJVMQvigj13H8t+wvA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||
"dependencies": {
|
||||
"bn.js": "^4.11.9",
|
||||
"brorand": "^1.1.0",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.1",
|
||||
"inherits": "^2.0.4",
|
||||
"minimalistic-assert": "^1.0.1",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/elliptic/node_modules/bn.js": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@@ -5018,17 +5218,6 @@
|
||||
"fast-safe-stringify": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ethereum-cryptography": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz",
|
||||
"integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==",
|
||||
"dependencies": {
|
||||
"@noble/curves": "1.1.0",
|
||||
"@noble/hashes": "1.3.1",
|
||||
"@scure/bip32": "1.3.1",
|
||||
"@scure/bip39": "1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-6.8.0.tgz",
|
||||
@@ -5647,16 +5836,6 @@
|
||||
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
|
||||
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
|
||||
},
|
||||
"node_modules/hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
"integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
|
||||
"dependencies": {
|
||||
"hash.js": "^1.0.3",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hoopy": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||
@@ -6905,11 +7084,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/micro-ftch": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz",
|
||||
"integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg=="
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
@@ -6977,11 +7151,6 @@
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||
},
|
||||
"node_modules/minimalistic-crypto-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@@ -7087,7 +7256,7 @@
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -7443,7 +7612,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -7568,7 +7737,7 @@
|
||||
"version": "8.4.31",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
||||
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -8046,7 +8215,6 @@
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
||||
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
},
|
||||
@@ -8058,7 +8226,6 @@
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.0"
|
||||
@@ -8482,7 +8649,6 @@
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
@@ -9955,6 +10121,19 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
|
||||
"integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/compiler-sfc": "3.3.4",
|
||||
"@vue/runtime-dom": "3.3.4",
|
||||
"@vue/server-renderer": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
|
||||
|
||||
@@ -63,10 +63,11 @@
|
||||
"@ethersproject/keccak256": "^5.7.0",
|
||||
"@ethersproject/strings": "^5.7.0",
|
||||
"@floating-ui/dom": "^1.5.3",
|
||||
"@personaelabs/spartan-ecdsa": "^2.3.0",
|
||||
"@rainbow-me/rainbowkit": "^1.1.1",
|
||||
"@semaphore-protocol/group": "^3.10.1",
|
||||
"@semaphore-protocol/identity": "^3.10.1",
|
||||
"@wagmi/core": "^1.4.3",
|
||||
"@web3modal/wagmi": "^3.1.0",
|
||||
"autolinker": "^4.0.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"discreetly-interfaces": "^0.1.39",
|
||||
@@ -79,6 +80,7 @@
|
||||
"qrcode": "^1.5.3",
|
||||
"socket.io-client": "^4.7.1",
|
||||
"svelte-material-icons": "^3.0.5",
|
||||
"viem": "^1.16.5",
|
||||
"wagmi": "^1.4.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,13 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>%sveltekit.error.message%</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #1f1f1f;
|
||||
color: #f1f1f1;
|
||||
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Something didn't work right</h1>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { identityExists } from '$lib/stores';
|
||||
import { getIdentityBackup } from '$lib/utils/';
|
||||
|
||||
$: id = getIdentityBackup();
|
||||
$: identityBackupExists = id ? true : false;
|
||||
$: encodedIdentity = 'data:text/json;charset=utf-8,' + encodeURIComponent(id!);
|
||||
|
||||
let revealIdentity = false;
|
||||
@@ -26,22 +26,25 @@
|
||||
</script>
|
||||
|
||||
<div class="m-2 sm:m-3 flex flex-col gap-4">
|
||||
{#if identityBackupExists}
|
||||
{#if $identityExists == 'safe' || $identityExists == 'unsafe'}
|
||||
<a class="btn variant-ghost-success" href={encodedIdentity} download="Discreetly_Identity.json"
|
||||
>Download Identity Backup as JSON</a
|
||||
>
|
||||
{#if !revealIdentity}
|
||||
<div class="btn variant-ghost-success" on:click={reveal}>Show Identity</div>
|
||||
{:else}
|
||||
<div class="btn variant-ghost-success" on:click={reveal}>Hide Identity</div>
|
||||
<textarea id="reveleadIdentity" class="textarea text-sm" rows="9" value={id} />
|
||||
{/if}
|
||||
{:else if $identityExists == 'encrypted'}
|
||||
<p class="h5 text-primary-500">
|
||||
Identity exists but is encrypted. Please unlock your keystore to reveal your identity.
|
||||
</p>
|
||||
{:else}
|
||||
<div class="text-sm text-primary-500">
|
||||
Error getting your identity backup. Please contact the developers for help.
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !revealIdentity}
|
||||
<div class="btn variant-ghost-success" on:click={reveal}>Show Identity</div>
|
||||
{:else}
|
||||
<div class="btn variant-ghost-success" on:click={reveal}>Hide Identity</div>
|
||||
<textarea id="reveleadIdentity" class="textarea text-sm" rows="9" value={id} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h2 class="h2 my-2 md:my-3 text-center">{heading}</h2>
|
||||
{/if}
|
||||
<slot name="header" />
|
||||
<div class="flex flex-col gap-2 md:gap-5 max-w-xl w-full mx-auto pb-3">
|
||||
<div class="flex flex-col gap-2 md:gap-5 max-w-5xl w-full mx-auto pb-3">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
101
src/lib/components/Gateways/EthereumWallet.svelte
Normal file
101
src/lib/components/Gateways/EthereumWallet.svelte
Normal file
@@ -0,0 +1,101 @@
|
||||
<script lang="ts">
|
||||
import { createWeb3Modal, defaultWagmiConfig } from '@web3modal/wagmi';
|
||||
import { getAccount, signMessage, watchAccount, disconnect, Config } from '@wagmi/core';
|
||||
import { mainnet, arbitrum, optimism, base, polygon } from '@wagmi/core/chains';
|
||||
import { onMount } from 'svelte';
|
||||
import { getCommitment } from '$lib/utils';
|
||||
import type { Web3Modal } from '@web3modal/wagmi/dist/types/src/client';
|
||||
import { alertQueue, configStore, selectedServer } from '$lib/stores';
|
||||
import { getEthAddressRoomNames } from '$lib/services/server';
|
||||
|
||||
const projectId = 'fcc228af1d77425f1482f07a961fb32d';
|
||||
let modal: Web3Modal;
|
||||
|
||||
let btnEl: HTMLElement;
|
||||
let address: string = '';
|
||||
let loadingRooms: boolean = false;
|
||||
let groups: string[] = [];
|
||||
let isConnected = false;
|
||||
const chains = [mainnet, arbitrum, optimism, base, polygon];
|
||||
const metadata = {
|
||||
name: 'Discreetly',
|
||||
description: 'Join Discreetly via your Ethereum address.',
|
||||
url: 'https://app.discreetly.chat',
|
||||
icons: ['https://avatars.githubusercontent.com/u/37784886']
|
||||
};
|
||||
|
||||
let wagmiConfig = defaultWagmiConfig({ chains, projectId, metadata });
|
||||
|
||||
async function proveOwnership() {
|
||||
const commitment = getCommitment();
|
||||
if (commitment) {
|
||||
const signature = await signMessage({
|
||||
message: commitment
|
||||
});
|
||||
} else {
|
||||
alertQueue.enqueue('Error getting Identity');
|
||||
}
|
||||
}
|
||||
|
||||
function connect() {
|
||||
if (getAccount().isConnected) {
|
||||
disconnect();
|
||||
} else {
|
||||
modal.open();
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
modal = createWeb3Modal({ wagmiConfig, projectId, chains });
|
||||
btnEl?.addEventListener('click', connect);
|
||||
watchAccount((account) => {
|
||||
address = account.address ?? '';
|
||||
if (account.isConnected) {
|
||||
btnEl!.innerText = 'Disconnect';
|
||||
loadingRooms = true;
|
||||
getEthAddressRoomNames($selectedServer, address)
|
||||
.then((groupNames) => {
|
||||
loadingRooms = false;
|
||||
groups = groupNames;
|
||||
})
|
||||
.finally(() => {
|
||||
loadingRooms = false;
|
||||
});
|
||||
isConnected = true;
|
||||
} else {
|
||||
btnEl!.innerText = 'Connect';
|
||||
isConnected = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-3 justify-between">
|
||||
<div>
|
||||
<h3 class="h4 mb-2">Step 1: Connect your wallet</h3>
|
||||
<button bind:this={btnEl} class="btn variant-outline-tertiary">Connect</button>
|
||||
</div>
|
||||
{#if isConnected}
|
||||
<div>
|
||||
<p class="h6">Your connected address is: {address}</p>
|
||||
</div>
|
||||
{#if groups.length > 0 || $configStore.beta}
|
||||
<p>You are eligible for the following Ethereum Groups:</p>
|
||||
<ul>
|
||||
{#each groups as group}
|
||||
<li>{group}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<div>
|
||||
<h3 class="h4 mb-2">
|
||||
Step 2: Sign your Identity Commitment to prove ownership of this address
|
||||
</h3>
|
||||
<button on:click={proveOwnership} id="btn" class="btn variant-outline-success">Sign</button>
|
||||
</div>
|
||||
{:else if loadingRooms}
|
||||
<p>Loading rooms...</p>
|
||||
{:else}
|
||||
<p>You are not eligible for any Ethereum Groups.</p>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
@@ -1,9 +1,8 @@
|
||||
<script lang="ts">
|
||||
import SelectServer from '$lib/components/SelectServer.svelte';
|
||||
import { alertAll } from '$lib/utils';
|
||||
import { inviteCode } from '$lib/utils/inviteCode';
|
||||
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { alertQueue } from '$lib/stores';
|
||||
export let code = '';
|
||||
|
||||
let acceptedRoomNames: string[] = [];
|
||||
let loading = false;
|
||||
let err: string | undefined;
|
||||
@@ -13,13 +12,13 @@
|
||||
inviteCode(code)
|
||||
.then(({ acceptedRoomNames, err }) => {
|
||||
if (err) {
|
||||
alertAll(err);
|
||||
alertQueue.enqueue(err);
|
||||
} else {
|
||||
acceptedRoomNames = acceptedRoomNames;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alertAll(err);
|
||||
alertQueue.enqueue(err);
|
||||
})
|
||||
.finally(() => {
|
||||
loading = false;
|
||||
@@ -80,52 +79,46 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col items-center px-2 mb-2 sm:mb-4">
|
||||
<label class="label w-full" for="selectServer"
|
||||
><span class="h5">Select or Add a Server</span>
|
||||
<SelectServer />
|
||||
</label>
|
||||
<label class="label mt-3" for="inviteCode">
|
||||
<span class="h5">Invite Code</span>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Invite Code"
|
||||
id="inviteCode"
|
||||
bind:value={code}
|
||||
on:keydown={(event) => inviteCodeKeyPress(event)}
|
||||
/>
|
||||
{#if !loading}
|
||||
<button
|
||||
class="btn variant-ghost-success"
|
||||
type="button"
|
||||
disabled={!code}
|
||||
on:click={() => addCode(code)}>Submit</button
|
||||
>
|
||||
{:else}
|
||||
<p class="italic">Loading...</p>
|
||||
{/if}
|
||||
</label>
|
||||
<label class="label" for="inviteCode">
|
||||
<span class="h5">Enter Invite Code:</span>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Invite Code"
|
||||
id="inviteCode"
|
||||
bind:value={code}
|
||||
on:keydown={(event) => inviteCodeKeyPress(event)}
|
||||
/>
|
||||
</label>
|
||||
{#if !loading}
|
||||
<button
|
||||
class="btn variant-ghost-success mt-3"
|
||||
type="button"
|
||||
disabled={!code}
|
||||
on:click={() => addCode(code)}>Submit</button
|
||||
>
|
||||
{:else}
|
||||
<p class="italic">Loading...</p>
|
||||
{/if}
|
||||
|
||||
{#if err}
|
||||
<aside class="p">
|
||||
<div>
|
||||
If you are having trouble and would like help, please message us on <a
|
||||
href="https://discord.gg/brJQ36KVxk"
|
||||
class="underline link">Discord</a
|
||||
>
|
||||
</div>
|
||||
</aside>
|
||||
{/if}
|
||||
{#if acceptedRoomNames.length > 0}
|
||||
<p class="text-center mt-2">You've been added to:</p>
|
||||
<div class="my-2">
|
||||
{#each acceptedRoomNames as name}
|
||||
<ins class="ins border-y border-success-800">{name}</ins>
|
||||
{/each}
|
||||
{#if err}
|
||||
<aside class="p">
|
||||
<div>
|
||||
If you are having trouble and would like help, please message us on <a
|
||||
href="https://discord.gg/brJQ36KVxk"
|
||||
class="underline link">Discord</a
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</aside>
|
||||
{/if}
|
||||
{#if acceptedRoomNames.length > 0}
|
||||
<p class="text-center mt-2">You've been added to:</p>
|
||||
<div class="my-2">
|
||||
{#each acceptedRoomNames as name}
|
||||
<ins class="ins border-y border-success-800">{name}</ins>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
aside {
|
||||
@@ -1,86 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { passwordSet, configStore, keyStore } from '$lib/stores';
|
||||
import Lock from 'svelte-material-icons/Lock.svelte';
|
||||
import LockOpen from 'svelte-material-icons/LockOpenVariant.svelte';
|
||||
import NoPassword from 'svelte-material-icons/LockOff.svelte';
|
||||
|
||||
import { getModalStore, type ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import { deriveKey, hashPassword } from '$lib/crypto/crypto';
|
||||
import { onMount } from 'svelte';
|
||||
import { alertAll, setPassword } from '$lib/utils';
|
||||
const modalStore = getModalStore();
|
||||
export let cls: string = '';
|
||||
|
||||
let minPasswordLength = 3;
|
||||
|
||||
function setPasswordModal() {
|
||||
const modal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
title: 'Set a Password',
|
||||
body: 'Set a password or pin to encrypt your identity and room passwords',
|
||||
value: '',
|
||||
valueAttr: { type: 'password', minlength: minPasswordLength, required: true },
|
||||
response: async (r: string) => {
|
||||
if (r != '' && r != null && r != undefined && r.length >= minPasswordLength) {
|
||||
setPassword(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
modalStore.trigger(modal);
|
||||
}
|
||||
|
||||
function unlock() {
|
||||
const modal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
title: 'Unlock',
|
||||
body: 'Enter your password to unlock your keystores',
|
||||
value: '',
|
||||
valueAttr: { type: 'password', minlength: 4, required: true },
|
||||
response: async (r: string) => {
|
||||
if (r != 'false' && r != '' && r != null && r != undefined) {
|
||||
const hashedPassword = await hashPassword(r);
|
||||
if ($configStore.hashedPwd == hashedPassword) {
|
||||
$keyStore = await deriveKey(r);
|
||||
} else {
|
||||
alertAll('Incorrect Password');
|
||||
$keyStore = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
modalStore.trigger(modal);
|
||||
}
|
||||
|
||||
function lock() {
|
||||
$keyStore = null;
|
||||
}
|
||||
onMount(() => {
|
||||
console.debug(
|
||||
'PadLock:',
|
||||
$passwordSet ? 'password set,' : 'password not set,',
|
||||
$keyStore !== null && $keyStore !== undefined ? 'unlocked' : 'locked'
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class={cls} id="lock">
|
||||
{#if $passwordSet}
|
||||
{#if $keyStore instanceof CryptoKey}
|
||||
<div on:click={lock} title="Unlocked, click to lock">
|
||||
<LockOpen class="w-full text-warning-300-600-token" />
|
||||
</div>
|
||||
{:else}
|
||||
<div on:click={unlock} title="Locked" class="w-full text-success-500"><Lock /></div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div on:click={setPasswordModal} title="Password not set">
|
||||
<NoPassword class="w-full text-error-500" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#lock {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Button from './button.svelte';
|
||||
import type { ButtonI } from '$lib/types';
|
||||
export let title: string;
|
||||
export let buttons: ButtonI[] = [];
|
||||
</script>
|
||||
|
||||
<div class="m-4 px-5 py-4 text-center bg-body-tertiary rounded-2">
|
||||
<h2 class="text-body-emphasis m-3">{title}</h2>
|
||||
<div class="col-lg-8 mx-auto fs-5 text-muted">
|
||||
<slot />
|
||||
</div>
|
||||
<div class="d-inline-flex gap-5 my-3">
|
||||
{#each buttons as button}
|
||||
<Button link={button.link} cls={button.cls} text={button.text} />
|
||||
{/each}
|
||||
</div>
|
||||
<div class="card">
|
||||
{#if $$slots.header}
|
||||
<header class="card-header h3"><slot name="header" /></header>
|
||||
{/if}
|
||||
{#if $$slots.description}
|
||||
<aside class="p italic px-4 pt-3"><slot name="description" /></aside>
|
||||
{/if}
|
||||
<section class="p-4"><slot /></section>
|
||||
{#if $$slots.footer}
|
||||
<footer class="card-footer"><slot name="footer" /></footer>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { addConsoleMessage } from '$lib/utils';
|
||||
import { alertQueue, configStore } from '$lib/stores';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
/**
|
||||
* Derives an encryption key from a given password using PBKDF2.
|
||||
@@ -47,14 +48,17 @@ export async function encrypt(plainText: string, key: CryptoKey): Promise<string
|
||||
key,
|
||||
encoder.encode(plainText)
|
||||
);
|
||||
console.log(encryptedContent);
|
||||
|
||||
const encryptedContentArr = new Uint8Array(encryptedContent);
|
||||
const encryptedBytes = [...iv, ...encryptedContentArr];
|
||||
|
||||
return btoa(String.fromCharCode(...encryptedBytes));
|
||||
} else if (get(configStore).hashedPwd) {
|
||||
alertQueue.enqueue('Unlock your identity with /unlock or click on the lock');
|
||||
console.error('Unlock your identity with /unlock or click on the lock');
|
||||
return null;
|
||||
} else {
|
||||
addConsoleMessage('No Password Set, please set a password with /setpassword', 'error');
|
||||
alertQueue.enqueue('No Password Set, please set a password with /setpassword');
|
||||
console.error('No password set, please set a password first');
|
||||
return null;
|
||||
}
|
||||
@@ -66,7 +70,6 @@ export async function decrypt(cipherText: string, key: CryptoKey): Promise<strin
|
||||
}
|
||||
if (key instanceof CryptoKey) {
|
||||
const decoder = new TextDecoder();
|
||||
console.log(cipherText);
|
||||
const encryptedBytes = Uint8Array.from(atob(cipherText), (c) => c.charCodeAt(0));
|
||||
|
||||
const iv = encryptedBytes.slice(0, 12);
|
||||
@@ -79,8 +82,12 @@ export async function decrypt(cipherText: string, key: CryptoKey): Promise<strin
|
||||
);
|
||||
|
||||
return decoder.decode(decryptedContent);
|
||||
} else if (get(configStore).hashedPwd) {
|
||||
alertQueue.enqueue('Unlock your identity with /unlock or click on the lock');
|
||||
console.error('Unlock your identity with /unlock or click on the lock');
|
||||
return null;
|
||||
} else {
|
||||
addConsoleMessage('No Password Set, please set a password with /setpassword', 'error');
|
||||
alertQueue.enqueue('No Password Set, please set a password with /setpassword');
|
||||
console.error('No password set, please set a password first');
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import { IdentityStoreE } from './types';
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
let defaultServers: serverStoreI;
|
||||
let beta = false;
|
||||
|
||||
if (dev) {
|
||||
beta = true;
|
||||
defaultServers = {
|
||||
'https://server.discreetly.chat/': {
|
||||
name: 'Discreetly Server',
|
||||
@@ -23,6 +25,7 @@ if (dev) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const configDefaults: ConfigurationI = {
|
||||
signUpStatus: {
|
||||
completedSignup: false,
|
||||
@@ -31,7 +34,7 @@ const configDefaults: ConfigurationI = {
|
||||
identityStore: IdentityStoreE.NO_IDENTITY,
|
||||
numMessagesToSave: 500,
|
||||
hashedPwd: undefined,
|
||||
beta: false
|
||||
beta: beta
|
||||
};
|
||||
|
||||
export { defaultServers, configDefaults };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { alertAll, getCommitment, updateRooms } from '$lib/utils/';
|
||||
import { getCommitment, updateRooms } from '$lib/utils/';
|
||||
import { postInviteCode } from '$lib/services/server';
|
||||
import { selectedServer, configStore } from '$lib/stores';
|
||||
import { selectedServer, configStore, alertQueue } from '$lib/stores';
|
||||
import { get } from 'svelte/store';
|
||||
import type { JoinResponseI } from '$lib/types';
|
||||
|
||||
@@ -11,8 +11,7 @@ export async function inviteCode(newCode: string) {
|
||||
try {
|
||||
const idc = getCommitment();
|
||||
if (!idc) {
|
||||
// TODO convert this to alertAll at some point
|
||||
alertAll('No identity commitment found');
|
||||
alertQueue.enqueue('No identity commitment found');
|
||||
throw new Error('No identity commitment found');
|
||||
}
|
||||
const result = (await postInviteCode(server, {
|
||||
@@ -15,6 +15,13 @@ export async function getServerData(serverUrl: string): Promise<ServerI> {
|
||||
return get([serverUrl]) as Promise<ServerI>;
|
||||
}
|
||||
|
||||
export async function getEthAddressRoomNames(
|
||||
server: string,
|
||||
ethAddress: string
|
||||
): Promise<string[]> {
|
||||
return get([server, `api/eth/group/${ethAddress}`]) as Promise<string[]>;
|
||||
}
|
||||
|
||||
export async function postInviteCode(serverUrl: string, data: { code: string; idc: string }) {
|
||||
return post([serverUrl, 'join'], data);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { storable, sessionable, encryptable } from './storeFactory';
|
||||
import { derived, writable, type Readable } from 'svelte/store';
|
||||
import { storable, sessionable, encryptable, queueable } from './storeFactory';
|
||||
import { derived, writable } from 'svelte/store';
|
||||
import { configDefaults } from '$lib/defaults';
|
||||
import type {
|
||||
ConfigurationI,
|
||||
@@ -14,7 +14,6 @@ import type {
|
||||
roomKeyStoreI,
|
||||
keyStoreI
|
||||
} from '$lib/types';
|
||||
import { decrypt } from '$lib/crypto/crypto';
|
||||
|
||||
/* ------------------ Server State ------------------*/
|
||||
/**
|
||||
@@ -90,6 +89,8 @@ export const rateLimitStore = storable({} as rateLimitStoreI, 'rateLimit');
|
||||
*/
|
||||
export const keyStore = writable({} as keyStoreI);
|
||||
|
||||
export const alertQueue = queueable([] as string[]);
|
||||
|
||||
/**
|
||||
* @description Configuration store, stores the user's settings
|
||||
*/
|
||||
@@ -130,13 +131,50 @@ export const identityStore = storable({} as IdentityStoreI, 'identity');
|
||||
*/
|
||||
export const identityKeyStore = encryptable({} as IdentityStoreI, 'identityencrypted');
|
||||
|
||||
export const identityExists = derived(
|
||||
[identityStore, identityKeyStore],
|
||||
([$identityStore, $identityKeyStore]) => {
|
||||
if ($identityStore._commitment || $identityKeyStore._commitment) {
|
||||
return true;
|
||||
export const lockStateStore = derived(
|
||||
[keyStore, passwordSet],
|
||||
([$keyStore, $passwordSet]): 'unlocked' | 'locked' | null => {
|
||||
if ($passwordSet) {
|
||||
if ($keyStore instanceof CryptoKey) {
|
||||
return 'unlocked';
|
||||
} else {
|
||||
return 'locked';
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const identityExists = derived(
|
||||
[identityStore, identityKeyStore, lockStateStore],
|
||||
([$identityStore, $identityKeyStore, $lockStateStore]):
|
||||
| 'safe'
|
||||
| 'unsafe'
|
||||
| 'encrypted'
|
||||
| null => {
|
||||
const id = $identityKeyStore;
|
||||
const id_ = $identityStore;
|
||||
if ($lockStateStore == null) {
|
||||
if (id_._commitment?.length > 0) {
|
||||
return 'unsafe';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if ($lockStateStore === 'unlocked') {
|
||||
if (id._commitment) {
|
||||
return 'safe';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if ($lockStateStore === 'locked') {
|
||||
if (typeof id === 'object') {
|
||||
return 'encrypted';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { writable, get } from 'svelte/store';
|
||||
import type { Writable } from 'svelte/store';
|
||||
import { keyStore } from '.';
|
||||
import { keyStore, lockStateStore } from '.';
|
||||
import { decrypt, encrypt } from '$lib/crypto/crypto';
|
||||
import type { EncryptableT } from '$lib/types';
|
||||
|
||||
export function storable<Type>(data: Type, localStorageKey: string): Writable<Type> {
|
||||
const store = writable<Type>(data);
|
||||
@@ -73,29 +74,31 @@ export function sessionable<Type>(data: Type, sessionStorageKey: string): Writab
|
||||
};
|
||||
}
|
||||
|
||||
export function encryptable<Type>(data: Type, localStorageKey: string): Writable<Type> {
|
||||
export function encryptable<Type>(data: Type, localStorageKey: string): EncryptableT<Type> {
|
||||
const store = writable<Type>(data);
|
||||
const { subscribe, set } = store;
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
if (isBrowser && localStorage.getItem(localStorageKey) !== null) {
|
||||
const storedValue = localStorage.getItem(localStorageKey);
|
||||
if (storedValue) {
|
||||
try {
|
||||
const key = get(keyStore);
|
||||
if (!key) {
|
||||
throw new Error('Key store not initialized, cannot encrypt data');
|
||||
}
|
||||
console.debug('Encryptable State: ', storedValue, key);
|
||||
decrypt(storedValue, key).then((decryptedData) => {
|
||||
if (decryptedData !== null) {
|
||||
set(JSON.parse(decryptedData) as Type);
|
||||
} else {
|
||||
console.error('Error decrypting data');
|
||||
function read() {
|
||||
if (isBrowser && localStorage.getItem(localStorageKey) !== null) {
|
||||
const storedValue = localStorage.getItem(localStorageKey);
|
||||
|
||||
if (storedValue) {
|
||||
try {
|
||||
const key = get(keyStore);
|
||||
if (!(get(lockStateStore) === 'unlocked') || !key) {
|
||||
throw new Error('Key store not initialized, cannot encrypt data');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(`Error reading local storage for key: ${localStorageKey}; ${e}`);
|
||||
decrypt(storedValue, key).then((decryptedData) => {
|
||||
if (decryptedData !== null) {
|
||||
set(JSON.parse(decryptedData)) as Type;
|
||||
} else {
|
||||
console.error('Error decrypting data');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(`Error reading local storage for key: ${localStorageKey}; ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,6 +137,43 @@ export function encryptable<Type>(data: Type, localStorageKey: string): Writable
|
||||
console.error('Error encrypting data');
|
||||
}
|
||||
});
|
||||
},
|
||||
read
|
||||
};
|
||||
}
|
||||
|
||||
export type QueueStore = ReturnType<typeof queueService>;
|
||||
declare function queueService(): {
|
||||
set: (value: any[]) => void;
|
||||
subscribe: (run: (value: any[]) => any, invalidate?: any) => () => void;
|
||||
update: (callBack: (value: any[]) => any[]) => void;
|
||||
enqueue: (value: any) => void;
|
||||
dequeue: () => any;
|
||||
};
|
||||
|
||||
export function queueable<Type>(data: Type[]): ReturnType<typeof queueService> {
|
||||
const store = writable<Type[]>(data);
|
||||
const { subscribe, set } = store;
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set: (value: Type[]) => {
|
||||
set(value);
|
||||
},
|
||||
update: (callBack: (value: Type[]) => Type[]) => {
|
||||
const updatedStore = callBack(get(store));
|
||||
set(updatedStore);
|
||||
},
|
||||
enqueue: (value: Type) => {
|
||||
const updatedStore = get(store);
|
||||
updatedStore.push(value);
|
||||
set(updatedStore);
|
||||
},
|
||||
dequeue: () => {
|
||||
const updatedStore = get(store);
|
||||
const val = updatedStore.shift();
|
||||
set(updatedStore);
|
||||
return val;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './stores';
|
||||
export * from './enums';
|
||||
export * from './interfaces';
|
||||
export * from './svelte';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { ServerI, MessageI, HexColor } from 'discreetly-interfaces';
|
||||
import type { RoomI } from './interfaces';
|
||||
import type { Identity } from '@semaphore-protocol/identity';
|
||||
import type { Writable } from 'svelte/store';
|
||||
|
||||
// Keyed by server URL
|
||||
export interface serverStoreI {
|
||||
@@ -58,3 +60,7 @@ export interface roomKeyStoreI {
|
||||
}
|
||||
|
||||
export type keyStoreI = CryptoKey | undefined | null;
|
||||
|
||||
export interface EncryptableT<Type> extends Writable<Type> {
|
||||
read: () => void;
|
||||
}
|
||||
|
||||
15
src/lib/types/svelte.ts
Normal file
15
src/lib/types/svelte.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { Toast, ToastSettings } from '@skeletonlabs/skeleton';
|
||||
import type { Subscriber, Invalidator, Unsubscriber } from 'svelte/motion';
|
||||
|
||||
export type toastStoreT = {
|
||||
subscribe: (
|
||||
this: void,
|
||||
run: Subscriber<Toast[]>,
|
||||
invalidate?: Invalidator<Toast[]> | undefined
|
||||
) => Unsubscriber;
|
||||
close: (id: string) => void;
|
||||
trigger: (toast: ToastSettings) => string;
|
||||
freeze: (index: number) => void;
|
||||
unfreeze: (index: number) => void;
|
||||
clear: () => void;
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
import { getToastStore } from '@skeletonlabs/skeleton';
|
||||
import { addConsoleMessage } from './console';
|
||||
|
||||
export function alertToast(alertMessage: string, timeout = 5000) {
|
||||
const toastStore = getToastStore();
|
||||
toastStore.trigger({ message: alertMessage, timeout: timeout });
|
||||
console.warn(alertMessage);
|
||||
}
|
||||
|
||||
export function alertAll(
|
||||
alertMessage: string,
|
||||
level: 'warning' | 'info' | 'userinput' | 'error' | 'space' | undefined = 'warning',
|
||||
timeout = 5000
|
||||
) {
|
||||
alertToast(alertMessage, timeout);
|
||||
console.warn(alertMessage);
|
||||
addConsoleMessage(alertMessage, level);
|
||||
}
|
||||
@@ -1,103 +1,90 @@
|
||||
import { get } from 'svelte/store';
|
||||
import { configStore, identityKeyStore, identityStore, keyStore } from '../stores';
|
||||
import {
|
||||
alertQueue,
|
||||
configStore,
|
||||
identityKeyStore,
|
||||
identityStore,
|
||||
identityExists,
|
||||
keyStore,
|
||||
lockStateStore
|
||||
} from '../stores';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import type { IdentityStoreI } from '$lib/types';
|
||||
import { addConsoleMessage } from './console';
|
||||
|
||||
export function createIdentity(regenerate = false): 'created' | 'exists' | 'unsafe' | 'error' {
|
||||
const old_id = get(identityKeyStore) as unknown as IdentityStoreI;
|
||||
if (!old_id._commitment || regenerate) {
|
||||
const identityStatus = get(identityExists);
|
||||
console.log(identityStatus);
|
||||
if (!get(identityExists) || regenerate) {
|
||||
console.debug('Creating identity');
|
||||
const identity = new Identity() as unknown as IdentityStoreI;
|
||||
const config = get(configStore);
|
||||
const key = get(keyStore);
|
||||
const lockState = get(lockStateStore);
|
||||
if (config.hashedPwd && config.hashedPwd.length > 0) {
|
||||
if (key) {
|
||||
if (lockState === 'unlocked') {
|
||||
try {
|
||||
identityKeyStore.set(identity);
|
||||
if (get(identityKeyStore)._commitment !== null) {
|
||||
console.log('Identity Created! Congrats on your new journey');
|
||||
if (get(identityExists) === 'safe') {
|
||||
alertQueue.enqueue('Identity Created! Congrats on your new journey');
|
||||
return 'created';
|
||||
} else {
|
||||
console.error('Error creating identity');
|
||||
alertQueue.enqueue('Error creating identity');
|
||||
return 'error';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Error creating identity: ${e}`);
|
||||
alertQueue.enqueue(`Error creating identity: ${e}`);
|
||||
return 'error';
|
||||
}
|
||||
} else {
|
||||
addConsoleMessage(
|
||||
'Unlock your identity with /unlock or click on the lock in the corner',
|
||||
'error'
|
||||
);
|
||||
alertQueue.enqueue('Unlock your account by clicking on the lock');
|
||||
return 'error';
|
||||
}
|
||||
} else {
|
||||
addConsoleMessage(
|
||||
'For your security please set a password with /password or click on the lock in the corner',
|
||||
'warning'
|
||||
alertQueue.enqueue(
|
||||
'For your security please set a password with /password or click on the lock in the corner'
|
||||
);
|
||||
identityStore.set(identity);
|
||||
return 'unsafe';
|
||||
}
|
||||
} else {
|
||||
console.warn('Identity already exists');
|
||||
alertQueue.enqueue('Identity already exists');
|
||||
return 'exists';
|
||||
}
|
||||
}
|
||||
|
||||
export function getIdentity(): IdentityStoreI {
|
||||
export function getIdentity(): IdentityStoreI | null {
|
||||
const decryptedIdentity = get(identityKeyStore) as unknown as IdentityStoreI;
|
||||
if (decryptedIdentity !== null) {
|
||||
|
||||
if (decryptedIdentity._commitment) {
|
||||
console.log(decryptedIdentity);
|
||||
return decryptedIdentity;
|
||||
} else {
|
||||
const identity = get(identityStore);
|
||||
if (identity !== null) {
|
||||
console.warn('Identity not encrypted, set a password!');
|
||||
if (identity._commitment?.length > 0) {
|
||||
alertQueue.enqueue('Identity not encrypted, set a password!');
|
||||
return identity;
|
||||
} else {
|
||||
console.warn('Identity not created, create an identity!');
|
||||
alertQueue.enqueue('Identity not created, create an identity!');
|
||||
}
|
||||
}
|
||||
throw new Error('Identity not created');
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getCommitment() {
|
||||
const id = get(identityKeyStore) as IdentityStoreI;
|
||||
const id_ = get(identityStore);
|
||||
if (id !== null && id !== undefined) {
|
||||
export function getCommitment(): string | null {
|
||||
const id = getIdentity();
|
||||
if (id) {
|
||||
return id._commitment;
|
||||
}
|
||||
if (id_ !== null && id_ !== undefined) {
|
||||
console.warn('PLEASE ADD A PASSWORD!');
|
||||
return id_._commitment;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getIdentityBackup() {
|
||||
const id = get(identityKeyStore);
|
||||
const id_ = get(identityStore);
|
||||
if (id !== null && id !== undefined) {
|
||||
export function getIdentityBackup(): string | null {
|
||||
const id = getIdentity();
|
||||
if (id) {
|
||||
return JSON.stringify(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (id_ !== null && id_ !== undefined) {
|
||||
console.warn('PLEASE ADD A PASSWORD!');
|
||||
return JSON.stringify(id_);
|
||||
}
|
||||
}
|
||||
|
||||
export function doesIdentityExist(): 'safe' | 'unsafe' | 'none' {
|
||||
const id = get(identityKeyStore);
|
||||
const id_ = get(identityStore);
|
||||
if (id._commitment !== null && id._commitment !== undefined) {
|
||||
return 'safe';
|
||||
}
|
||||
if (id_._commitment !== null && id_._commitment !== undefined) {
|
||||
console.warn('PLEASE ADD A PASSWORD');
|
||||
return 'unsafe';
|
||||
}
|
||||
return 'none';
|
||||
}
|
||||
|
||||
export function encryptIdentity(identity: IdentityStoreI) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
export * from './alert';
|
||||
export * from './console';
|
||||
export * from './identity';
|
||||
export * from './inviteCode';
|
||||
export * from './password';
|
||||
export * from './rateLimit';
|
||||
export * from './rooms';
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import { deriveKey, hashPassword } from '$lib/crypto/crypto';
|
||||
import { get, writable } from 'svelte/store';
|
||||
import { configStore, identityKeyStore, identityStore, keyStore } from '$lib/stores';
|
||||
import { doesIdentityExist, encryptIdentity } from './identity';
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
configStore,
|
||||
identityKeyStore,
|
||||
identityStore,
|
||||
keyStore,
|
||||
identityExists,
|
||||
alertQueue,
|
||||
roomKeyStore
|
||||
} from '$lib/stores';
|
||||
import { encryptIdentity } from './identity';
|
||||
import type { IdentityStoreI } from '$lib/types';
|
||||
|
||||
export async function setPassword(password: string): Promise<'success' | string> {
|
||||
const hashedPassword = await hashPassword(password);
|
||||
let identity: IdentityStoreI | undefined;
|
||||
if (hashedPassword !== null) {
|
||||
const idStatus = doesIdentityExist();
|
||||
const idStatus = get(identityExists);
|
||||
/******************************
|
||||
* STAGE1: DECRYPT/STORE EVERYTHING INTO MEMORY
|
||||
******************************/
|
||||
@@ -49,3 +57,18 @@ export async function setPassword(password: string): Promise<'success' | string>
|
||||
}
|
||||
return 'error';
|
||||
}
|
||||
|
||||
export async function unlockPadlock(password: string) {
|
||||
const hashedPassword = await hashPassword(password);
|
||||
if (get(configStore).hashedPwd == hashedPassword) {
|
||||
deriveKey(password).then((key) => {
|
||||
keyStore.set(key);
|
||||
// Don't remove these. There is no reactive way to automatically decrypt encrypted stores, so we have to trigger it manually when the keys are derived
|
||||
identityKeyStore.read();
|
||||
roomKeyStore.read();
|
||||
});
|
||||
} else {
|
||||
alertQueue.enqueue('Incorrect Password');
|
||||
keyStore.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
selectedServer,
|
||||
serverStore,
|
||||
messageStore,
|
||||
currentSelectedRoom
|
||||
currentSelectedRoom,
|
||||
alertQueue
|
||||
} from '$lib/stores';
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
@@ -44,8 +45,7 @@ async function getRoomIdsIfEmpty(server: string, roomIds: string[]): Promise<str
|
||||
if (roomIds.length < 1) {
|
||||
const idc = getCommitment();
|
||||
if (!idc) {
|
||||
// TODO convert this to alertAll at some point
|
||||
console.error('No identity commitment found');
|
||||
alertQueue.enqueue('No identity commitment found');
|
||||
throw new Error('No identity commitment found');
|
||||
}
|
||||
return await getRoomIdsByIdentityCommitment(server, idc);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Modal, initializeStores } from '@skeletonlabs/skeleton';
|
||||
import { Modal, getToastStore, initializeStores } from '@skeletonlabs/skeleton';
|
||||
import { Toast, storePopup } from '@skeletonlabs/skeleton';
|
||||
import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
|
||||
import '../app.postcss';
|
||||
import { onMount } from 'svelte';
|
||||
import AppHeader from './AppHeader.svelte';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
import { selectedServer } from '$lib/stores';
|
||||
import { selectedServer, alertQueue } from '$lib/stores';
|
||||
import { getServerList, isInputFieldFocused, setDefaultServers } from '$lib/utils/';
|
||||
import { updateServer } from '$lib/utils/';
|
||||
import { Drawer, getDrawerStore } from '@skeletonlabs/skeleton';
|
||||
@@ -14,10 +14,12 @@
|
||||
import SelectRoom from '$lib/components/SelectRoom.svelte';
|
||||
import Console from './console/Console.svelte';
|
||||
import Sidebar from './Sidebar.svelte';
|
||||
import AppFooter from './AppFooter.svelte';
|
||||
import AppFooter from './Footer.svelte';
|
||||
|
||||
initializeStores();
|
||||
|
||||
const toastStore = getToastStore();
|
||||
|
||||
const drawerStore = getDrawerStore();
|
||||
// Hack to get BigInt <-> JSON compatibility
|
||||
(BigInt.prototype as any).toJSON = function () {
|
||||
@@ -46,6 +48,12 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
setInterval(() => {
|
||||
const toast = alertQueue.dequeue();
|
||||
if (toast) {
|
||||
toastStore.trigger({ message: toast });
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { passwordSet, configStore, keyStore } from '$lib/stores';
|
||||
import { passwordSet, configStore, keyStore, alertQueue } from '$lib/stores';
|
||||
import {
|
||||
getModalStore,
|
||||
TabAnchor,
|
||||
@@ -23,7 +23,7 @@
|
||||
import LockOpen from 'svelte-material-icons/LockOpenVariant.svelte';
|
||||
import NoPassword from 'svelte-material-icons/LockOff.svelte';
|
||||
import Door from 'svelte-material-icons/Door.svelte';
|
||||
import { alertAll } from '$lib/utils';
|
||||
import { unlockPadlock } from '$lib/utils';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
const drawerStore = getDrawerStore();
|
||||
@@ -49,13 +49,7 @@
|
||||
valueAttr: { type: 'password', minlength: 4, required: true },
|
||||
response: async (r: string) => {
|
||||
if (r != 'false' && r != '' && r != null && r != undefined) {
|
||||
const hashedPassword = await hashPassword(r);
|
||||
if ($configStore.hashedPwd == hashedPassword) {
|
||||
$keyStore = await deriveKey(r);
|
||||
} else {
|
||||
alertAll('Incorrect Password');
|
||||
$keyStore = null;
|
||||
}
|
||||
unlockPadlock(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -65,13 +59,6 @@
|
||||
function lock() {
|
||||
$keyStore = null;
|
||||
}
|
||||
onMount(() => {
|
||||
console.debug(
|
||||
'PadLock:',
|
||||
$passwordSet ? 'password set,' : 'password not set,',
|
||||
$keyStore !== null && $keyStore !== undefined ? 'unlocked' : 'locked'
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="card p-4 w-72 shadow-xl" data-popup="popupMenu">
|
||||
@@ -79,7 +66,7 @@
|
||||
<!-- (optionally you can provide a label here) -->
|
||||
<ul>
|
||||
<li id="will-close">
|
||||
<a href="/settings">
|
||||
<a href="/about">
|
||||
<Information />
|
||||
<span class="flex-auto">About</span>
|
||||
</a>
|
||||
@@ -15,9 +15,9 @@
|
||||
import NoPassword from 'svelte-material-icons/LockOff.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import { hashPassword, deriveKey } from '$lib/crypto/crypto';
|
||||
import { configStore, keyStore, passwordSet } from '$lib/stores';
|
||||
import { alertAll } from '$lib/utils';
|
||||
import { configStore, keyStore, passwordSet, alertQueue } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { unlockPadlock } from '$lib/utils';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
|
||||
@@ -30,13 +30,7 @@
|
||||
valueAttr: { type: 'password', minlength: 4, required: true },
|
||||
response: async (r: string) => {
|
||||
if (r != 'false' && r != '' && r != null && r != undefined) {
|
||||
const hashedPassword = await hashPassword(r);
|
||||
if ($configStore.hashedPwd == hashedPassword) {
|
||||
$keyStore = await deriveKey(r);
|
||||
} else {
|
||||
alertAll('Incorrect Password');
|
||||
$keyStore = null;
|
||||
}
|
||||
unlockPadlock(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -46,14 +40,6 @@
|
||||
function lock() {
|
||||
$keyStore = null;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
console.debug(
|
||||
'PadLock:',
|
||||
$passwordSet ? 'password set,' : 'password not set,',
|
||||
$keyStore !== null && $keyStore !== undefined ? 'unlocked' : 'locked'
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<AppRail height="h-full">
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { currentSelectedRoom, keyStore, rateLimitStore, roomKeyStore } from '$lib/stores';
|
||||
import {
|
||||
currentSelectedRoom,
|
||||
keyStore,
|
||||
rateLimitStore,
|
||||
roomKeyStore,
|
||||
alertQueue
|
||||
} from '$lib/stores';
|
||||
import { genProof } from '$lib/crypto/rlnProver';
|
||||
import type { Socket } from 'socket.io-client';
|
||||
import { getIdentity, alertToast, clearMessageHistory, alertAll } from '$lib/utils';
|
||||
import { getIdentity, clearMessageHistory } from '$lib/utils';
|
||||
import Send from 'svelte-material-icons/Send.svelte';
|
||||
import { decrypt, encrypt } from '$lib/crypto/crypto';
|
||||
|
||||
@@ -32,23 +38,25 @@
|
||||
|
||||
function checkStatus(): boolean {
|
||||
if (!connected) {
|
||||
alertToast('NOT CONNECTED TO CHAT SERVER');
|
||||
alertQueue.enqueue('NOT CONNECTED TO CHAT SERVER');
|
||||
sendingMessage = false;
|
||||
return false;
|
||||
}
|
||||
if (messageText.length < 1) {
|
||||
alertToast('MESSAGE IS EMPTY');
|
||||
alertQueue.enqueue('MESSAGE IS EMPTY');
|
||||
sendingMessage = false;
|
||||
return false;
|
||||
}
|
||||
if (messageText.length > 2000) {
|
||||
alertToast('MESSAGE IS TOO LONG, SENDING MAY FAIL UNDER NETWORK CONSTRAINED CONDITIONS');
|
||||
alertQueue.enqueue(
|
||||
'MESSAGE IS TOO LONG, SENDING MAY FAIL UNDER NETWORK CONSTRAINED CONDITIONS'
|
||||
);
|
||||
sendingMessage = false;
|
||||
return false;
|
||||
}
|
||||
// This is 100% thanks to Violet for spamming the chat with spaces
|
||||
if (messageText.replaceAll(' ', '') == '') {
|
||||
alertToast('MESSAGE IS EMPTY');
|
||||
alertQueue.enqueue('MESSAGE IS EMPTY');
|
||||
sendingMessage = false;
|
||||
return false;
|
||||
}
|
||||
@@ -56,7 +64,7 @@
|
||||
}
|
||||
|
||||
function help() {
|
||||
alertToast('Commands: /clear, /help');
|
||||
alertQueue.enqueue('Commands: /clear, /help');
|
||||
}
|
||||
|
||||
function processCommand(value: string) {
|
||||
@@ -154,11 +162,11 @@
|
||||
} catch (err: any) {
|
||||
console.error('Error sending message: ', err);
|
||||
if (err.message.includes('Merkle Proof')) {
|
||||
alertToast(
|
||||
alertQueue.enqueue(
|
||||
"Couldn't generate Merkle Proof. Maybe you don't belong in the room or don't have an updated member list."
|
||||
);
|
||||
} else {
|
||||
alertToast(err as string);
|
||||
alertQueue.enqueue(err as string);
|
||||
}
|
||||
} finally {
|
||||
sendingMessage = false;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { deriveKey, hashPassword } from '$lib/crypto/crypto';
|
||||
import { configStore, identityKeyStore, keyStore, passwordSet } from '$lib/stores';
|
||||
import {
|
||||
addConsoleMessage,
|
||||
clearConsoleMessages,
|
||||
doesIdentityExist,
|
||||
setPassword
|
||||
} from '$lib/utils/';
|
||||
import { inviteCode } from '$lib/utils/inviteCode';
|
||||
configStore,
|
||||
identityKeyStore,
|
||||
keyStore,
|
||||
passwordSet,
|
||||
identityExists
|
||||
} from '$lib/stores';
|
||||
import { addConsoleMessage, clearConsoleMessages, setPassword, unlockPadlock } from '$lib/utils/';
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { createIdentity } from '$lib/utils/';
|
||||
|
||||
export let placeholder: string = 'Enter / Command';
|
||||
@@ -79,20 +80,7 @@
|
||||
addConsoleMessage('Locked!');
|
||||
break;
|
||||
case '/unlock':
|
||||
const hashedPwd = await hashPassword(args[0]);
|
||||
if (hashedPwd === $configStore.hashedPwd) {
|
||||
if ($keyStore && !(args[1] === 'force')) {
|
||||
addConsoleMessage(
|
||||
'Already Unlocked! use `/unlock PASSWORD force` to override this and derive the key again',
|
||||
'warning'
|
||||
);
|
||||
break;
|
||||
}
|
||||
$keyStore = await deriveKey(args[0]);
|
||||
addConsoleMessage('Unlocked!');
|
||||
} else {
|
||||
addConsoleMessage(`Invalid password!`, 'warning');
|
||||
}
|
||||
unlockPadlock(args[0]);
|
||||
break;
|
||||
case '/export':
|
||||
addConsoleMessage('Exporting Identity');
|
||||
@@ -117,7 +105,7 @@
|
||||
addConsoleMessage(`Identity: ${$identityKeyStore}`);
|
||||
break;
|
||||
case '/createIdentity':
|
||||
const idStatus = doesIdentityExist();
|
||||
const idStatus = $identityExists;
|
||||
if (idStatus === 'safe') {
|
||||
addConsoleMessage('✅ Identity Exists Already');
|
||||
} else if (idStatus === 'unsafe') {
|
||||
|
||||
@@ -1,8 +1,46 @@
|
||||
<script lang="ts">
|
||||
import Container from '$lib/components/Container.svelte';
|
||||
import JoinMore from './JoinMore.svelte';
|
||||
import EthereumWallet from '$lib/components/Gateways/EthereumWallet.svelte';
|
||||
import InviteCodeGateway from '$lib/components/Gateways/InviteCode.svelte';
|
||||
import SelectServer from '$lib/components/SelectServer.svelte';
|
||||
import Card from '$lib/components/card.svelte';
|
||||
import { configStore } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
<Container heading="Join More Communities">
|
||||
<JoinMore />
|
||||
<div class="variant-ghost-success p-4 rounded-token">
|
||||
<h3 class="h4">Select Server, or add a new Server:</h3>
|
||||
<SelectServer />
|
||||
</div>
|
||||
<div class="flex flex-row flex-wrap gap-5 justify-evenly">
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Join via invite code:</svelte:fragment>
|
||||
<svelte:fragment slot="description"
|
||||
>If you were given an invite code, you can
|
||||
</svelte:fragment>
|
||||
<InviteCodeGateway code={$configStore.signUpStatus.inviteCode} />
|
||||
</Card>
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Discord Bot</svelte:fragment>
|
||||
<svelte:fragment slot="description"
|
||||
>Add the discord bot to your server Today!
|
||||
</svelte:fragment>
|
||||
<a
|
||||
href="https://discord.com/api/oauth2/authorize?client_id=1142162852132700200&permissions=2147483648&scope=bot"
|
||||
class="btn variant-ghost-primary">Invite Discord Bot!</a
|
||||
>
|
||||
</Card>
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Join via Jubmojii:</svelte:fragment>
|
||||
<svelte:fragment slot="description">Coming Soon!</svelte:fragment>
|
||||
</Card>
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Join via Ethereum Address:</svelte:fragment>
|
||||
<svelte:fragment slot="description"
|
||||
>Are you a genesis validator, daohack survivor, nouns holder? You can join using your
|
||||
Ethereum address.
|
||||
</svelte:fragment>
|
||||
<EthereumWallet />
|
||||
</Card>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<script lang="ts">
|
||||
import Join from '$lib/components/Join.svelte';
|
||||
import { configStore } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
<div class="card variant-ghost-tertiary">
|
||||
<header class="card-header">
|
||||
<h4 class="h4">Join More Rooms</h4>
|
||||
</header>
|
||||
<section class="p-2 mb-2">
|
||||
<Join code={$configStore.signUpStatus.inviteCode} />
|
||||
</section>
|
||||
</div>
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { identityExists } from '$lib/stores';
|
||||
import DeleteIdentity from './identity/DeleteIdentity.svelte';
|
||||
import BackupIdentity from './identity/BackupIdentity.svelte';
|
||||
import RestoreIdentity from './identity/RestoreIdentity.svelte';
|
||||
@@ -8,6 +7,7 @@
|
||||
import IdentityIcon from 'svelte-material-icons/Account.svelte';
|
||||
import Eye from 'svelte-material-icons/Eye.svelte';
|
||||
import Container from '../../lib/components/Container.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
<Container heading="Manage Settings">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { identityKeyStore, keyStore } from '$lib/stores';
|
||||
import { alertAll } from '$lib/utils';
|
||||
import { alertQueue, identityKeyStore, keyStore } from '$lib/stores';
|
||||
import { FileDropzone } from '@skeletonlabs/skeleton';
|
||||
import { poseidon2 } from 'poseidon-lite/poseidon2';
|
||||
import { poseidon1 } from 'poseidon-lite/poseidon1';
|
||||
@@ -19,37 +18,37 @@
|
||||
id = backup;
|
||||
} catch (e) {
|
||||
console.warn('Could not parse json as object');
|
||||
alertAll('Invalid JSON detected');
|
||||
alertQueue.enqueue('Invalid JSON detected');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!id._nullifier) {
|
||||
alertAll("_nullifier doesn't exist in backup");
|
||||
alertQueue.enqueue("_nullifier doesn't exist in backup");
|
||||
}
|
||||
if (!id._trapdoor) {
|
||||
alertAll("_trapdoor doesn't exist in backup");
|
||||
alertQueue.enqueue("_trapdoor doesn't exist in backup");
|
||||
}
|
||||
if (!id._secret) {
|
||||
alertAll("_secret doesn't exist in backup");
|
||||
alertQueue.enqueue("_secret doesn't exist in backup");
|
||||
}
|
||||
const checkSecret = poseidon2([id._nullifier, id._trapdoor]);
|
||||
if (checkSecret != id._secret) {
|
||||
alertAll('Secret does not match secret from backup');
|
||||
alertQueue.enqueue('Secret does not match secret from backup');
|
||||
}
|
||||
if (!id._commitment) {
|
||||
alertAll("_commitment doesn't exist in backup");
|
||||
alertQueue.enqueue("_commitment doesn't exist in backup");
|
||||
}
|
||||
const checkCommitment = poseidon1([id._secret]);
|
||||
if (checkCommitment != id._commitment) {
|
||||
alertAll('Commitment does not match commitment backup');
|
||||
alertQueue.enqueue('Commitment does not match commitment backup');
|
||||
}
|
||||
console.log('Restoring identity from backup file...');
|
||||
if ($keyStore !== undefined || $keyStore !== null) {
|
||||
$identityKeyStore = id;
|
||||
} else {
|
||||
alertAll('Please set a password or unlock before restoring your identity');
|
||||
alertQueue.enqueue('Please set a password or unlock before restoring your identity');
|
||||
}
|
||||
alertAll(
|
||||
alertQueue.enqueue(
|
||||
`Identity restored from backup file with identity commitment:
|
||||
${$identityKeyStore._commitment}`
|
||||
);
|
||||
@@ -60,7 +59,7 @@
|
||||
console.debug(`Backup/recovery file type detected as ${f?.type}`);
|
||||
let unverifiedBackup: any;
|
||||
if (!f) {
|
||||
alertAll('No file selected');
|
||||
alertQueue.enqueue('No file selected');
|
||||
return;
|
||||
}
|
||||
if (f.type == 'application/json' || f.type == 'text/plain') {
|
||||
@@ -69,7 +68,7 @@
|
||||
restoreBackup(unverifiedBackup);
|
||||
});
|
||||
} else {
|
||||
alertAll(
|
||||
alertQueue.enqueue(
|
||||
'Invalid file type, must be a JSON object with the _nullifier, _trapdoor, _secret, and _commitment as stringified bigints'
|
||||
);
|
||||
console.warn('Invalid file type');
|
||||
@@ -80,7 +79,7 @@
|
||||
const textBox = document.getElementById('jsonRecovery') as HTMLInputElement;
|
||||
const json = textBox.value;
|
||||
if (!json || json == '') {
|
||||
alertAll('No JSON detected');
|
||||
alertQueue.enqueue('No JSON detected');
|
||||
return;
|
||||
} else {
|
||||
restoreBackup(json);
|
||||
|
||||
@@ -45,5 +45,5 @@
|
||||
</form>
|
||||
</Container>
|
||||
{:else}
|
||||
<h2 class="h3">Password Set!</h2>
|
||||
<Container heading="Password set" />
|
||||
{/if}
|
||||
|
||||
@@ -1,35 +1,67 @@
|
||||
<script lang="ts">
|
||||
import { configStore, identityKeyStore, identityStore, serverStore } from '$lib/stores';
|
||||
import {
|
||||
configStore,
|
||||
identityExists,
|
||||
identityKeyStore,
|
||||
identityStore,
|
||||
lockStateStore,
|
||||
passwordSet,
|
||||
serverStore
|
||||
} from '$lib/stores';
|
||||
import { IdentityStoreE } from '$lib/types';
|
||||
import { alertQueue } from '$lib/stores';
|
||||
|
||||
function toggleBeta() {
|
||||
$configStore.beta = !$configStore.beta;
|
||||
}
|
||||
|
||||
function triggerAlert() {
|
||||
alertQueue.enqueue('TEST');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="status" class="flex flex-col gap-5">
|
||||
<div>
|
||||
<h2 class="h3">configStore</h2>
|
||||
<div>Completed Signup: {JSON.stringify($configStore.signUpStatus.completedSignup)}</div>
|
||||
<div>Identity Backedup: {JSON.stringify($configStore.signUpStatus.identityBackedUp)}</div>
|
||||
<div>IdentityStore Type: {IdentityStoreE[$configStore.identityStore]}</div>
|
||||
<div>Beta: {JSON.stringify($configStore.beta)}</div>
|
||||
<div>Hashed Password: {JSON.stringify($configStore.hashedPwd)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="h3">Identity Data</h2>
|
||||
{#each Object.keys($identityStore) as key}
|
||||
<div>Unprotected {key}: {JSON.stringify($identityStore[key])}</div>
|
||||
{/each}
|
||||
{#each Object.keys($identityKeyStore) as key}
|
||||
<div>Protected {key}: {JSON.stringify($identityKeyStore[key])}</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="h3">Server Data</h2>
|
||||
{#each Object.keys($serverStore) as key}
|
||||
<div>{$serverStore[key].name}:</div>
|
||||
<div class="ps-5">id: {$serverStore[key].id}</div>
|
||||
<div class="ps-5">version: {$serverStore[key].version}</div>
|
||||
<div class="ps-5">url: {key}</div>
|
||||
{/each}
|
||||
<div class="p-4">
|
||||
<div id="status" class="flex flex-col gap-5">
|
||||
<div>
|
||||
<h2 class="h3">configStore</h2>
|
||||
<div>Completed Signup: {JSON.stringify($configStore.signUpStatus.completedSignup)}</div>
|
||||
<div>Identity Backedup: {JSON.stringify($configStore.signUpStatus.identityBackedUp)}</div>
|
||||
<div>IdentityStore Type: {IdentityStoreE[$configStore.identityStore]}</div>
|
||||
<div on:click={toggleBeta}>Beta: {JSON.stringify($configStore.beta)}</div>
|
||||
<div>Hashed Password: {JSON.stringify($configStore.hashedPwd)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="h3">Identity Data</h2>
|
||||
{#if $identityExists == 'safe' || $identityExists == 'unsafe'}
|
||||
{#each Object.keys($identityStore) as key}
|
||||
<div>Unprotected {key}: {JSON.stringify($identityStore[key])}</div>
|
||||
{/each}
|
||||
{#each Object.keys($identityKeyStore) as key}
|
||||
<div>Protected {key}: {JSON.stringify($identityKeyStore[key])}</div>
|
||||
{/each}
|
||||
{:else if $identityExists == 'encrypted'}
|
||||
<div>Identity Exists but is encrypted</div>
|
||||
{:else}
|
||||
<div>No Identity Found</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="h3">Server Data</h2>
|
||||
{#each Object.keys($serverStore) as key}
|
||||
<div>{$serverStore[key].name}:</div>
|
||||
<div class="ps-5">id: {$serverStore[key].id}</div>
|
||||
<div class="ps-5">version: {$serverStore[key].version}</div>
|
||||
<div class="ps-5">url: {key}</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="h3">Status States</h2>
|
||||
<div>identityExists: {$identityExists}</div>
|
||||
<div>Password Set: {$passwordSet}</div>
|
||||
<div>Lock State: {$lockStateStore}</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn variant-outline-primary m-4" on:click={triggerAlert}>Test Alert</button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { identityStore, configStore, consoleStore } from '$lib/stores';
|
||||
import { createIdentity, doesIdentityExist } from '$lib/utils/';
|
||||
import { configStore, identityExists } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import ArrowRight from 'svelte-material-icons/ArrowRightBold.svelte';
|
||||
import Text from 'svelte-material-icons/TextBox.svelte';
|
||||
import Account from 'svelte-material-icons/AccountHardHat.svelte';
|
||||
import { inviteCode } from '$lib/utils/inviteCode';
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { addConsoleMessage } from '$lib/utils/console';
|
||||
import Console from '../console/Console.svelte';
|
||||
|
||||
function checkForIdentity() {
|
||||
const idStatus = doesIdentityExist();
|
||||
const idStatus = $identityExists;
|
||||
if (idStatus === 'safe') {
|
||||
addConsoleMessage('✅ Identity Found');
|
||||
} else if (idStatus === 'encrypted') {
|
||||
addConsoleMessage('⚠️ Identity Found, but it is encrypted');
|
||||
} else if (idStatus === 'unsafe') {
|
||||
addConsoleMessage('⚠️ Identity Found, but it is unsafe');
|
||||
} else if (idStatus === 'none') {
|
||||
} else if (idStatus === null) {
|
||||
addConsoleMessage('❌ No Identity Found');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user