mirror of
https://github.com/creating2morrow/neveko.git
synced 2024-12-22 11:39:22 +00:00
commit
ba628f99a1
52 changed files with 4963 additions and 3633 deletions
12
.github/workflows/rust.yml
vendored
12
.github/workflows/rust.yml
vendored
|
@ -20,10 +20,12 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install dependencies
|
||||
run: sudo apt install -y libssl-dev build-essential
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
run: sudo apt install -y libssl-dev build-essential && rustup toolchain install nightly
|
||||
- name: Build and Clippy
|
||||
run: RUSTFLAGS="-Z threads=4" cargo +nightly build --future-incompat-report && cargo clippy
|
||||
- name: Run tests
|
||||
run: cd neveko-core && RUST_TEST_THREADS=1 cargo test --verbose
|
||||
run: cd neveko-core && RUST_TEST_THREADS=1 cargo test
|
||||
|
|
19
.gitignore
vendored
19
.gitignore
vendored
|
@ -10,6 +10,21 @@ notes.txt
|
|||
.vscode/settings.json
|
||||
*.bz2
|
||||
*.zip
|
||||
*/monero-x86_64-linux-gnu-v0.18.3.3/**
|
||||
*/i2p-zero-linux.v1.20/**
|
||||
monero-x86_64-linux-gnu-v*/
|
||||
*.jar
|
||||
opt/*
|
||||
*.so
|
||||
*.config
|
||||
*.log
|
||||
*.key
|
||||
router.info
|
||||
router.keys.dat
|
||||
prngseed.rnd
|
||||
hostsdb.blockfile
|
||||
certificates/
|
||||
netDb/*
|
||||
peerProfiles/*
|
||||
*.dat
|
||||
*.txt
|
||||
*.txt.gz
|
||||
opt-backup/j4-i2p-rs/jassets/addressbook.war
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "j4-i2p-rs"]
|
||||
path = j4-i2p-rs
|
||||
url = https://github.com/kn0sys/j4-i2p-rs.git
|
305
Cargo.lock
generated
305
Cargo.lock
generated
|
@ -71,7 +71,7 @@ dependencies = [
|
|||
"android-properties",
|
||||
"bitflags 1.3.2",
|
||||
"cc",
|
||||
"jni-sys",
|
||||
"jni-sys 0.3.0",
|
||||
"libc 0.2.153",
|
||||
"log",
|
||||
"ndk",
|
||||
|
@ -249,6 +249,15 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -558,16 +567,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
|
@ -658,9 +657,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "devise"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8"
|
||||
checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d"
|
||||
dependencies = [
|
||||
"devise_codegen",
|
||||
"devise_core",
|
||||
|
@ -668,9 +667,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "devise_codegen"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6"
|
||||
checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867"
|
||||
dependencies = [
|
||||
"devise_core",
|
||||
"quote",
|
||||
|
@ -678,9 +677,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "devise_core"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
|
||||
checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"proc-macro2",
|
||||
|
@ -767,6 +766,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "ecolor"
|
||||
version = "0.21.0"
|
||||
|
@ -1027,6 +1032,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
|
@ -1035,6 +1046,7 @@ checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
@ -1057,12 +1069,34 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
|
@ -1084,6 +1118,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
|
@ -1108,7 +1143,7 @@ dependencies = [
|
|||
"libc 0.2.153",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows",
|
||||
"windows 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1409,7 +1444,7 @@ dependencies = [
|
|||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows",
|
||||
"windows 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1524,6 +1559,48 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "j4-i2p-rs"
|
||||
version = "0.2.0-alpha"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"j4rs",
|
||||
"log",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "j4rs"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "689ae4f2bd4eba82601592f3d22b7e7147b1df52d3b525223f5218990501b4eb"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"java-locator",
|
||||
"jni-sys 0.4.0",
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.153",
|
||||
"libloading 0.8.0",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "java-locator"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
|
@ -1533,7 +1610,7 @@ dependencies = [
|
|||
"cesu8",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-sys",
|
||||
"jni-sys 0.3.0",
|
||||
"log",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
|
@ -1546,6 +1623,25 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c30a312d782b8d56a1e0897d45c1af33f31f9b4a4d13d31207a8675e0223b818"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c199962dfd5610ced8eca382606e349f7940a4ac7d867b58a046123411cbb4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.26"
|
||||
|
@ -1703,7 +1799,7 @@ version = "0.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc 0.2.153",
|
||||
"libc 0.1.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1855,7 +1951,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"jni-sys",
|
||||
"jni-sys 0.3.0",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
"raw-window-handle",
|
||||
|
@ -1874,7 +1970,7 @@ version = "0.4.1+23.1.7779620"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3"
|
||||
dependencies = [
|
||||
"jni-sys",
|
||||
"jni-sys 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1915,6 +2011,7 @@ dependencies = [
|
|||
name = "neveko_core"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"curve25519-dalek",
|
||||
|
@ -1922,6 +2019,7 @@ dependencies = [
|
|||
"env_logger",
|
||||
"hex",
|
||||
"hmac",
|
||||
"j4-i2p-rs",
|
||||
"jwt",
|
||||
"kn0sys-lmdb-rs",
|
||||
"lazy_static 1.4.0",
|
||||
|
@ -1936,6 +2034,8 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -1943,6 +2043,7 @@ dependencies = [
|
|||
name = "neveko_gui"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"console_error_panic_hook",
|
||||
"eframe",
|
||||
|
@ -2025,6 +2126,15 @@ dependencies = [
|
|||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -2484,9 +2594,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
|||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.7.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
|
@ -2494,14 +2604,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.11.0"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3085,6 +3193,20 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.153",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
|
@ -3140,18 +3262,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3807,6 +3929,59 @@ dependencies = [
|
|||
"windows-targets 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -3870,6 +4045,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -3882,6 +4073,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3894,6 +4091,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -3906,6 +4109,18 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3918,6 +4133,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -3930,6 +4151,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -3942,6 +4169,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3954,6 +4187,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.28.6"
|
||||
|
|
18
README.md
18
README.md
|
@ -19,21 +19,21 @@ NEVidebla-EKOnomia (invisible economy)
|
|||
|
||||
## Dev
|
||||
|
||||
* stack - rust (egui, rocket), lmdb, i2p-zero, monero(rpc, daemon)
|
||||
* stack - rust (egui, rocket), lmdb, i2p, monero(rpc, daemon)
|
||||
* install dependencies
|
||||
* ubuntu example: `sudo apt update -y && sudo apt upgrade -y`
|
||||
* `sudo apt install -y libssl-dev build-essential`
|
||||
* `git clone https://github.com/creating2morrow/neveko`
|
||||
* `git clone --recursive https://github.com/creating2morrow/neveko`
|
||||
* `cd neveko && ./scripts/build_all_and_run.sh "-- -h"`
|
||||
* Example to start neveko with remote stagenet node / i2p proxy remote for development:
|
||||
* `./scripts/build_all_and_run.sh "-- --monero-location monero-x86_64-linux-gnu-v0.18.3.3 --monero-rpc-host http://127.0.0.1:38083 --monero-rpc-daemon http://xmr3kaacphwkk4z2gp35bdl47lrrnzimmyqj4oliauqrjzqecofa.b32.i2p:38081 --monero-rpc-username user --monero-rpc-cred pass --remote-node --i2p-advanced --i2p-tunnels-json /home/user/neveko/i2p-manual/config --i2p-proxy-host http://x.x.x.x:xxxx --i2p-socks-proxy-host http://x.x.x.x:xxxx"`
|
||||
* `./scripts/build_all_and_run.sh "-- --monero-location monero-x86_64-linux-gnu-v0.18.3.4 --monero-rpc-host http://127.0.0.1:38083 --monero-rpc-daemon http://xmr3kaacphwkk4z2gp35bdl47lrrnzimmyqj4oliauqrjzqecofa.b32.i2p:38081 --monero-rpc-username user --monero-rpc-cred pass --remote-node --i2p-advanced --i2p-tunnels-json /home/user/neveko/i2p-manual/config --i2p-proxy-host http://x.x.x.x:xxxx --i2p-socks-proxy-host http://x.x.x.x:xxxx"`
|
||||
* the `--monero-location` flag is needed even when using a remote node because
|
||||
neveko has its own monero-wallet-rpc instance
|
||||
* remote nodes are forced over the `--i2p-proxy-host`
|
||||
* Recommended neveko-core startup with full node and i2p-zero locally running:
|
||||
* ` ./scripts/build_all_and_run.sh "-- --monero-blockchain-dir=/home/user/.bitmonero --monero-location monero-x86_64-linux-gnu-v0.18.3.3 --i2p-zero-dir /home/user/i2p-zero-linux.v1.21/ --monero-blockchain-dir /home/user/.bitmonero"`
|
||||
* Recommended neveko-core startup with full node:
|
||||
* ` ./scripts/build_all_and_run.sh "-- --monero-blockchain-dir=/home/user/.bitmonero --monero-location monero-x86_64-linux-gnu-v0.18.3.4 --monero-blockchain-dir /home/user/.bitmonero"`
|
||||
* monerod doesn't need to be running because neveko will start it and monero-wallet-rpc
|
||||
* gui will automatically detect monerod, rpc and i2p-zero if neveko core is started first
|
||||
* gui will automatically detect monerod, rpc if neveko core is started first
|
||||
* Neveko doesn't write logs to file. Use the command below to write to a log file:
|
||||
```bash
|
||||
{NEVEKO_START_CMDS} > neveko.log 2>&1
|
||||
|
@ -41,13 +41,14 @@ NEVidebla-EKOnomia (invisible economy)
|
|||
* just remember to put cli password in the original window, not the log file window
|
||||
* https://stackoverflow.com/questions/6674327/redirect-all-output-to-file-in-bash
|
||||
* gui built with rust [egui](https://docs.rs/egui/latest/egui/)
|
||||
* copy the `certificates` directory from `j4-i2p-rs` to `neveko` root
|
||||
* see [j4-i2p-rs](https://github.com/kn0sys/j4-i2p-rs) for more information on embedded i2p
|
||||
* darknet release server links are located at: http://neveko.i2p/index.txt
|
||||
|
||||
## Installation Mananger
|
||||
|
||||
* additional required software can be downloaded from the gui home or `Binaries` links below
|
||||
* additional required software can be downloaded from `Binaries` links below
|
||||
* hashes are in core [lib.rs](./neveko-core/src/lib.rs)
|
||||
* download i2p-zero, put the path in the connection manager or cli `--i2p-zero-dir` flag
|
||||
* download monero, update connection manager or cli
|
||||
* `--monero-blockchain-dir`, where to put lmdb for monero (e.g. path/to/ssd)
|
||||
* `--monero-location`, path to monero download
|
||||
|
@ -101,7 +102,6 @@ NEVidebla-EKOnomia (invisible economy)
|
|||
* can be overriden with remote node
|
||||
* use the `--remote-node` flag
|
||||
* [monero-wallet-rpc](https://www.getmonero.org/downloads/#cli) - (not included) interface for xmr wallet ops
|
||||
* [i2p-zero](https://github.com/creating2morrow/i2p-zero/releases/tag/v1.21-neveko) - (not included) tunnel creation and http proxy
|
||||
|
||||
most of the complex logic stays in neveko-core, exported from [lib.rs](./neveko-core/src/lib.rs)
|
||||
|
||||
|
|
1
j4-i2p-rs
Submodule
1
j4-i2p-rs
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 35874a836a66059fe4d177a8d8e8061c454d9d87
|
468
neveko-auth/Cargo.lock
generated
468
neveko-auth/Cargo.lock
generated
|
@ -17,7 +17,7 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -127,10 +127,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -140,9 +143,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.0.2"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
@ -180,6 +183,12 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -286,7 +295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -301,9 +310,34 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -316,15 +350,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.2"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"fiat-crypto",
|
||||
"platforms",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
|
@ -411,7 +444,7 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
|
||||
dependencies = [
|
||||
"bitflags 2.0.2",
|
||||
"bitflags 2.6.0",
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
|
@ -463,6 +496,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
|
@ -486,7 +525,7 @@ checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
|||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
@ -498,7 +537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -509,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -571,6 +610,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.27"
|
||||
|
@ -579,6 +624,7 @@ checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
@ -601,12 +647,34 @@ version = "0.3.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.27"
|
||||
|
@ -628,6 +696,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
|
@ -649,8 +718,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.44.0",
|
||||
]
|
||||
|
@ -672,7 +741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
|
@ -719,7 +788,7 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -887,7 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -915,6 +984,67 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "j4-i2p-rs"
|
||||
version = "0.2.0-alpha"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"j4rs",
|
||||
"log",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "j4rs"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "689ae4f2bd4eba82601592f3d22b7e7147b1df52d3b525223f5218990501b4eb"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"java-locator",
|
||||
"jni-sys",
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.158",
|
||||
"libloading",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "java-locator"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c30a312d782b8d56a1e0897d45c1af33f31f9b4a4d13d31207a8675e0223b818"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c199962dfd5610ced8eca382606e349f7940a4ac7d867b58a046123411cbb4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
|
@ -939,6 +1069,18 @@ dependencies = [
|
|||
"sha2 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kn0sys-lmdb-rs"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fbf491e9e95a325cbfe1459734cec781c0145c0d5cb7c4ced71af742364d19"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc 0.2.158",
|
||||
"liblmdb-sys",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
|
@ -959,9 +1101,9 @@ checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "liblmdb-sys"
|
||||
|
@ -970,7 +1112,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -988,18 +1140,6 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d"
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-rs"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4aefe7b433f795629ce42f35ccf7a620c38bd457238bfaa2489dafc7e36167e7"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0",
|
||||
"libc 0.2.140",
|
||||
"liblmdb-sys",
|
||||
"log 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
@ -1012,21 +1152,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
|
@ -1081,8 +1209,8 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1098,7 +1226,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"http",
|
||||
"httparse",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"mime",
|
||||
"spin",
|
||||
|
@ -1114,8 +1242,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
|
@ -1130,7 +1258,7 @@ name = "neveko_auth"
|
|||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"neveko_core",
|
||||
"rocket",
|
||||
]
|
||||
|
@ -1139,6 +1267,7 @@ dependencies = [
|
|||
name = "neveko_core"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"curve25519-dalek",
|
||||
|
@ -1146,10 +1275,11 @@ dependencies = [
|
|||
"env_logger",
|
||||
"hex",
|
||||
"hmac",
|
||||
"j4-i2p-rs",
|
||||
"jwt",
|
||||
"kn0sys-lmdb-rs",
|
||||
"lazy_static 1.4.0",
|
||||
"lmdb-rs",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"num",
|
||||
"rand",
|
||||
"rand_core",
|
||||
|
@ -1160,9 +1290,20 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1256,7 +1397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1280,7 +1421,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
|
@ -1311,7 +1452,7 @@ checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -1339,7 +1480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -1392,12 +1533,6 @@ version = "0.3.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
|
@ -1441,7 +1576,7 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
@ -1465,6 +1600,26 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -1547,7 +1702,7 @@ dependencies = [
|
|||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
|
@ -1582,7 +1737,7 @@ dependencies = [
|
|||
"futures",
|
||||
"indexmap",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"multer",
|
||||
"num_cpus",
|
||||
|
@ -1633,7 +1788,7 @@ dependencies = [
|
|||
"http",
|
||||
"hyper",
|
||||
"indexmap",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"pear",
|
||||
"percent-encoding",
|
||||
|
@ -1676,7 +1831,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1738,7 +1893,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
|
@ -1749,7 +1904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1840,7 +1995,7 @@ version = "1.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1864,7 +2019,7 @@ version = "0.4.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -1926,6 +2081,20 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.158",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
@ -1957,6 +2126,26 @@ dependencies = [
|
|||
"libc 0.1.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
|
@ -1973,7 +2162,7 @@ version = "0.1.45"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2028,7 +2217,7 @@ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
|
@ -2139,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
|
@ -2266,7 +2455,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
|
@ -2299,7 +2488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2407,6 +2596,59 @@ dependencies = [
|
|||
"windows-targets 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -2461,6 +2703,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2473,6 +2731,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2485,6 +2749,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2497,6 +2767,18 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2509,6 +2791,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2521,6 +2809,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2533,6 +2827,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2545,6 +2845,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
|
|
|
@ -17,6 +17,6 @@ use neveko_core::{
|
|||
/// Creates user on initial login
|
||||
#[get("/login/<signature>/<aid>/<uid>")]
|
||||
pub async fn login(aid: String, uid: String, signature: String) -> Custom<Json<Authorization>> {
|
||||
let m_auth: Authorization = auth::verify_login(aid, uid, signature).await;
|
||||
Custom(Status::Created, Json(m_auth))
|
||||
let m_auth = auth::verify_login(aid, uid, signature).await;
|
||||
Custom(Status::Created, Json(m_auth.unwrap_or_default()))
|
||||
}
|
||||
|
|
468
neveko-contact/Cargo.lock
generated
468
neveko-contact/Cargo.lock
generated
|
@ -17,7 +17,7 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -127,10 +127,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -140,9 +143,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.0.2"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
@ -180,6 +183,12 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -286,7 +295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -301,9 +310,34 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -316,15 +350,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.2"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"fiat-crypto",
|
||||
"platforms",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
|
@ -411,7 +444,7 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
|
||||
dependencies = [
|
||||
"bitflags 2.0.2",
|
||||
"bitflags 2.6.0",
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
|
@ -463,6 +496,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
|
@ -486,7 +525,7 @@ checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
|||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
@ -498,7 +537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -509,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -571,6 +610,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
|
@ -579,6 +624,7 @@ checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
@ -601,12 +647,34 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
|
@ -628,6 +696,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
|
@ -649,8 +718,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.44.0",
|
||||
]
|
||||
|
@ -672,7 +741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
|
@ -719,7 +788,7 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -887,7 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -915,6 +984,67 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "j4-i2p-rs"
|
||||
version = "0.2.0-alpha"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"j4rs",
|
||||
"log",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "j4rs"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "689ae4f2bd4eba82601592f3d22b7e7147b1df52d3b525223f5218990501b4eb"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"java-locator",
|
||||
"jni-sys",
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.158",
|
||||
"libloading",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "java-locator"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c30a312d782b8d56a1e0897d45c1af33f31f9b4a4d13d31207a8675e0223b818"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c199962dfd5610ced8eca382606e349f7940a4ac7d867b58a046123411cbb4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
|
@ -939,6 +1069,18 @@ dependencies = [
|
|||
"sha2 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kn0sys-lmdb-rs"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fbf491e9e95a325cbfe1459734cec781c0145c0d5cb7c4ced71af742364d19"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc 0.2.158",
|
||||
"liblmdb-sys",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
|
@ -959,9 +1101,9 @@ checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "liblmdb-sys"
|
||||
|
@ -970,7 +1112,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -988,18 +1140,6 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-rs"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4aefe7b433f795629ce42f35ccf7a620c38bd457238bfaa2489dafc7e36167e7"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0",
|
||||
"libc 0.2.140",
|
||||
"liblmdb-sys",
|
||||
"log 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
@ -1012,21 +1152,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
|
@ -1081,8 +1209,8 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1098,7 +1226,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"http",
|
||||
"httparse",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"mime",
|
||||
"spin",
|
||||
|
@ -1114,8 +1242,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
|
@ -1130,7 +1258,7 @@ name = "neveko_contact"
|
|||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"neveko_core",
|
||||
"rocket",
|
||||
]
|
||||
|
@ -1139,6 +1267,7 @@ dependencies = [
|
|||
name = "neveko_core"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"curve25519-dalek",
|
||||
|
@ -1146,10 +1275,11 @@ dependencies = [
|
|||
"env_logger",
|
||||
"hex",
|
||||
"hmac",
|
||||
"j4-i2p-rs",
|
||||
"jwt",
|
||||
"kn0sys-lmdb-rs",
|
||||
"lazy_static 1.4.0",
|
||||
"lmdb-rs",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"num",
|
||||
"rand",
|
||||
"rand_core",
|
||||
|
@ -1160,9 +1290,20 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1256,7 +1397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1280,7 +1421,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
|
@ -1311,7 +1452,7 @@ checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -1339,7 +1480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -1392,12 +1533,6 @@ version = "0.3.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
|
@ -1441,7 +1576,7 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
@ -1465,6 +1600,26 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -1547,7 +1702,7 @@ dependencies = [
|
|||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
|
@ -1582,7 +1737,7 @@ dependencies = [
|
|||
"futures",
|
||||
"indexmap",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"multer",
|
||||
"num_cpus",
|
||||
|
@ -1633,7 +1788,7 @@ dependencies = [
|
|||
"http",
|
||||
"hyper",
|
||||
"indexmap",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"pear",
|
||||
"percent-encoding",
|
||||
|
@ -1676,7 +1831,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1738,7 +1893,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
|
@ -1749,7 +1904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1840,7 +1995,7 @@ version = "1.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1864,7 +2019,7 @@ version = "0.4.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -1926,6 +2081,20 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.158",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
@ -1957,6 +2126,26 @@ dependencies = [
|
|||
"libc 0.1.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
|
@ -1973,7 +2162,7 @@ version = "0.1.45"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2028,7 +2217,7 @@ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
|
@ -2139,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
|
@ -2266,7 +2455,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
|
@ -2299,7 +2488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2407,6 +2596,59 @@ dependencies = [
|
|||
"windows-targets 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -2461,6 +2703,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2473,6 +2731,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2485,6 +2749,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2497,6 +2767,18 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2509,6 +2791,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2521,6 +2809,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2533,6 +2827,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2545,6 +2845,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
|
|
|
@ -15,7 +15,6 @@ use neveko_core::{
|
|||
models::*,
|
||||
proof,
|
||||
reqres,
|
||||
utils,
|
||||
};
|
||||
|
||||
/// Add contact
|
||||
|
@ -25,17 +24,18 @@ pub async fn add_contact(
|
|||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<Contact>> {
|
||||
let res_contact = contact::create(&req_contact).await;
|
||||
if res_contact.cid == utils::empty_string() {
|
||||
let u_contact = res_contact.unwrap_or_default();
|
||||
if u_contact.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(res_contact))
|
||||
Custom(Status::Ok, Json(u_contact))
|
||||
}
|
||||
|
||||
/// Return all contacts
|
||||
#[get("/")]
|
||||
pub async fn get_contacts(_token: auth::BearerToken) -> Custom<Json<Vec<Contact>>> {
|
||||
let contacts = contact::find_all();
|
||||
Custom(Status::Ok, Json(contacts))
|
||||
Custom(Status::Ok, Json(contacts.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Delete a contact by CID
|
||||
|
@ -44,9 +44,9 @@ pub async fn remove_contact(
|
|||
contact: String,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<Vec<Contact>>> {
|
||||
contact::delete(&contact);
|
||||
let _ = contact::delete(&contact);
|
||||
let contacts = contact::find_all();
|
||||
Custom(Status::Ok, Json(contacts))
|
||||
Custom(Status::Ok, Json(contacts.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// prove payment
|
||||
|
|
385
neveko-core/Cargo.lock
generated
385
neveko-core/Cargo.lock
generated
|
@ -17,7 +17,7 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -126,6 +126,15 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -174,6 +183,12 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -280,7 +295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -295,9 +310,34 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -465,6 +505,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
|
@ -500,7 +546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -511,7 +557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -573,6 +619,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.27"
|
||||
|
@ -581,6 +633,7 @@ checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
@ -603,12 +656,34 @@ version = "0.3.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.27"
|
||||
|
@ -630,6 +705,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
|
@ -651,7 +727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.44.0",
|
||||
|
@ -674,7 +750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
|
@ -721,7 +797,7 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -889,7 +965,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -917,6 +993,67 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "j4-i2p-rs"
|
||||
version = "0.2.0-alpha"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"j4rs",
|
||||
"log",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "j4rs"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "689ae4f2bd4eba82601592f3d22b7e7147b1df52d3b525223f5218990501b4eb"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"java-locator",
|
||||
"jni-sys",
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.158",
|
||||
"libloading",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "java-locator"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c30a312d782b8d56a1e0897d45c1af33f31f9b4a4d13d31207a8675e0223b818"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c199962dfd5610ced8eca382606e349f7940a4ac7d867b58a046123411cbb4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
|
@ -948,7 +1085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "29e0b46b27729cc3238baa573fe2f4df74af76ad1fdb576ff9ccabb97ecf756c"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"liblmdb-sys",
|
||||
"log",
|
||||
]
|
||||
|
@ -973,9 +1110,9 @@ checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "liblmdb-sys"
|
||||
|
@ -984,7 +1121,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1071,7 +1218,7 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -1104,7 +1251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
|
@ -1119,6 +1266,7 @@ dependencies = [
|
|||
name = "neveko_core"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"curve25519-dalek",
|
||||
|
@ -1126,6 +1274,7 @@ dependencies = [
|
|||
"env_logger",
|
||||
"hex",
|
||||
"hmac",
|
||||
"j4-i2p-rs",
|
||||
"jwt",
|
||||
"kn0sys-lmdb-rs",
|
||||
"lazy_static 1.4.0",
|
||||
|
@ -1140,9 +1289,20 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1242,7 +1402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1266,7 +1426,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
|
@ -1297,7 +1457,7 @@ checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -1325,7 +1485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -1427,7 +1587,7 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
@ -1451,6 +1611,26 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -1662,7 +1842,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1724,7 +1904,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
|
@ -1735,7 +1915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1826,7 +2006,7 @@ version = "1.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1850,7 +2030,7 @@ version = "0.4.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -1912,6 +2092,20 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.158",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
@ -1943,6 +2137,26 @@ dependencies = [
|
|||
"libc 0.1.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
|
@ -1959,7 +2173,7 @@ version = "0.1.45"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2018,7 +2232,7 @@ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
|
@ -2397,6 +2611,59 @@ dependencies = [
|
|||
"windows-targets 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -2451,6 +2718,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2463,6 +2746,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2475,6 +2764,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2487,6 +2782,18 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2499,6 +2806,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2511,6 +2824,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2523,6 +2842,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2535,6 +2860,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
chrono = "0.4.23"
|
||||
clap = { version = "4.1.4", features = ["derive"] }
|
||||
curve25519-dalek = "4.1.3"
|
||||
|
@ -13,6 +14,7 @@ diqwest = "1.1.1"
|
|||
env_logger = "0.10.0"
|
||||
hex = "0.4.3"
|
||||
hmac = "0.12.1"
|
||||
j4-i2p-rs = { path = "../j4-i2p-rs", version = "0.2.0-alpha" }
|
||||
jwt = "0.16.0"
|
||||
lazy_static = "1.4.0"
|
||||
kn0sys-lmdb-rs = "0.1.2"
|
||||
|
@ -21,10 +23,12 @@ num = "0.4.1"
|
|||
rand = "0.8.5"
|
||||
rand_core = "0.6.4"
|
||||
reqwest = { version = "0.11.12", features = ["json"] }
|
||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||
rocket = { version = "0.5.0-rc.3", features = ["json"] }
|
||||
rpassword = "0.0.4"
|
||||
schedule_recv = "0.1.0"
|
||||
sha2 = "0.10.6"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.94"
|
||||
sysinfo = "0.31.2"
|
||||
thiserror = "1.0.63"
|
||||
tokio = "1.25.0"
|
||||
|
|
|
@ -10,21 +10,21 @@ pub struct Args {
|
|||
short,
|
||||
long,
|
||||
help = "Set release environment (dev, prod)",
|
||||
default_value = "dev"
|
||||
default_value = "prod"
|
||||
)]
|
||||
pub release_env: String,
|
||||
/// Monero location
|
||||
#[arg(
|
||||
long,
|
||||
help = "Monero download absolute path.",
|
||||
default_value = "monero-x86_64-linux-gnu-v0.18.3.3"
|
||||
default_value = "monero-x86_64-linux-gnu-v0.18.3.4"
|
||||
)]
|
||||
pub monero_location: String,
|
||||
/// Monero RPC host
|
||||
#[arg(
|
||||
long,
|
||||
help = "Monero RPC host.",
|
||||
default_value = "http://localhost:38083"
|
||||
default_value = "http://localhost:18083"
|
||||
)]
|
||||
pub monero_rpc_host: String,
|
||||
/// Monero blockchain location
|
||||
|
@ -34,18 +34,11 @@ pub struct Args {
|
|||
default_value = "/home/user/.bitmonero"
|
||||
)]
|
||||
pub monero_blockchain_dir: String,
|
||||
/// Absolute path to i2p zero
|
||||
#[arg(
|
||||
long,
|
||||
help = "Absolute path to i2p-zero directroy",
|
||||
default_value = "/home/user/i2p-zero-linux.v1.21"
|
||||
)]
|
||||
pub i2p_zero_dir: String,
|
||||
/// Monero RPC daemon host
|
||||
#[arg(
|
||||
long,
|
||||
help = "Monero RPC daemon.",
|
||||
default_value = "http://localhost:38081"
|
||||
default_value = "http://localhost:18081"
|
||||
)]
|
||||
pub monero_rpc_daemon: String,
|
||||
/// Monero RPC Username
|
||||
|
@ -97,14 +90,14 @@ pub struct Args {
|
|||
#[arg(
|
||||
long,
|
||||
help = "i2p http proxy host",
|
||||
default_value = "http://localhost:4444"
|
||||
default_value = "http://localhost:4456"
|
||||
)]
|
||||
pub i2p_proxy_host: String,
|
||||
/// i2p wallet proxy host (i2p socks)
|
||||
#[arg(
|
||||
long,
|
||||
help = "i2p remote node socks proxy host",
|
||||
default_value = "http://localhost:9051"
|
||||
default_value = "http://localhost:9056"
|
||||
)]
|
||||
pub i2p_socks_proxy_host: String,
|
||||
/// Connect wallet rpc for a remote-node, WARNING: may harm privacy
|
||||
|
@ -149,7 +142,7 @@ pub struct Args {
|
|||
default_value = "/home/user/neveko/i2p-manual"
|
||||
)]
|
||||
pub i2p_tunnels_json: String,
|
||||
/// Dummy flag for normal neveko i2p-zero config. Future use.
|
||||
/// Dummy flag for normal neveko i2p config. Future use.
|
||||
#[arg(
|
||||
long,
|
||||
help = "Normal mode. Neveko will handle i2p proxy tunnels and identity.",
|
||||
|
@ -160,7 +153,7 @@ pub struct Args {
|
|||
#[arg(
|
||||
long,
|
||||
help = "Set i2p anon inbound connectivity",
|
||||
default_value = "38089"
|
||||
default_value = "18089"
|
||||
)]
|
||||
pub anon_inbound_port: u16,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
use crate::{
|
||||
args,
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
models::*,
|
||||
monero,
|
||||
reqres,
|
||||
|
@ -10,6 +13,7 @@ use crate::{
|
|||
utils,
|
||||
};
|
||||
use clap::Parser;
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -32,7 +36,7 @@ use sha2::Sha384;
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
/// Create authorization data to sign and expiration
|
||||
pub fn create(address: &String) -> Authorization {
|
||||
pub fn create(address: &String) -> Result<Authorization, MdbError> {
|
||||
info!("creating auth");
|
||||
let aid: String = format!("{}{}", crate::AUTH_DB_KEY, utils::generate_rnd());
|
||||
let rnd: String = utils::generate_rnd();
|
||||
|
@ -41,32 +45,33 @@ pub fn create(address: &String) -> Authorization {
|
|||
let new_auth = Authorization {
|
||||
aid,
|
||||
created,
|
||||
uid: utils::empty_string(),
|
||||
uid: String::new(),
|
||||
rnd,
|
||||
token,
|
||||
xmr_address: String::from(address),
|
||||
};
|
||||
let s = db::Interface::open();
|
||||
debug!("insert auth: {:?}", &new_auth);
|
||||
let k = &new_auth.aid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Authorization::to_db(&new_auth));
|
||||
new_auth
|
||||
let k = &new_auth.aid.as_bytes();
|
||||
let v = bincode::serialize(&new_auth).unwrap_or_default();
|
||||
let db = &DATABASE_LOCK;
|
||||
db::write_chunks(&db.env, &db.handle, k, &v)?;
|
||||
Ok(new_auth)
|
||||
}
|
||||
|
||||
/// Authorization lookup for recurring requests
|
||||
pub fn find(aid: &String) -> Authorization {
|
||||
pub fn find(aid: &String) -> Result<Authorization, MdbError> {
|
||||
info!("searching for auth: {}", aid);
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(aid));
|
||||
debug!("auth read: {}", r);
|
||||
if r == utils::empty_string() {
|
||||
return Default::default();
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &aid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
Authorization::from_db(String::from(aid), r)
|
||||
let result: Authorization = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Update new authorization creation time
|
||||
fn update_expiration(f_auth: &Authorization, address: &String) -> Authorization {
|
||||
fn update_expiration(f_auth: &Authorization, address: &String) -> Result<Authorization, MdbError> {
|
||||
info!("modify auth expiration");
|
||||
let data = utils::generate_rnd();
|
||||
let time: i64 = chrono::offset::Utc::now().timestamp();
|
||||
|
@ -77,27 +82,28 @@ fn update_expiration(f_auth: &Authorization, address: &String) -> Authorization
|
|||
data,
|
||||
create_token(String::from(address), time),
|
||||
);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_auth.aid);
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
&u_auth.aid,
|
||||
&Authorization::to_db(&u_auth),
|
||||
);
|
||||
return u_auth;
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, &u_auth.aid.as_bytes().to_vec())?;
|
||||
let k = u_auth.aid.as_bytes();
|
||||
let v = bincode::serialize(&u_auth).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k, &v)?;
|
||||
Ok(u_auth)
|
||||
}
|
||||
|
||||
/// Performs the signature verfication against stored auth
|
||||
pub async fn verify_login(aid: String, uid: String, signature: String) -> Authorization {
|
||||
pub async fn verify_login(
|
||||
aid: String,
|
||||
uid: String,
|
||||
signature: String,
|
||||
) -> Result<Authorization, MdbError> {
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let m_address: reqres::XmrRpcAddressResponse = monero::get_address().await;
|
||||
let address = m_address.result.address;
|
||||
let f_auth: Authorization = find(&aid);
|
||||
if f_auth.xmr_address == utils::empty_string() {
|
||||
let f_auth: Authorization = find(&aid)?;
|
||||
if f_auth.xmr_address.is_empty() {
|
||||
error!("auth not found");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return create(&address);
|
||||
|
@ -113,51 +119,47 @@ pub async fn verify_login(aid: String, uid: String, signature: String) -> Author
|
|||
if sig_address == utils::ApplicationErrors::LoginError.value() {
|
||||
error!("signature validation failed");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return f_auth;
|
||||
return Ok(f_auth);
|
||||
}
|
||||
let f_user: User = user::find(&uid);
|
||||
if f_user.xmr_address == utils::empty_string() {
|
||||
let f_user: User = user::find(&uid)?;
|
||||
if f_user.xmr_address.is_empty() {
|
||||
info!("creating new user");
|
||||
let u: User = user::create(&address);
|
||||
let u: User = user::create(&address)?;
|
||||
// update auth with uid
|
||||
let u_auth = Authorization::update_uid(f_auth, String::from(&u.uid));
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_auth.aid);
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
&u_auth.aid,
|
||||
&Authorization::to_db(&u_auth),
|
||||
);
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, &u_auth.aid.as_bytes())?;
|
||||
let v = bincode::serialize(&u_auth).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, u_auth.aid.as_bytes(), &v)?;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return u_auth;
|
||||
} else if f_user.xmr_address != utils::empty_string() {
|
||||
Ok(u_auth)
|
||||
} else if !f_user.xmr_address.is_empty() {
|
||||
info!("returning user");
|
||||
let m_access = verify_access(&address, &signature).await;
|
||||
let m_access = verify_access(&address, &signature).await?;
|
||||
if !m_access {
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return Default::default();
|
||||
return Ok(Default::default());
|
||||
}
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return f_auth;
|
||||
return Ok(f_auth);
|
||||
} else {
|
||||
error!("error creating user");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return Default::default();
|
||||
return Ok(Default::default());
|
||||
}
|
||||
}
|
||||
|
||||
/// Called during auth flow to update data to sign and expiration
|
||||
async fn verify_access(address: &String, signature: &String) -> bool {
|
||||
async fn verify_access(address: &String, signature: &String) -> Result<bool, MdbError> {
|
||||
// look up auth for address
|
||||
let f_auth: Authorization = find(address);
|
||||
if f_auth.xmr_address != utils::empty_string() {
|
||||
let f_auth: Authorization = find(address)?;
|
||||
if !f_auth.xmr_address.is_empty() {
|
||||
// check expiration, generate new data to sign if necessary
|
||||
let now: i64 = chrono::offset::Utc::now().timestamp();
|
||||
let expiration = get_auth_expiration();
|
||||
if now > f_auth.created + expiration {
|
||||
update_expiration(&f_auth, address);
|
||||
return false;
|
||||
update_expiration(&f_auth, address)?;
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
// verify signature on the data if not expired
|
||||
|
@ -171,10 +173,10 @@ async fn verify_access(address: &String, signature: &String) -> bool {
|
|||
};
|
||||
if sig_address == utils::ApplicationErrors::LoginError.value() {
|
||||
debug!("signing failed");
|
||||
return false;
|
||||
return Ok(false);
|
||||
}
|
||||
info!("auth verified");
|
||||
return true;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// get the auth expiration command line configuration
|
||||
|
@ -184,8 +186,8 @@ fn get_auth_expiration() -> i64 {
|
|||
}
|
||||
|
||||
fn create_token(address: String, created: i64) -> String {
|
||||
let jwt_secret_key = utils::get_jwt_secret_key();
|
||||
let key: Hmac<Sha384> = Hmac::new_from_slice(&jwt_secret_key.as_bytes()).expect("hash");
|
||||
let jwt_secret_key = utils::get_jwt_secret_key().unwrap_or_default();
|
||||
let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect("hash");
|
||||
let header = Header {
|
||||
algorithm: AlgorithmType::Hs384,
|
||||
..Default::default()
|
||||
|
@ -202,6 +204,12 @@ fn create_token(address: String, created: i64) -> String {
|
|||
#[derive(Debug)]
|
||||
pub struct BearerToken(String);
|
||||
|
||||
impl BearerToken {
|
||||
pub fn get_token(self) -> String {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BearerTokenError {
|
||||
Expired,
|
||||
|
@ -217,7 +225,7 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
let env = utils::get_release_env();
|
||||
let dev = utils::ReleaseEnvironment::Development;
|
||||
if env == dev {
|
||||
return Outcome::Success(BearerToken(utils::empty_string()));
|
||||
return Outcome::Success(BearerToken(String::new()));
|
||||
}
|
||||
let token = request.headers().get_one("token");
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
|
@ -231,8 +239,8 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
match token {
|
||||
Some(token) => {
|
||||
// check validity
|
||||
let jwt_secret_key = utils::get_jwt_secret_key();
|
||||
let key: Hmac<Sha384> = Hmac::new_from_slice(&jwt_secret_key.as_bytes()).expect("");
|
||||
let jwt_secret_key = utils::get_jwt_secret_key().unwrap_or_default();
|
||||
let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect("");
|
||||
let jwt: Result<
|
||||
Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>,
|
||||
jwt::Error,
|
||||
|
@ -250,10 +258,7 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
}
|
||||
// verify expiration
|
||||
let now: i64 = chrono::offset::Utc::now().timestamp();
|
||||
let expire = match claims["expiration"].parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let expire = claims["expiration"].parse::<i64>().unwrap_or(0);
|
||||
if now > expire {
|
||||
return Outcome::Failure((
|
||||
Status::Unauthorized,
|
||||
|
@ -275,82 +280,70 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::error::NevekoError;
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn find_test_auth(k: &String) -> Authorization {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s: db::Interface = db::Interface::async_open().await;
|
||||
let v = db::Interface::async_read(&s.env, &s.handle, k).await;
|
||||
Authorization::from_db(String::from(k), v)
|
||||
fn find_test_auth(k: &String) -> Result<Authorization, MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())?;
|
||||
let result: Authorization = bincode::deserialize(&v[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
fn create_test() -> Result<(), MdbError> {
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
let test_auth = create(&address);
|
||||
let test_auth = create(&address)?;
|
||||
assert_eq!(test_auth.xmr_address, address);
|
||||
tokio::spawn(async move {
|
||||
cleanup(&test_auth.aid).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let _ = cleanup(&test_auth.aid);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
fn find_test() -> Result<(), MdbError> {
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
let test_auth = create(&address);
|
||||
let test_auth = create(&address)?;
|
||||
let aid = String::from(&test_auth.aid);
|
||||
tokio::spawn(async move {
|
||||
let f_auth: Authorization = find_test_auth(&aid).await;
|
||||
assert_ne!(f_auth.xmr_address, address);
|
||||
cleanup(&test_auth.aid).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let f_auth: Authorization = find_test_auth(&aid)?;
|
||||
assert_eq!(f_auth.xmr_address, address);
|
||||
cleanup(&test_auth.aid)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_expiration_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
fn update_expiration_test() -> Result<(), MdbError> {
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
let test_auth = create(&address);
|
||||
let test_auth = create(&address)?;
|
||||
let aid = String::from(&test_auth.aid);
|
||||
tokio::spawn(async move {
|
||||
let f_auth = find_test_auth(&aid).await;
|
||||
let u_auth = update_expiration(&f_auth, &address);
|
||||
assert!(f_auth.created < u_auth.created);
|
||||
cleanup(&test_auth.aid).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let f_auth = find_test_auth(&aid)?;
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let u_auth = update_expiration(&f_auth, &address)?;
|
||||
assert!(f_auth.created < u_auth.created);
|
||||
let _ = cleanup(&test_auth.aid)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_token_test() {
|
||||
fn create_token_test() -> Result<(), NevekoError> {
|
||||
let test_value = "test";
|
||||
let test_jwt = create_token(String::from(test_value), 0);
|
||||
let jwt_secret_key = utils::get_jwt_secret_key();
|
||||
let jwt_secret_key = utils::get_jwt_secret_key().unwrap_or_default();
|
||||
let key: Hmac<Sha384> = Hmac::new_from_slice(&jwt_secret_key.as_bytes()).expect("");
|
||||
let jwt: Result<
|
||||
Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>,
|
||||
|
@ -364,6 +357,7 @@ mod tests {
|
|||
assert_eq!(expected, actual);
|
||||
}
|
||||
Err(_) => error!("create_token_test error"),
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
//! contact operations module
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
i2p,
|
||||
models::*,
|
||||
monero,
|
||||
reqres,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -21,22 +26,8 @@ pub const NEVEKO_VENDOR_ENABLED: &str = "NEVEKO_VENDOR_ENABLED";
|
|||
pub const NEVEKO_VENDOR_MODE_OFF: &str = "0";
|
||||
pub const NEVEKO_VENDOR_MODE_ON: &str = "1";
|
||||
|
||||
pub enum Prune {
|
||||
Full,
|
||||
Pruned,
|
||||
}
|
||||
|
||||
impl Prune {
|
||||
pub fn value(&self) -> u32 {
|
||||
match *self {
|
||||
Prune::Full => 0,
|
||||
Prune::Pruned => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new contact
|
||||
pub async fn create(c: &Json<Contact>) -> Contact {
|
||||
pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
|
||||
let f_cid: String = format!("{}{}", crate::CONTACT_DB_KEY, utils::generate_rnd());
|
||||
info!("creating contact: {}", f_cid);
|
||||
let new_contact = Contact {
|
||||
|
@ -48,80 +39,90 @@ pub async fn create(c: &Json<Contact>) -> Contact {
|
|||
};
|
||||
let is_valid = validate_contact(c).await;
|
||||
if !is_valid {
|
||||
return Default::default();
|
||||
log::error!("invalid contact");
|
||||
return Ok(Default::default());
|
||||
}
|
||||
debug!("insert contact: {:?}", &new_contact);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_contact.cid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Contact::to_db(&new_contact));
|
||||
let v = bincode::serialize(&new_contact).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)?;
|
||||
// in order to retrieve all contact, write keys to with cl
|
||||
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let str_lk = String::from(list_key);
|
||||
let lk_bytes = str_lk.as_bytes();
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &lk_bytes.to_vec())?;
|
||||
if r.is_empty() {
|
||||
debug!("creating contact index");
|
||||
}
|
||||
let contact_list = [r, String::from(&f_cid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let contact_list = [old, String::from(&f_cid)].join(",");
|
||||
let s_contactlist = bincode::serialize(&contact_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing contact index {} for key {}",
|
||||
contact_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &contact_list);
|
||||
new_contact
|
||||
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_contactlist)?;
|
||||
Ok(new_contact)
|
||||
}
|
||||
|
||||
/// Contact lookup
|
||||
pub fn find(cid: &String) -> Contact {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(cid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(cid: &String) -> Result<Contact, MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &cid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
Contact::from_db(String::from(cid), r)
|
||||
let result: Contact = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Contact lookup
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Contact {
|
||||
let contacts = find_all();
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Result<Contact, NevekoError> {
|
||||
let contacts = find_all().map_err(|_| NevekoError::Database(MdbError::NotFound))?;
|
||||
for c in contacts {
|
||||
if c.i2p_address == String::from(i2p_address) {
|
||||
return c;
|
||||
if c.i2p_address == *i2p_address {
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
Default::default()
|
||||
Err(NevekoError::Database(MdbError::NotFound))
|
||||
}
|
||||
|
||||
/// Contact deletion
|
||||
pub fn delete(cid: &String) {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(cid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn delete(cid: &String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &cid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact not found");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
db::Interface::delete(&s.env, &s.handle, &cid);
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, cid.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// All contact lookup
|
||||
pub fn find_all() -> Vec<Contact> {
|
||||
pub fn find_all() -> Result<Vec<Contact>, MdbError> {
|
||||
info!("looking up all contacts");
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact index not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let v_cid = r.split(",");
|
||||
let v: Vec<String> = v_cid.map(|s| String::from(s)).collect();
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_cid = str_r.split(",");
|
||||
let v: Vec<String> = v_cid.map(String::from).collect();
|
||||
let mut contacts: Vec<Contact> = Vec::new();
|
||||
for id in v {
|
||||
if id != utils::empty_string() {
|
||||
let contact: Contact = find(&id);
|
||||
if !id.is_empty() {
|
||||
let contact: Contact = find(&id)?;
|
||||
contacts.push(contact);
|
||||
}
|
||||
}
|
||||
contacts
|
||||
Ok(contacts)
|
||||
}
|
||||
|
||||
async fn validate_contact(j: &Json<Contact>) -> bool {
|
||||
|
@ -140,35 +141,41 @@ async fn validate_contact(j: &Json<Contact>) -> bool {
|
|||
}
|
||||
|
||||
/// Send our information
|
||||
pub async fn share() -> Contact {
|
||||
let s = db::Interface::async_open().await;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, NEVEKO_VENDOR_ENABLED).await;
|
||||
let is_vendor = r == NEVEKO_VENDOR_MODE_ON;
|
||||
pub async fn share() -> Result<Contact, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&NEVEKO_VENDOR_ENABLED.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let is_vendor = str_r == NEVEKO_VENDOR_MODE_ON;
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let m_address: reqres::XmrRpcAddressResponse = monero::get_address().await;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
let nmpk = utils::get_nmpk();
|
||||
let i2p_address = i2p::get_destination(None);
|
||||
let nmpk = utils::get_nmpk()?;
|
||||
let i2p_address = i2p::get_destination(i2p::ServerTunnelType::App)?;
|
||||
let xmr_address = m_address.result.address;
|
||||
Contact {
|
||||
cid: utils::empty_string(),
|
||||
Ok(Contact {
|
||||
cid: String::new(),
|
||||
nmpk,
|
||||
i2p_address,
|
||||
is_vendor,
|
||||
xmr_address,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn exists(from: &String) -> bool {
|
||||
let all = find_all();
|
||||
pub fn exists(from: &String) -> Result<bool, MdbError> {
|
||||
let all = find_all()?;
|
||||
let mut addresses: Vec<String> = Vec::new();
|
||||
for c in all {
|
||||
addresses.push(c.i2p_address);
|
||||
}
|
||||
return addresses.contains(from);
|
||||
Ok(addresses.contains(from))
|
||||
}
|
||||
|
||||
/// Get invoice for jwp creation
|
||||
|
@ -228,10 +235,10 @@ pub async fn add_contact_request(contact: String) -> Result<Contact, Box<dyn Err
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -252,7 +259,10 @@ mod tests {
|
|||
tokio::spawn(async move {
|
||||
let test_contact = create(&j_contact).await;
|
||||
let expected: Contact = Default::default();
|
||||
assert_eq!(test_contact.xmr_address, expected.xmr_address);
|
||||
assert_eq!(
|
||||
test_contact.unwrap_or_default().xmr_address,
|
||||
expected.xmr_address
|
||||
);
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
}
|
||||
|
@ -272,12 +282,12 @@ mod tests {
|
|||
..Default::default()
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Contact::to_db(&expected_contact))
|
||||
.await;
|
||||
let actual_contact: Contact = find(&String::from(k));
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = bincode::serialize(&expected_contact).unwrap_or_default();
|
||||
let _ = db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v);
|
||||
let actual_contact: Contact = find(&String::from(k)).unwrap_or_default();
|
||||
assert_eq!(expected_contact.xmr_address, actual_contact.xmr_address);
|
||||
cleanup(&String::from(k)).await;
|
||||
let _ = cleanup(&String::from(k));
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
}
|
||||
|
|
|
@ -1,185 +1,212 @@
|
|||
//! Primary LMDB interface for read, write, delete etc.
|
||||
#![deny(missing_docs)]
|
||||
|
||||
//! Logic for interfacing with LMDB.
|
||||
|
||||
extern crate kn0sys_lmdb_rs as lmdb;
|
||||
|
||||
use lmdb::{
|
||||
DbFlags,
|
||||
DbHandle,
|
||||
EnvBuilder,
|
||||
Environment,
|
||||
};
|
||||
use lmdb::*;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
info,
|
||||
};
|
||||
use std::sync::LazyLock;
|
||||
use sysinfo::System;
|
||||
|
||||
use crate::utils;
|
||||
|
||||
/// LMDB Interface allows access to the env
|
||||
/// Ratio of map size to available memory is 20 percent
|
||||
const MAP_SIZE_MEMORY_RATIO: f32 = 0.2;
|
||||
/// Ratio of chunk size to available memory is 0.2 percent
|
||||
const CHUNK_SIZE_MEMORY_RATIO: f32 = MAP_SIZE_MEMORY_RATIO * 0.01;
|
||||
|
||||
/// Database lock is initialized on startup in order to cache the db handle
|
||||
pub static DATABASE_LOCK: LazyLock<DatabaseEnvironment> = LazyLock::new(|| {
|
||||
DatabaseEnvironment::open().unwrap_or_else(|_| panic!("failed to initialize lmdb!"))
|
||||
});
|
||||
|
||||
/// The database environment for handling primary database operations.
|
||||
///
|
||||
/// and handle for the write, read and delete
|
||||
///
|
||||
/// functionality.
|
||||
pub struct Interface {
|
||||
/// By default the database will be written to /home/user/.neveko/{ENV}/lmdb
|
||||
pub struct DatabaseEnvironment {
|
||||
/// Represents LMDB Environment.
|
||||
pub env: Environment,
|
||||
/// DB handle.
|
||||
pub handle: DbHandle,
|
||||
}
|
||||
|
||||
impl Interface {
|
||||
/// Instantiation of ```Environment``` and ```DbHandle```
|
||||
pub fn open() -> Self {
|
||||
info!("excecuting lmdb open");
|
||||
let release_env = utils::get_release_env();
|
||||
let file_path = format!(
|
||||
"/home/{}/.{}/",
|
||||
std::env::var("USER").unwrap_or(String::from("user")),
|
||||
crate::APP_NAME,
|
||||
);
|
||||
let mut env_str: &str = "test-lmdb";
|
||||
if release_env != utils::ReleaseEnvironment::Development {
|
||||
env_str = "lmdb";
|
||||
};
|
||||
let env = EnvBuilder::new()
|
||||
// increase map size for writing the multisig txset
|
||||
.map_size(crate::LMDB_MAPSIZE)
|
||||
.open(format!("{}/{}", file_path, env_str), 0o777)
|
||||
.expect(&format!("could not open LMDB at {}", file_path));
|
||||
let handle = env.get_default_db(DbFlags::empty()).unwrap();
|
||||
Interface { env, handle }
|
||||
}
|
||||
pub async fn async_open() -> Self {
|
||||
info!("excecuting lmdb async open");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::open()
|
||||
}
|
||||
/// Write a key-value to LMDB. NEVEKO does not currently support
|
||||
impl DatabaseEnvironment {
|
||||
/// Opens environment in specified path. The map size defaults to 20 percent
|
||||
///
|
||||
/// writing multiple key value pairs.
|
||||
pub fn write(e: &Environment, h: &DbHandle, k: &str, v: &str) {
|
||||
/// of available memory and can be set via the `LMDB_MAP_SIZE` environment
|
||||
/// variable.
|
||||
///
|
||||
/// The path of the user can be set with `LMDB_USER`.
|
||||
pub fn open() -> Result<Self, MdbError> {
|
||||
let s = System::new_all();
|
||||
let default_map_size: u64 =
|
||||
(s.available_memory() as f32 * MAP_SIZE_MEMORY_RATIO).floor() as u64;
|
||||
let env_map_size: u64 = match std::env::var("LMDB_MAP_SIZE") {
|
||||
Err(_) => default_map_size,
|
||||
Ok(size) => size.parse::<u64>().unwrap_or(default_map_size),
|
||||
};
|
||||
info!("setting lmdb map size to: {}", env_map_size);
|
||||
let user: String = match std::env::var("LMDB_USER") {
|
||||
Err(_) => std::env::var("USER").unwrap_or(String::from("user")),
|
||||
Ok(user) => user,
|
||||
};
|
||||
info!("$LMDB_USER={}", user);
|
||||
info!("excecuting lmdb open");
|
||||
let file_path: String = format!("/home/{}/.{}/", user, "neveko");
|
||||
let env_str = utils::get_release_env().value();
|
||||
let env: Environment = EnvBuilder::new()
|
||||
.map_size(env_map_size)
|
||||
.open(format!("{}/{}", file_path, env_str), 0o777)
|
||||
.unwrap_or_else(|_| panic!("could not open LMDB at {}", file_path));
|
||||
let default: Result<DbHandle, MdbError> = env.get_default_db(DbFlags::empty());
|
||||
if default.is_err() {
|
||||
panic!("could not set db handle")
|
||||
}
|
||||
let handle: DbHandle = default?;
|
||||
Ok(DatabaseEnvironment { env, handle })
|
||||
}
|
||||
/// Write a key/value pair to the database. It is not possible to
|
||||
///
|
||||
/// write with empty keys.
|
||||
fn write(e: &Environment, h: &DbHandle, k: &Vec<u8>, v: &Vec<u8>) -> Result<(), MdbError> {
|
||||
info!("excecuting lmdb write");
|
||||
// don't try and write empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't write empty key");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let txn = e.new_transaction().unwrap();
|
||||
let new_txn = e.new_transaction()?;
|
||||
let txn = new_txn;
|
||||
{
|
||||
// get a database bound to this transaction
|
||||
let db = txn.bind(&h);
|
||||
let pair = vec![(k, v)];
|
||||
let db: Database = txn.bind(h);
|
||||
let pair: Vec<(&Vec<u8>, &Vec<u8>)> = vec![(k, v)];
|
||||
for &(key, value) in pair.iter() {
|
||||
db.set(&key, &value).unwrap();
|
||||
db.set(key, value)
|
||||
.unwrap_or_else(|_| error!("failed to set key: {:?}", k));
|
||||
}
|
||||
}
|
||||
match txn.commit() {
|
||||
Err(_) => error!("failed to commit!"),
|
||||
Ok(_) => (),
|
||||
}
|
||||
txn.commit()
|
||||
}
|
||||
pub async fn async_write(e: &Environment, h: &DbHandle, k: &str, v: &str) {
|
||||
info!("excecuting lmdb async write");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::write(e, h, k, v)
|
||||
}
|
||||
/// Read a value from LMDB by passing the key as a static
|
||||
/// Read key from the database. If it doesn't exist then
|
||||
///
|
||||
/// string. If the value does not exist an empty string is
|
||||
/// an empty vector will be returned. Treat all empty vectors
|
||||
///
|
||||
/// returned. NEVEKO does not currently support duplicate keys.
|
||||
pub fn read(e: &Environment, h: &DbHandle, k: &str) -> String {
|
||||
/// from database operations as failures.
|
||||
pub fn read(e: &Environment, h: &DbHandle, k: &Vec<u8>) -> Result<Vec<u8>, MdbError> {
|
||||
info!("excecuting lmdb read");
|
||||
// don't try and read empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't read empty key");
|
||||
return utils::empty_string();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let get_reader = e.get_reader();
|
||||
let reader: ReadonlyTransaction = get_reader?;
|
||||
let db: Database = reader.bind(h);
|
||||
let mut result: Vec<u8> = Vec::new();
|
||||
for num_writes in 0..usize::MAX {
|
||||
let mut new_key: Vec<u8> = k.to_vec();
|
||||
let mut key_count: Vec<u8> = (num_writes).to_be_bytes().to_vec();
|
||||
new_key.append(&mut key_count);
|
||||
let mut r = db.get::<Vec<u8>>(&new_key).unwrap_or_default();
|
||||
if r.is_empty() {
|
||||
break;
|
||||
}
|
||||
result.append(&mut r);
|
||||
}
|
||||
let reader = e.get_reader().unwrap();
|
||||
let db = reader.bind(&h);
|
||||
let value = db.get::<&str>(&k).unwrap_or_else(|_| "");
|
||||
let r = String::from(value);
|
||||
{
|
||||
if r == utils::empty_string() {
|
||||
debug!("Failed to read from db.")
|
||||
if result.is_empty() {
|
||||
error!("failed to read key {:?} from db", k);
|
||||
}
|
||||
}
|
||||
r
|
||||
Ok(result)
|
||||
}
|
||||
pub async fn async_read(e: &Environment, h: &DbHandle, k: &str) -> String {
|
||||
info!("excecuting lmdb async read");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::read(e, h, k)
|
||||
}
|
||||
/// Delete a value from LMDB by passing the key as a
|
||||
///
|
||||
/// static string. If the value does not exist then an
|
||||
///
|
||||
/// error will be logged.
|
||||
pub fn delete(e: &Environment, h: &DbHandle, k: &str) {
|
||||
/// Deletes a key/value pair from the database
|
||||
pub fn delete(e: &Environment, h: &DbHandle, k: &[u8]) -> Result<(), MdbError> {
|
||||
info!("excecuting lmdb delete");
|
||||
// don't try and delete empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't delete empty key");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let txn = e.new_transaction().unwrap();
|
||||
let new_txn = e.new_transaction();
|
||||
let txn = new_txn?;
|
||||
let get_reader = e.get_reader();
|
||||
let reader: ReadonlyTransaction = get_reader?;
|
||||
let db_reader: Database = reader.bind(h);
|
||||
{
|
||||
// get a database bound to this transaction
|
||||
let db = txn.bind(&h);
|
||||
db.del(&k).unwrap_or_else(|_| error!("failed to delete"));
|
||||
}
|
||||
match txn.commit() {
|
||||
Err(_) => error!("failed to commit!"),
|
||||
Ok(_) => (),
|
||||
let db = txn.bind(h);
|
||||
|
||||
for num_writes in 0..usize::MAX {
|
||||
let mut new_key: Vec<u8> = k.to_vec();
|
||||
let mut key_count: Vec<u8> = num_writes.to_be_bytes().to_vec();
|
||||
new_key.append(&mut key_count);
|
||||
let r = db_reader.get::<Vec<u8>>(&new_key).unwrap_or_default();
|
||||
if r.is_empty() {
|
||||
break;
|
||||
}
|
||||
db.del(&new_key)
|
||||
.unwrap_or_else(|_| error!("failed to delete"));
|
||||
}
|
||||
}
|
||||
txn.commit()
|
||||
}
|
||||
pub async fn async_delete(e: &Environment, h: &DbHandle, k: &str) {
|
||||
info!("excecuting lmdb async delete");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::delete(e, h, k)
|
||||
}
|
||||
|
||||
/// Write chunks to the database. This function uses one percent
|
||||
///
|
||||
/// of the map size . Setting the map_size to a low value
|
||||
///
|
||||
/// will cause degraded performance.
|
||||
pub fn write_chunks(e: &Environment, h: &DbHandle, k: &[u8], v: &[u8]) -> Result<(), MdbError> {
|
||||
let s = System::new_all();
|
||||
let chunk_size = (s.available_memory() as f32 * CHUNK_SIZE_MEMORY_RATIO) as usize;
|
||||
let mut writes: usize = 1;
|
||||
let mut index: usize = 0;
|
||||
let length = v.len();
|
||||
loop {
|
||||
let mut old_key: Vec<u8> = k.to_vec();
|
||||
let mut append: Vec<u8> = (writes - 1).to_be_bytes().to_vec();
|
||||
old_key.append(&mut append);
|
||||
if length > chunk_size && (length - index > chunk_size) {
|
||||
// write chunks until the last value which is smaller than chunk_size
|
||||
let _ = DatabaseEnvironment::write(
|
||||
e,
|
||||
h,
|
||||
&old_key,
|
||||
&v[index..(chunk_size * writes)].to_vec(),
|
||||
);
|
||||
index += chunk_size;
|
||||
writes += 1;
|
||||
} else {
|
||||
DatabaseEnvironment::write(e, h, &old_key, &v[index..length].to_vec())?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn async_write_and_read_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
tokio::spawn(async move {
|
||||
let s = Interface::async_open().await;
|
||||
let k = "async-test-key";
|
||||
let v = "async-test-value";
|
||||
Interface::async_write(&s.env, &s.handle, k, v).await;
|
||||
let expected = String::from(v);
|
||||
let actual = Interface::async_read(&s.env, &s.handle, k).await;
|
||||
assert_eq!(expected, actual);
|
||||
Interface::async_delete(&s.env, &s.handle, &k).await;
|
||||
});
|
||||
}
|
||||
use rand::RngCore;
|
||||
|
||||
#[test]
|
||||
fn async_write_and_delete_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
tokio::spawn(async move {
|
||||
let s = Interface::open();
|
||||
let k = "write_and_delete_test_test-key";
|
||||
let v = "write_and_delete_test_test-value";
|
||||
Interface::async_write(&s.env, &s.handle, k, v).await;
|
||||
let expected = utils::empty_string();
|
||||
Interface::async_delete(&s.env, &s.handle, &k).await;
|
||||
let actual = Interface::async_read(&s.env, &s.handle, k).await;
|
||||
assert_eq!(expected, actual);
|
||||
});
|
||||
fn environment_test() -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
const DATA_SIZE_10MB: usize = 10000000;
|
||||
let mut data = vec![0u8; DATA_SIZE_10MB];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let k = "test-key".as_bytes();
|
||||
let expected = &data.to_vec();
|
||||
write_chunks(&db.env, &db.handle, &Vec::from(k), &Vec::from(data))?;
|
||||
let actual = DatabaseEnvironment::read(&db.env, &db.handle, &Vec::from(k));
|
||||
assert_eq!(expected.to_vec(), actual?);
|
||||
let _ = DatabaseEnvironment::delete(&db.env, &db.handle, &Vec::from(k))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
use std::error::Error;
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
models::*,
|
||||
monero,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -16,7 +21,7 @@ use log::{
|
|||
use rocket::serde::json::Json;
|
||||
|
||||
/// Create a new dispute
|
||||
pub fn create(d: Json<Dispute>) -> Dispute {
|
||||
pub fn create(d: Json<Dispute>) -> Result<Dispute, MdbError> {
|
||||
let f_did: String = format!("{}{}", crate::DISPUTE_DB_KEY, utils::generate_rnd());
|
||||
info!("create dispute: {}", &f_did);
|
||||
let new_dispute = Dispute {
|
||||
|
@ -26,70 +31,78 @@ pub fn create(d: Json<Dispute>) -> Dispute {
|
|||
tx_set: String::from(&d.tx_set),
|
||||
};
|
||||
debug!("insert dispute: {:?}", &d);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &d.did;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Dispute::to_db(&new_dispute));
|
||||
let v = bincode::serialize(&new_dispute).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)?;
|
||||
// in order to retrieve all orders, write keys to with dl
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
debug!("creating dispute index");
|
||||
}
|
||||
let dispute_list = [String::from(&r), String::from(&f_did)].join(",");
|
||||
let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let dispute_list = [String::from(&s_r), String::from(&f_did)].join(",");
|
||||
let s_dispute_list = bincode::serialize(&dispute_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing dispute index {} for id: {}",
|
||||
dispute_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_dispute_list)?;
|
||||
// restart the dispute aut-settle thread
|
||||
let cleared = is_dispute_clear(r);
|
||||
let cleared = is_dispute_clear(s_r);
|
||||
if !cleared {
|
||||
debug!("restarting dispute auto-settle");
|
||||
utils::restart_dispute_auto_settle();
|
||||
}
|
||||
new_dispute
|
||||
Ok(new_dispute)
|
||||
}
|
||||
|
||||
/// Dispute lookup
|
||||
pub fn find(did: &String) -> Dispute {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(did));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(did: &String) -> Result<Dispute, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &did.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("dispute not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::Panic));
|
||||
}
|
||||
Dispute::from_db(String::from(did), r)
|
||||
let result: Dispute = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Lookup all disputes
|
||||
pub fn find_all() -> Vec<Dispute> {
|
||||
let d_s = db::Interface::open();
|
||||
pub fn find_all() -> Result<Vec<Dispute>, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let d_list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let d_r = db::Interface::read(&d_s.env, &d_s.handle, &String::from(d_list_key));
|
||||
if d_r == utils::empty_string() {
|
||||
let d_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &d_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if d_r.is_empty() {
|
||||
error!("dispute index not found");
|
||||
}
|
||||
let d_v_did = d_r.split(",");
|
||||
let d_v: Vec<String> = d_v_did.map(|s| String::from(s)).collect();
|
||||
let str_r: String = bincode::deserialize(&d_r[..]).unwrap_or_default();
|
||||
let d_v_did = str_r.split(",");
|
||||
let d_v: Vec<String> = d_v_did.map(String::from).collect();
|
||||
let mut disputes: Vec<Dispute> = Vec::new();
|
||||
for o in d_v {
|
||||
let dispute: Dispute = find(&o);
|
||||
if dispute.did != utils::empty_string() {
|
||||
let dispute: Dispute = find(&o)?;
|
||||
if !dispute.did.is_empty() {
|
||||
disputes.push(dispute);
|
||||
}
|
||||
}
|
||||
disputes
|
||||
Ok(disputes)
|
||||
}
|
||||
|
||||
/// Dispute deletion
|
||||
pub fn delete(did: &String) {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(did));
|
||||
if r == utils::empty_string() {
|
||||
pub fn delete(did: &String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &did.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("dispute not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
db::Interface::delete(&s.env, &s.handle, &String::from(did))
|
||||
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, did.as_bytes())
|
||||
}
|
||||
|
||||
/// Triggered on DISPUTE_LAST_CHECK_DB_KEY.
|
||||
|
@ -99,46 +112,50 @@ pub fn delete(did: &String) {
|
|||
/// creation date of the dispute plus the one week
|
||||
///
|
||||
/// grace period then the dispute is auto-settled.
|
||||
pub async fn settle_dispute() {
|
||||
pub async fn settle_dispute() -> Result<(), NevekoError> {
|
||||
let tick: std::sync::mpsc::Receiver<()> =
|
||||
schedule_recv::periodic_ms(crate::DISPUTE_CHECK_INTERVAL);
|
||||
loop {
|
||||
debug!("running dispute auto-settle thread");
|
||||
tick.recv().unwrap();
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
info!("dispute index not found");
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let v_mid = r.split(",");
|
||||
let d_vec: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_mid = str_r.split(",");
|
||||
let d_vec: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("dispute contents: {:#?}", d_vec);
|
||||
let cleared = is_dispute_clear(r);
|
||||
let cleared = is_dispute_clear(str_r);
|
||||
if cleared {
|
||||
// index was created but cleared
|
||||
info!("terminating dispute auto-settle thread");
|
||||
db::Interface::delete(&s.env, &s.handle, list_key);
|
||||
return;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, list_key.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
return Ok(());
|
||||
}
|
||||
for d in d_vec {
|
||||
let dispute: Dispute = find(&d);
|
||||
if dispute.did != utils::empty_string() {
|
||||
let dispute: Dispute = find(&d)?;
|
||||
if !dispute.did.is_empty() {
|
||||
let now = chrono::offset::Utc::now().timestamp();
|
||||
let settle_date = dispute.created + crate::DISPUTE_AUTO_SETTLE as i64;
|
||||
if settle_date > now {
|
||||
let wallet_name = String::from(dispute.orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_name = dispute.orid;
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let signed = monero::sign_multisig(dispute.tx_set).await;
|
||||
let submit = monero::submit_multisig(signed.result.tx_data_hex).await;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
if submit.result.tx_hash_list.is_empty() {
|
||||
error!("could not broadcast txset for dispute: {}", &dispute.did);
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
// remove the dispute from the db
|
||||
remove_from_auto_settle(dispute.did);
|
||||
remove_from_auto_settle(dispute.did).map(|_| NevekoError::Dispute)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,43 +164,46 @@ pub async fn settle_dispute() {
|
|||
|
||||
fn is_dispute_clear(r: String) -> bool {
|
||||
let v_mid = r.split(",");
|
||||
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("dispute index contents: {:#?}", v);
|
||||
let limit = v.len() <= 1;
|
||||
if !limit {
|
||||
return v.len() >= 2
|
||||
&& v[v.len() - 1] == utils::empty_string()
|
||||
&& v[0] == utils::empty_string();
|
||||
v.len() >= 2 && v[v.len() - 1].is_empty() && v[0].is_empty()
|
||||
} else {
|
||||
return limit;
|
||||
limit
|
||||
}
|
||||
}
|
||||
|
||||
/// clear dispute from index
|
||||
fn remove_from_auto_settle(did: String) {
|
||||
fn remove_from_auto_settle(did: String) -> Result<(), NevekoError> {
|
||||
info!("removing id {} from disputes", &did);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("dispute list index is empty");
|
||||
}
|
||||
let pre_v_fts = r.split(",");
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let pre_v_fts = str_r.split(",");
|
||||
let v: Vec<String> = pre_v_fts
|
||||
.map(|s| {
|
||||
if s != &did {
|
||||
String::from(s)
|
||||
} else {
|
||||
utils::empty_string()
|
||||
String::new()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let dispute_list = v.join(",");
|
||||
let s_dispute_list = bincode::serialize(&dispute_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing dipsute index {} for id: {}",
|
||||
dispute_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_dispute_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Executes POST /market/dispute/create
|
||||
|
@ -227,16 +247,21 @@ async fn transmit_dispute_request(
|
|||
/// A decomposition trigger for the dispute request so that the logic
|
||||
///
|
||||
/// can be executed from the gui.
|
||||
pub async fn trigger_dispute_request(contact: &String, dispute: &Dispute) -> Dispute {
|
||||
pub async fn trigger_dispute_request(
|
||||
contact: &String,
|
||||
dispute: &Dispute,
|
||||
) -> Result<Dispute, NevekoError> {
|
||||
info!("executing trigger_dispute_request");
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let dispute = transmit_dispute_request(contact, &jwp, dispute).await;
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let dispute = transmit_dispute_request(contact, &str_jwp, dispute).await;
|
||||
// handle a failure to create dispute
|
||||
if dispute.is_err() {
|
||||
error!("failed to create dispute");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Dispute);
|
||||
}
|
||||
dispute.unwrap_or(Default::default())
|
||||
Ok(dispute.map_err(|_| NevekoError::Dispute)?)
|
||||
}
|
||||
|
|
21
neveko-core/src/error.rs
Normal file
21
neveko-core/src/error.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use kn0sys_lmdb_rs::MdbError;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Use for mapping errors in functions that can throw multiple errors.
|
||||
#[derive(Debug, Error)]
|
||||
#[error("Neveko error. See logs for more info.")]
|
||||
pub enum NevekoError {
|
||||
Auth,
|
||||
Contact,
|
||||
Database(MdbError),
|
||||
Dispute,
|
||||
I2P,
|
||||
J4I2PRS,
|
||||
Message,
|
||||
MoneroRpc,
|
||||
MoneroDaemon,
|
||||
Nasr,
|
||||
Order,
|
||||
Product,
|
||||
Unknown,
|
||||
}
|
|
@ -1,32 +1,73 @@
|
|||
//! TODO: replace i2p-zero with i2pd bindings
|
||||
//! embedded i2p module
|
||||
|
||||
use crate::{
|
||||
args,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
monero::get_anon_inbound_port,
|
||||
utils,
|
||||
DEFAULT_HTTP_PROXY_PORT,
|
||||
DEFAULT_SOCKS_PORT,
|
||||
};
|
||||
use clap::Parser;
|
||||
use log::{
|
||||
debug,
|
||||
info,
|
||||
warn,
|
||||
use j4i2prs::{
|
||||
router_wrapper as rw,
|
||||
tunnel_control as tc,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::*;
|
||||
use serde::{
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
use std::{
|
||||
env,
|
||||
fs,
|
||||
process::Command,
|
||||
time::Duration,
|
||||
fs::File,
|
||||
io::{
|
||||
self,
|
||||
BufRead,
|
||||
},
|
||||
path::Path,
|
||||
sync::mpsc::{
|
||||
Receiver,
|
||||
Sender,
|
||||
},
|
||||
thread,
|
||||
};
|
||||
|
||||
struct Listener {
|
||||
is_running: bool,
|
||||
run_tx: Sender<bool>,
|
||||
run_rx: Receiver<bool>,
|
||||
}
|
||||
|
||||
impl Default for Listener {
|
||||
fn default() -> Self {
|
||||
let is_running = false;
|
||||
let (run_tx, run_rx) = std::sync::mpsc::channel();
|
||||
Listener {
|
||||
is_running,
|
||||
run_tx,
|
||||
run_rx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// https://doc.rust-lang.org/rust-by-example/std_misc/file/read_lines.html
|
||||
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(filename)?;
|
||||
Ok(io::BufReader::new(file).lines())
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct HttpProxyStatus {
|
||||
pub open: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq)]
|
||||
pub enum ProxyStatus {
|
||||
Opening,
|
||||
Open,
|
||||
|
@ -41,226 +82,220 @@ impl ProxyStatus {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Tunnel {
|
||||
// http proxy tunnel wont have this field
|
||||
dest: Option<String>,
|
||||
port: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Tunnels {
|
||||
tunnels: Vec<Tunnel>,
|
||||
}
|
||||
|
||||
impl Default for Tunnels {
|
||||
fn default() -> Self {
|
||||
Tunnels {
|
||||
tunnels: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Looks for the `tunnels-config.json` at /home/$USER/.i2p-zero/config/
|
||||
///
|
||||
/// and attempts to extract the app and http proxy tunnel information.
|
||||
async fn find_tunnels() {
|
||||
let args = args::Args::parse();
|
||||
let app_port = utils::get_app_port();
|
||||
let file_path = format!(
|
||||
"/home/{}/.i2p-zero/config/tunnels.json",
|
||||
env::var("USER").unwrap_or(String::from("user"))
|
||||
);
|
||||
let contents = fs::read_to_string(file_path).unwrap_or(utils::empty_string());
|
||||
debug!("i2p tunnels: {}", contents);
|
||||
let has_app_tunnel = contents.contains(&format!("{}", app_port));
|
||||
let proxy_port = get_i2p_proxy_port();
|
||||
let socks_proxy_port = get_i2p_socks_proxy_port();
|
||||
let has_http_tunnel = contents.contains(&proxy_port);
|
||||
let has_socks_proxy_tunnel = contents.contains(&format!("{}", &socks_proxy_port));
|
||||
let has_anon_inbound_tunnel = contents.contains(&format!("{}", args.anon_inbound_port));
|
||||
if !has_app_tunnel || !has_http_tunnel || !has_anon_inbound_tunnel || !has_socks_proxy_tunnel {
|
||||
tokio::time::sleep(Duration::new(120, 0)).await;
|
||||
}
|
||||
if !has_app_tunnel {
|
||||
debug!("creating app tunnel");
|
||||
create_tunnel();
|
||||
}
|
||||
if !has_http_tunnel {
|
||||
debug!("creating http tunnel");
|
||||
create_http_proxy();
|
||||
}
|
||||
if !has_anon_inbound_tunnel {
|
||||
debug!("creating anon inbound tunnel");
|
||||
create_anon_inbound_tunnel();
|
||||
}
|
||||
if !has_socks_proxy_tunnel {
|
||||
debug!("creating socks proxy tunnel");
|
||||
create_socks_proxy_tunnel();
|
||||
}
|
||||
}
|
||||
|
||||
/// Called on application startup for i2p tunnel creation,
|
||||
///
|
||||
/// proxy tunnel, etc. Logs proxy status every 10 minutes.
|
||||
pub async fn start() {
|
||||
info!("starting i2p-zero");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let output = Command::new(format!("{}/router/bin/i2p-zero", path)).spawn();
|
||||
match output {
|
||||
Ok(child) => debug!("{:?}", child.stdout),
|
||||
_ => {
|
||||
warn!("i2p-zero not installed, manual tunnel creation required");
|
||||
()
|
||||
}
|
||||
}
|
||||
find_tunnels().await;
|
||||
{
|
||||
tokio::spawn(async move {
|
||||
let tick: std::sync::mpsc::Receiver<()> =
|
||||
schedule_recv::periodic_ms(crate::I2P_CONNECTIVITY_CHECK_INTERVAL);
|
||||
loop {
|
||||
tick.recv().unwrap();
|
||||
check_connection().await;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an i2p tunnel for the NEVEKO application
|
||||
fn create_tunnel() {
|
||||
info!("creating tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args([
|
||||
"server.create",
|
||||
"127.0.0.1",
|
||||
&format!("{}", utils::get_app_port()),
|
||||
])
|
||||
.spawn()
|
||||
.expect("i2p-zero failed to create a app tunnel");
|
||||
debug!("{:?}", output.stdout);
|
||||
}
|
||||
|
||||
/// Create an i2p tunnel for the monero wallet socks proxy
|
||||
fn create_socks_proxy_tunnel() {
|
||||
info!("creating monerod socks proxy tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args(["socks.create", &format!("{}", get_i2p_socks_proxy_port())])
|
||||
.spawn()
|
||||
.expect("i2p-zero failed to create a socks proxy tunnel");
|
||||
debug!("{:?}", output.stdout);
|
||||
}
|
||||
|
||||
/// Create an i2p tunnel for the monero tx proxy
|
||||
fn create_anon_inbound_tunnel() {
|
||||
info!("creating monerod anon inbound proxy tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args([
|
||||
"server.create",
|
||||
"127.0.0.1",
|
||||
&format!("{}", args.anon_inbound_port),
|
||||
])
|
||||
.spawn()
|
||||
.expect("i2p-zero failed to create a anon inbound tunnel");
|
||||
debug!("{:?}", output.stdout);
|
||||
}
|
||||
|
||||
/// Extract i2p port from command line arg
|
||||
fn get_i2p_proxy_port() -> String {
|
||||
let proxy_host = utils::get_i2p_http_proxy();
|
||||
let values = proxy_host.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let port = v.remove(2);
|
||||
port
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
v.remove(2)
|
||||
}
|
||||
|
||||
/// Extract i2p socks port from command line arg
|
||||
fn get_i2p_socks_proxy_port() -> String {
|
||||
let proxy_host = utils::get_i2p_wallet_proxy_host();
|
||||
let values = proxy_host.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let port = v.remove(2);
|
||||
port
|
||||
}
|
||||
|
||||
/// Create the http proxy if it doesn't exist
|
||||
fn create_http_proxy() {
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
info!("creating http proxy");
|
||||
let port = get_i2p_proxy_port();
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args(["http.create", &port])
|
||||
.spawn()
|
||||
.expect("i2p-zero failed to create a http proxy");
|
||||
debug!("{:?}", output.stdout);
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
v.remove(2)
|
||||
}
|
||||
|
||||
/// This is the `dest` value of the app i2p tunnels
|
||||
///
|
||||
/// in `tunnels-config.json`.
|
||||
///
|
||||
/// `port` - the port of the tunnel (e.g. `utils::get_app_port()`)
|
||||
pub fn get_destination(port: Option<u16>) -> String {
|
||||
let mut file_path = format!(
|
||||
"/home/{}/.i2p-zero/config/tunnels.json",
|
||||
env::var("USER").unwrap_or(String::from("user"))
|
||||
);
|
||||
let args = args::Args::parse();
|
||||
let is_advanced_mode =
|
||||
std::env::var(crate::NEVEKO_I2P_ADVANCED_MODE).unwrap_or(utils::empty_string());
|
||||
if args.i2p_advanced || is_advanced_mode == String::from("1") {
|
||||
let advanced_tunnel =
|
||||
std::env::var(crate::NEVEKO_I2P_TUNNELS_JSON).unwrap_or(utils::empty_string());
|
||||
let manual_tunnel = if advanced_tunnel == utils::empty_string() {
|
||||
args.i2p_tunnels_json
|
||||
} else {
|
||||
advanced_tunnel
|
||||
};
|
||||
file_path = format!("{}/tunnels.json", manual_tunnel);
|
||||
/// `st` - ServerTunnelType (App or AnonInbound)
|
||||
pub fn get_destination(st: ServerTunnelType) -> Result<String, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r_anon_b32_dest = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::APP_ANON_IN_B32_DEST.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r_app_b32_dest = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::APP_B32_DEST.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let anon_b32_dest: String = bincode::deserialize(&r_anon_b32_dest[..]).unwrap_or_default();
|
||||
let app_b32_dest: String = bincode::deserialize(&&r_app_b32_dest[..]).unwrap_or_default();
|
||||
match st {
|
||||
ServerTunnelType::App => Ok(app_b32_dest),
|
||||
ServerTunnelType::AnonInbound => Ok(anon_b32_dest),
|
||||
}
|
||||
// Don't panic if i2p-zero isn't installed
|
||||
let contents = match fs::read_to_string(file_path) {
|
||||
Ok(file) => file,
|
||||
_ => utils::empty_string(),
|
||||
};
|
||||
if contents != utils::empty_string() {
|
||||
let input = format!(r#"{contents}"#);
|
||||
let j: Tunnels = serde_json::from_str(&input).unwrap_or(Default::default());
|
||||
let mut destination: String = utils::empty_string();
|
||||
let tunnels: Vec<Tunnel> = j.tunnels;
|
||||
for tunnel in tunnels {
|
||||
if tunnel.port == format!("{}", port.unwrap_or(utils::get_app_port())) {
|
||||
destination = tunnel.dest.unwrap_or(utils::empty_string());
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
utils::empty_string()
|
||||
}
|
||||
|
||||
/// Ping the i2p-zero http proxy `tunnel-control http.state <port>`
|
||||
pub async fn check_connection() -> ProxyStatus {
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let port = get_i2p_proxy_port();
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args(["http.state", &port])
|
||||
.output()
|
||||
.expect("check i2p connection failed");
|
||||
let str_status = String::from_utf8(output.stdout).unwrap();
|
||||
if str_status == ProxyStatus::Open.value() {
|
||||
debug!("http proxy is open");
|
||||
ProxyStatus::Open
|
||||
} else {
|
||||
debug!("http proxy is opening");
|
||||
ProxyStatus::Opening
|
||||
/// Ping our base 32 destination address over the http proxy
|
||||
pub async fn check_connection() -> Result<ProxyStatus, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r =
|
||||
db::DatabaseEnvironment::read(&db.env, &db.handle, &crate::I2P_STATUS.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("i2p status not found");
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let result: ProxyStatus = bincode::deserialize(&r[..]).unwrap_or(ProxyStatus::Opening);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum ServerTunnelType {
|
||||
App,
|
||||
AnonInbound,
|
||||
}
|
||||
|
||||
/// Create app and anon inbound server tunnels if they don't exist yet
|
||||
fn create_server_tunnel(st: ServerTunnelType) -> Result<tc::Tunnel, NevekoError> {
|
||||
let port: u16 = if st == ServerTunnelType::App {
|
||||
utils::get_app_port()
|
||||
} else {
|
||||
get_anon_inbound_port()
|
||||
};
|
||||
let b32_key = if st == ServerTunnelType::App {
|
||||
crate::APP_B32_DEST.as_bytes()
|
||||
} else {
|
||||
crate::APP_ANON_IN_B32_DEST.as_bytes()
|
||||
};
|
||||
let sk_key = if st == ServerTunnelType::App {
|
||||
crate::APP_I2P_SK.as_bytes()
|
||||
} else {
|
||||
crate::APP_ANON_IN_SK.as_bytes()
|
||||
};
|
||||
let db = &DATABASE_LOCK;
|
||||
let tunnel: tc::Tunnel =
|
||||
tc::Tunnel::new("127.0.0.1".to_string(), port, tc::TunnelType::Server).unwrap_or_default();
|
||||
let b32_dest: String = tunnel.get_destination();
|
||||
log::debug!("destination: {}", &b32_dest);
|
||||
let v_b32_dest = bincode::serialize(&b32_dest).unwrap_or_default();
|
||||
let v_sk = bincode::serialize(&tunnel.get_sk()).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, b32_key, &v_b32_dest)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&db.env, &db.handle, sk_key, &v_sk)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(tunnel)
|
||||
}
|
||||
|
||||
/// Start router and automatic i2p tunnel creation
|
||||
///
|
||||
/// We'll check for an existing i2p secret key. If it doesn't
|
||||
///
|
||||
/// exist create a new one.
|
||||
pub fn start() -> Result<(), NevekoError> {
|
||||
let http_proxy_port: u16 = get_i2p_proxy_port()
|
||||
.parse::<u16>()
|
||||
.unwrap_or(DEFAULT_HTTP_PROXY_PORT);
|
||||
let socks_port: u16 = get_i2p_socks_proxy_port()
|
||||
.parse::<u16>()
|
||||
.unwrap_or(DEFAULT_SOCKS_PORT);
|
||||
// check for existing app and anon inbound server tunnels
|
||||
let db = &DATABASE_LOCK;
|
||||
let r_anon_in_sk = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::APP_ANON_IN_SK.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r_app_sk =
|
||||
db::DatabaseEnvironment::read(&db.env, &db.handle, &crate::APP_I2P_SK.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let anon_in_sk: String = bincode::deserialize(&r_anon_in_sk[..]).unwrap_or_default();
|
||||
let app_sk: String = bincode::deserialize(&r_app_sk[..]).unwrap_or_default();
|
||||
log::info!("starting j4i2prs...");
|
||||
let r = rw::Wrapper::create_router().map_err(|_| NevekoError::I2P)?;
|
||||
let mut l: Listener = Default::default();
|
||||
let run_tx = l.run_tx.clone();
|
||||
let _ = thread::spawn(move || {
|
||||
log::info!("run thread started");
|
||||
run_tx
|
||||
.send(true)
|
||||
.unwrap_or_else(|_| log::error!("failed to run router"));
|
||||
});
|
||||
// run the main thread forever unless we get a router shutdown signal
|
||||
let _ = thread::spawn(move || {
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
loop {
|
||||
if let Ok(run) = l.run_rx.try_recv() {
|
||||
if run {
|
||||
log::info!("starting router");
|
||||
r.invoke_router(rw::METHOD_RUN)
|
||||
.unwrap_or_else(|_| log::error!("failed to run router"));
|
||||
}
|
||||
}
|
||||
if !l.is_running {
|
||||
let is_router_on = r.is_running().unwrap_or_default();
|
||||
if !is_router_on {
|
||||
log::info!("router is warming up, please wait...");
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_secs(60));
|
||||
if is_router_on {
|
||||
// check router config
|
||||
if let Ok(lines) = read_lines("./router.config") {
|
||||
for line in lines.map_while(Result::ok) {
|
||||
if line.contains("i2np.udp.port") {
|
||||
let port = line.split("=").collect::<Vec<&str>>()[1];
|
||||
log::info!("router is running on external port = {}", port);
|
||||
log::info!("open this port for better connectivity");
|
||||
log::info!("this port was randomly assigned, keep it private");
|
||||
l.is_running = true;
|
||||
// start the http proxy
|
||||
let http_proxy: tc::Tunnel = tc::Tunnel::new(
|
||||
"127.0.0.1".to_string(),
|
||||
http_proxy_port,
|
||||
tc::TunnelType::Http,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let _ = http_proxy.start(None);
|
||||
// start the socks proxy
|
||||
let socks_proxy: tc::Tunnel = tc::Tunnel::new(
|
||||
"127.0.0.1".to_string(),
|
||||
socks_port,
|
||||
tc::TunnelType::Socks,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let _ = socks_proxy.start(None);
|
||||
log::info!("http proxy on port {}", http_proxy.get_port());
|
||||
log::info!("socks proxy on port {}", socks_proxy.get_port());
|
||||
if app_sk.is_empty() {
|
||||
let t = create_server_tunnel(ServerTunnelType::App)
|
||||
.unwrap_or_default();
|
||||
let _ = t.start(None);
|
||||
} else {
|
||||
let app_tunnel = tc::Tunnel::new(
|
||||
"127.0.0.1".to_string(),
|
||||
utils::get_app_port(),
|
||||
tc::TunnelType::ExistingServer,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let _ = app_tunnel.start(Some(String::from(&app_sk)));
|
||||
}
|
||||
if anon_in_sk.is_empty() {
|
||||
let t = create_server_tunnel(ServerTunnelType::AnonInbound)
|
||||
.unwrap_or_default();
|
||||
let _ = t.start(None);
|
||||
} else {
|
||||
let anon_tunnel = tc::Tunnel::new(
|
||||
"127.0.0.1".to_string(),
|
||||
get_anon_inbound_port(),
|
||||
tc::TunnelType::ExistingServer,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let _ = anon_tunnel.start(Some(String::from(&anon_in_sk)));
|
||||
}
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = bincode::serialize(&ProxyStatus::Open).unwrap_or_default();
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
crate::I2P_STATUS.as_bytes(),
|
||||
&v,
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))
|
||||
.unwrap_or_else(|_| log::error!("failed to write i2p status."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ pub mod contact;
|
|||
pub mod neveko25519;
|
||||
pub mod dispute;
|
||||
pub mod db;
|
||||
pub mod error;
|
||||
pub mod i2p;
|
||||
pub mod message;
|
||||
pub mod models;
|
||||
|
@ -21,6 +22,10 @@ pub const NEVEKO_JWT_SECRET_KEY: &str = "NEVEKO_JWT_SECRET_KEY";
|
|||
pub const NEVEKO_NMPK: &str = "NEVEKO_NMPK";
|
||||
|
||||
// LMDB Keys
|
||||
pub const APP_B32_DEST: &str = "app-b32";
|
||||
pub const APP_ANON_IN_B32_DEST: &str = "app-anon-in-b32";
|
||||
pub const APP_I2P_SK: &str = "app-i2p-sk";
|
||||
pub const APP_ANON_IN_SK: &str = "app-anon-in-sk";
|
||||
pub const AUTH_DB_KEY: &str = "a";
|
||||
pub const CONTACT_DB_KEY: &str = "c";
|
||||
pub const DISPUTE_DB_KEY: &str = "d";
|
||||
|
@ -37,7 +42,7 @@ pub const RX_MESSAGE_DB_KEY: &str = "rx";
|
|||
pub const DISPUTE_LAST_CHECK_DB_KEY: &str = "dlc";
|
||||
pub const FTS_DB_KEY: &str = "fts";
|
||||
pub const CUSTOMER_ORDER_LIST_DB_KEY: &str = "olc";
|
||||
pub const ADJUDICATOR_DB_KEY: &str = "med8";
|
||||
pub const ADJUDICATOR_DB_KEY: &str = "med8";
|
||||
pub const MSIG_MESSAGE_DB_KEY: &str = "msig";
|
||||
pub const MSIG_MESSAGE_LIST_DB_KEY: &str = "msigl";
|
||||
pub const FTS_JWP_DB_KEY: &str = "fts-jwp";
|
||||
|
@ -48,8 +53,6 @@ pub const DELIVERY_INFO_DB_KEY: &str = "delivery";
|
|||
pub const MONERO_WALLET_PASSWORD: &str = "MONERO_WALLET_PASSWORD";
|
||||
/// Environment variable for I2P proxy host
|
||||
pub const NEVEKO_I2P_PROXY_HOST: &str = "NEVEKO_I2P_PROXY_HOST";
|
||||
/// Environment variable for I2P manual tunnels.json
|
||||
pub const NEVEKO_I2P_TUNNELS_JSON: &str = "NEVEKO_I2P_TUNNELS_JSON";
|
||||
/// Environment variable for I2P advanced mode
|
||||
pub const NEVEKO_I2P_ADVANCED_MODE: &str = "NEVEKO_I2P_ADVANCED_MODE";
|
||||
/// Environment variable for I2P advanced mode
|
||||
|
@ -59,21 +62,15 @@ pub const MONERO_WALLET_RPC_HOST: &str = "MONERO_WALLET_RPC_HOST";
|
|||
/// Reference to check if gui set remote node flag
|
||||
pub const GUI_REMOTE_NODE: &str = "GUI_REMOTE_NODE";
|
||||
pub const GUI_SET_REMOTE_NODE: &str = "1";
|
||||
|
||||
/// The latest monero release download
|
||||
pub const MONERO_RELEASE_VERSION: &str = "monero-linux-x64-v0.18.3.2.tar.bz2";
|
||||
pub const MONERO_RELEASE_HASH: &str =
|
||||
"9dafd70230a7b3a73101b624f3b5f439cc5b84a19b12c17c24e6aab94b678cbb";
|
||||
/// The latest i2p-zero release version
|
||||
pub const I2P_ZERO_RELEASE_VERSION: &str = "v1.21";
|
||||
pub const I2P_ZERO_RELEASH_HASH: &str =
|
||||
"14f34052ad6abb0c24b048816b0ea86b696ae350dd139dd1e90a67ca88e1d07a";
|
||||
|
||||
pub const LMDB_MAPSIZE: u64 = 1 * 1024 * 1024 * 1024;
|
||||
pub const I2P_CONNECTIVITY_CHECK_INTERVAL: u32 = 600000;
|
||||
pub const FTS_RETRY_INTERVAL: u32 = 60000;
|
||||
/// There is a one week grace period for manual intervention of disputes
|
||||
pub const DISPUTE_AUTO_SETTLE: u32 = 1000 * 60 * 60 * 24 * 7;
|
||||
/// Daily dispute auto-settle check interval
|
||||
pub const DISPUTE_CHECK_INTERVAL: u32 = 1000 * 60 * 60 * 24;
|
||||
/// Default app port
|
||||
pub const DEFAULT_HTTP_PROXY_PORT: u16 = 4455;
|
||||
/// Default app port
|
||||
pub const DEFAULT_SOCKS_PORT: u16 = 9051;
|
||||
/// I2P CONNECTION CHECK
|
||||
pub const I2P_STATUS: &str = "I2P_STATUS";
|
||||
// DO NOT EDIT BELOW THIS LINE
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
use crate::{
|
||||
contact,
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
i2p,
|
||||
models::*,
|
||||
monero,
|
||||
|
@ -11,6 +15,7 @@ use crate::{
|
|||
reqres,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -36,24 +41,19 @@ pub enum MessageType {
|
|||
Multisig,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MultisigMessageData {
|
||||
info: String,
|
||||
sub_type: String,
|
||||
orid: String,
|
||||
}
|
||||
|
||||
impl Default for MultisigMessageData {
|
||||
fn default() -> Self {
|
||||
MultisigMessageData {
|
||||
info: utils::empty_string(),
|
||||
sub_type: utils::empty_string(),
|
||||
orid: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new message
|
||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||
pub async fn create(
|
||||
m: Json<Message>,
|
||||
jwp: String,
|
||||
m_type: MessageType,
|
||||
) -> Result<Message, NevekoError> {
|
||||
let rnd = utils::generate_rnd();
|
||||
let mut f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, &rnd);
|
||||
if m_type == MessageType::Multisig {
|
||||
|
@ -61,50 +61,60 @@ pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Messa
|
|||
}
|
||||
info!("creating message: {}", &f_mid);
|
||||
let created = chrono::offset::Utc::now().timestamp();
|
||||
// get contact public gpg key and encipher the message
|
||||
// get contact public message key and encipher the message
|
||||
debug!("sending message: {:?}", &m);
|
||||
let contact: Contact = contact::find(&m.to);
|
||||
let contact: Contact = contact::find(&m.to).map_err(|_| NevekoError::Message)?;
|
||||
let hex_nmpk: String = contact.nmpk;
|
||||
let encipher = Some(String::from(neveko25519::ENCIPHER));
|
||||
let e_body = neveko25519::cipher(&hex_nmpk, String::from(&m.body), encipher).await;
|
||||
let new_message = Message {
|
||||
mid: String::from(&f_mid),
|
||||
uid: String::from(&m.uid),
|
||||
from: i2p::get_destination(None),
|
||||
from: i2p::get_destination(i2p::ServerTunnelType::App)?,
|
||||
body: e_body,
|
||||
created,
|
||||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert message: {:?}", &new_message);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_message.mid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all message, write keys to with ml
|
||||
let list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let d_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [d_r, String::from(&f_mid)].join(",");
|
||||
let s_msg_list = bincode::serialize(&msg_list).unwrap_or_default();
|
||||
debug!("writing message index {} for id: {}", msg_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
let db = &DATABASE_LOCK;
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_msg_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
info!("attempting to send message");
|
||||
let send = send_message(&new_message, &jwp, m_type).await;
|
||||
send.unwrap();
|
||||
new_message
|
||||
Ok(new_message)
|
||||
}
|
||||
|
||||
/// Rx message
|
||||
pub async fn rx(m: Json<Message>) {
|
||||
pub async fn rx(m: Json<Message>) -> Result<(), NevekoError> {
|
||||
info!("rx from: {}", &m.from);
|
||||
// make sure the message isn't something strange
|
||||
let is_valid = validate_message(&m);
|
||||
if !is_valid {
|
||||
return;
|
||||
error!("invalid contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
// don't allow messages from outside the contact list
|
||||
let is_in_contact_list = contact::exists(&m.from);
|
||||
let is_in_contact_list = contact::exists(&m.from).map_err(|_| NevekoError::Contact)?;
|
||||
if !is_in_contact_list {
|
||||
return;
|
||||
error!("not a mutual contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
let f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, utils::generate_rnd());
|
||||
let new_message = Message {
|
||||
|
@ -116,30 +126,37 @@ pub async fn rx(m: Json<Message>) {
|
|||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert message: {:?}", &new_message);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_message.mid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all message, write keys to with rx
|
||||
let list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [old, String::from(&f_mid)].join(",");
|
||||
let s_msg_list = bincode::serialize(&msg_list).unwrap_or_default();
|
||||
debug!("writing message index {} for {}", msg_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_msg_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parse the multisig message type and info
|
||||
async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
||||
let d: reqres::DecipheredMessageBody = decipher_body(mid).await;
|
||||
let mut bytes = hex::decode(d.body.into_bytes()).unwrap_or(Vec::new());
|
||||
let decoded = String::from_utf8(bytes).unwrap_or(utils::empty_string());
|
||||
async fn parse_multisig_message(mid: String) -> Result<MultisigMessageData, NevekoError> {
|
||||
let d: reqres::DecipheredMessageBody = decipher_body(mid).await?;
|
||||
let mut bytes = hex::decode(d.body.into_bytes()).unwrap_or_default();
|
||||
let decoded = String::from_utf8(bytes).unwrap_or(String::new());
|
||||
let values = decoded.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
if v.len() != VALID_MSIG_MSG_LENGTH {
|
||||
error!("invalid msig message length");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Message);
|
||||
}
|
||||
let sub_type: String = v.remove(0);
|
||||
let orid: String = v.remove(0);
|
||||
|
@ -153,11 +170,11 @@ async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
|||
}
|
||||
bytes = Vec::new();
|
||||
debug!("zero decipher bytes: {:?}", bytes);
|
||||
MultisigMessageData {
|
||||
Ok(MultisigMessageData {
|
||||
info,
|
||||
sub_type,
|
||||
orid,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Rx multisig message
|
||||
|
@ -175,21 +192,24 @@ async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
|||
///
|
||||
/// ```rust
|
||||
/// // lookup prepare info for vendor
|
||||
/// use neveko_core::db;
|
||||
/// let s = db::Interface::open();
|
||||
/// use neveko_core::db::*;
|
||||
/// let db = &DATABASE_LOCK;
|
||||
/// let key = "prepare-o123-test.b32.i2p";
|
||||
/// let info_str = db::Interface::read(&s.env, &s.handle, &key);
|
||||
/// let info_str = DatabaseEnvironment::read(&db.env, &db.handle, &key.as_bytes().to_vec());
|
||||
/// ```
|
||||
pub async fn rx_multisig(m: Json<Message>) {
|
||||
pub async fn rx_multisig(m: Json<Message>) -> Result<(), NevekoError> {
|
||||
info!("rx multisig from: {}", &m.from);
|
||||
// make sure the message isn't something strange
|
||||
let is_valid = validate_message(&m);
|
||||
if !is_valid {
|
||||
return;
|
||||
error!("invalid contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
// don't allow messages from outside the contact list
|
||||
let is_in_contact_list = contact::exists(&m.from);
|
||||
let is_in_contact_list = contact::exists(&m.from).map_err(|_| NevekoError::Contact)?;
|
||||
if !is_in_contact_list {
|
||||
return;
|
||||
error!("not a mutual contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
let f_mid: String = format!("msig{}", utils::generate_rnd());
|
||||
let new_message = Message {
|
||||
|
@ -200,76 +220,103 @@ pub async fn rx_multisig(m: Json<Message>) {
|
|||
created: chrono::offset::Utc::now().timestamp(),
|
||||
to: String::from(&m.to),
|
||||
};
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_message.mid;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await;
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all msig messages, write keys to with msigl
|
||||
let list_key = crate::MSIG_MESSAGE_LIST_DB_KEY;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r == utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating msig message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [old, String::from(&f_mid)].join(",");
|
||||
let s_msg_list = bincode::serialize(&msg_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing msig message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::async_write(&s.env, &s.handle, &String::from(list_key), &msg_list).await;
|
||||
let data: MultisigMessageData = parse_multisig_message(new_message.mid).await;
|
||||
let db = &DATABASE_LOCK;
|
||||
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_msg_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let data: MultisigMessageData = parse_multisig_message(new_message.mid).await?;
|
||||
debug!(
|
||||
"writing multisig message type {} for order {}",
|
||||
&data.sub_type, &data.orid
|
||||
);
|
||||
// lookup msig message data by {type}-{order id}-{contact .b32.i2p address}
|
||||
// store info as {a_info}:{a_info (optional)}
|
||||
let s_msig = db::Interface::async_open().await;
|
||||
let s_msig =
|
||||
db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from);
|
||||
db::Interface::async_write(&s_msig.env, &s_msig.handle, &msig_key, &data.info).await;
|
||||
let db = &DATABASE_LOCK;
|
||||
|
||||
db::write_chunks(
|
||||
&s_msig.env,
|
||||
&db.handle,
|
||||
msig_key.as_bytes(),
|
||||
data.info.as_bytes(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find(mid: &String) -> Message {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(mid));
|
||||
if r == utils::empty_string() {
|
||||
/// Message lookup()
|
||||
pub fn find(mid: &String) -> Result<Message, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &mid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("message not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Message);
|
||||
}
|
||||
Message::from_db(String::from(mid), r)
|
||||
let result: Message = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find_all() -> Vec<Message> {
|
||||
let i_s = db::Interface::open();
|
||||
pub fn find_all() -> Result<Vec<Message>, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
let i_r: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_mid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_mid.map(|s| String::from(s)).collect();
|
||||
let i_v: Vec<String> = i_v_mid.map(String::from).collect();
|
||||
let mut messages: Vec<Message> = Vec::new();
|
||||
for m in i_v {
|
||||
let message: Message = find(&m);
|
||||
if message.mid != utils::empty_string() {
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
let o_list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let o_s = db::Interface::open();
|
||||
let o_r = db::Interface::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
||||
if o_r == utils::empty_string() {
|
||||
let o_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &o_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if o_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
let o_r: String = bincode::deserialize(&o_r[..]).unwrap_or_default();
|
||||
let o_v_mid = o_r.split(",");
|
||||
let o_v: Vec<String> = o_v_mid.map(|s| String::from(s)).collect();
|
||||
let o_v: Vec<String> = o_v_mid.map(String::from).collect();
|
||||
for m in o_v {
|
||||
let message: Message = find(&m);
|
||||
if message.mid != utils::empty_string() {
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
messages
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
/// Tx message
|
||||
|
@ -286,7 +333,7 @@ async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(
|
|||
.await
|
||||
.unwrap_or(false);
|
||||
if is_online {
|
||||
return match client?
|
||||
match client?
|
||||
.post(url)
|
||||
.header("proof", jwp)
|
||||
.json(&out)
|
||||
|
@ -297,8 +344,8 @@ async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(
|
|||
let status = response.status();
|
||||
debug!("send response: {:?}", status.as_str());
|
||||
if status == StatusCode::OK || status == StatusCode::PAYMENT_REQUIRED {
|
||||
remove_from_fts(String::from(&out.mid));
|
||||
return Ok(());
|
||||
remove_from_fts(String::from(&out.mid))?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -307,27 +354,29 @@ async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(
|
|||
error!("failed to send message due to: {:?}", e);
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
send_to_retry(String::from(&out.mid)).await;
|
||||
send_to_retry(String::from(&out.mid)).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns deciphered message
|
||||
pub async fn decipher_body(mid: String) -> reqres::DecipheredMessageBody {
|
||||
let m = find(&mid);
|
||||
let contact = contact::find_by_i2p_address(&m.from);
|
||||
pub async fn decipher_body(mid: String) -> Result<reqres::DecipheredMessageBody, NevekoError> {
|
||||
let m = find(&mid)?;
|
||||
let contact = contact::find_by_i2p_address(&m.from)?;
|
||||
let nmpk = contact.nmpk;
|
||||
let message = String::from(&m.body);
|
||||
let body = neveko25519::cipher(&nmpk, message, None).await;
|
||||
reqres::DecipheredMessageBody { mid, body }
|
||||
Ok(reqres::DecipheredMessageBody { mid, body })
|
||||
}
|
||||
|
||||
/// Message deletion
|
||||
pub fn delete(mid: &String) {
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &String::from(mid));
|
||||
pub fn delete(mid: &String) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, mid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ping the contact health check over i2p
|
||||
|
@ -363,63 +412,75 @@ async fn is_contact_online(contact: &String, jwp: String) -> Result<bool, Box<dy
|
|||
}
|
||||
|
||||
/// stage message for async retry
|
||||
async fn send_to_retry(mid: String) {
|
||||
async fn send_to_retry(mid: String) -> Result<(), NevekoError> {
|
||||
info!("sending {} to fts", &mid);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
// in order to retrieve FTS (failed-to-send), write keys to db with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating fts message index");
|
||||
}
|
||||
let mut msg_list = [String::from(&r), String::from(&mid)].join(",");
|
||||
let i_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let mut msg_list = [String::from(&i_r), String::from(&mid)].join(",");
|
||||
let s_msg_list = bincode::serialize(&msg_list).unwrap_or_default();
|
||||
// don't duplicate message ids in fts
|
||||
if String::from(&r).contains(&String::from(&mid)) {
|
||||
msg_list = r;
|
||||
if String::from(&i_r).contains(&String::from(&mid)) {
|
||||
msg_list = i_r;
|
||||
}
|
||||
debug!(
|
||||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_msg_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// restart fts if not empty
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let v_mid = r.split(",");
|
||||
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_mid = str_r.split(",");
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
let cleared = is_fts_clear(r);
|
||||
let cleared = is_fts_clear(str_r);
|
||||
if !cleared {
|
||||
debug!("restarting fts");
|
||||
utils::restart_retry_fts();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// clear fts message from index
|
||||
fn remove_from_fts(mid: String) {
|
||||
fn remove_from_fts(mid: String) -> Result<(), NevekoError> {
|
||||
info!("removing id {} from fts", &mid);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
// in order to retrieve FTS (failed-to-send), write keys to with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("fts is empty");
|
||||
}
|
||||
let pre_v_fts = r.split(",");
|
||||
let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let pre_v_fts = s_r.split(",");
|
||||
let v: Vec<String> = pre_v_fts
|
||||
.map(|s| {
|
||||
if s != &mid {
|
||||
String::from(s)
|
||||
} else {
|
||||
utils::empty_string()
|
||||
String::new()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let msg_list = v.join(",");
|
||||
let s_msg_list = bincode::serialize(&msg_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_msg_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Triggered on app startup, retries to send fts every minute
|
||||
|
@ -427,42 +488,48 @@ fn remove_from_fts(mid: String) {
|
|||
/// FTS thread terminates when empty and gets restarted on the next
|
||||
///
|
||||
/// failed-to-send message.
|
||||
pub async fn retry_fts() {
|
||||
pub async fn retry_fts() -> Result<(), NevekoError> {
|
||||
let tick: std::sync::mpsc::Receiver<()> = schedule_recv::periodic_ms(crate::FTS_RETRY_INTERVAL);
|
||||
loop {
|
||||
debug!("running retry failed-to-send thread");
|
||||
tick.recv().unwrap();
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
info!("fts message index not found");
|
||||
break; // terminate fts if no message to send
|
||||
return Err(NevekoError::Database(MdbError::NotFound)); // terminate fts if no message to send
|
||||
}
|
||||
let v_mid = r.split(",");
|
||||
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||
let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_mid = s_r.split(",");
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
let cleared = is_fts_clear(r);
|
||||
let cleared = is_fts_clear(s_r);
|
||||
if cleared {
|
||||
// index was created but cleared
|
||||
info!("terminating retry fts thread");
|
||||
db::Interface::delete(&s.env, &s.handle, list_key);
|
||||
break;
|
||||
let _ =
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
break Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
for m in v {
|
||||
let message: Message = find(&m);
|
||||
if message.mid != utils::empty_string() {
|
||||
let s = db::Interface::open();
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
// get jwp from db
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &message.to);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
if jwp != utils::empty_string() {
|
||||
let jwp =
|
||||
db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if !jwp.is_empty() {
|
||||
let m_type = if message.mid.contains("msig") {
|
||||
MessageType::Multisig
|
||||
} else {
|
||||
MessageType::Normal
|
||||
};
|
||||
send_message(&message, &jwp, m_type).await.unwrap();
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
send_message(&message, &str_jwp, m_type).await.unwrap();
|
||||
} else {
|
||||
error!("not jwp found for fts id: {}", &message.mid);
|
||||
}
|
||||
|
@ -476,35 +543,34 @@ fn validate_message(j: &Json<Message>) -> bool {
|
|||
info!("validating message: {}", &j.mid);
|
||||
j.mid.len() < utils::string_limit()
|
||||
&& j.body.len() < utils::message_limit()
|
||||
&& j.to == i2p::get_destination(None)
|
||||
&& j.to == i2p::get_destination(i2p::ServerTunnelType::App).unwrap_or_default()
|
||||
&& j.uid.len() < utils::string_limit()
|
||||
}
|
||||
|
||||
fn is_fts_clear(r: String) -> bool {
|
||||
let v_mid = r.split(",");
|
||||
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
let limit = v.len() <= 1;
|
||||
if !limit {
|
||||
return v.len() >= 2
|
||||
&& v[v.len() - 1] == utils::empty_string()
|
||||
&& v[0] == utils::empty_string();
|
||||
v.len() >= 2 && v[v.len() - 1].is_empty() && v[0].is_empty()
|
||||
} else {
|
||||
return limit;
|
||||
limit
|
||||
}
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `prepare_multisig_info` method.
|
||||
pub async fn send_prepare_info(orid: &String, contact: &String) {
|
||||
let s = db::Interface::open();
|
||||
pub async fn send_prepare_info(orid: &String, contact: &String) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let prepare_info = monero::prepare_wallet().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!(
|
||||
"{}:{}:{}",
|
||||
PREPARE_MSIG, orid, &prepare_info.result.multisig_info
|
||||
|
@ -516,21 +582,28 @@ pub async fn send_prepare_info(orid: &String, contact: &String) {
|
|||
..Default::default()
|
||||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `make_multisig_info` method.
|
||||
pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>) {
|
||||
let s = db::Interface::open();
|
||||
pub async fn send_make_info(
|
||||
orid: &String,
|
||||
contact: &String,
|
||||
info: Vec<String>,
|
||||
) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let make_info = monero::make_wallet(info).await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!("{}:{}:{}", MAKE_MSIG, orid, &make_info.result.multisig_info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -539,8 +612,10 @@ pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>)
|
|||
..Default::default()
|
||||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
|
@ -551,14 +626,15 @@ pub async fn send_exchange_info(
|
|||
contact: &String,
|
||||
info: Vec<String>,
|
||||
kex_init: bool,
|
||||
) {
|
||||
let s = db::Interface::open();
|
||||
) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let exchange_info = monero::exchange_multisig_keys(false, info, &wallet_password).await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let mut body_str = format!(
|
||||
"{}:{}:{}",
|
||||
KEX_ONE_MSIG, orid, &exchange_info.result.multisig_info
|
||||
|
@ -576,21 +652,24 @@ pub async fn send_exchange_info(
|
|||
..Default::default()
|
||||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `export_multisig_info` method.
|
||||
pub async fn send_export_info(orid: &String, contact: &String) {
|
||||
let s = db::Interface::open();
|
||||
pub async fn send_export_info(orid: &String, contact: &String) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let exchange_info = monero::export_multisig_info().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!("{}:{}:{}", EXPORT_MSIG, orid, &exchange_info.result.info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -599,8 +678,10 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
|||
..Default::default()
|
||||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The customer or vendor (dispute only) needs to export
|
||||
|
@ -608,22 +689,23 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
|||
/// multisig info after funding. Once the info is imported
|
||||
///
|
||||
/// successfully the order needs to be updated to `MultisigComplete`.
|
||||
pub async fn send_import_info(orid: &String, info: &Vec<String>) {
|
||||
pub async fn send_import_info(orid: &String, info: &Vec<String>) -> Result<(), NevekoError> {
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let pre_import = monero::import_multisig_info(info.to_vec()).await;
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
if pre_import.result.n_outputs == 0 {
|
||||
error!("unable to import multisig info for order: {}", orid);
|
||||
return;
|
||||
return Err(NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
let mut old_order = order::find(orid);
|
||||
let mut old_order = order::find(orid)?;
|
||||
let status = order::StatusType::MulitsigComplete.value();
|
||||
old_order.status = String::from(&status);
|
||||
let j_old_order = Json(old_order);
|
||||
order::modify(j_old_order);
|
||||
order::modify(j_old_order)?;
|
||||
debug!("order: {} updated to: {}", orid, status);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Customer begins multisig orchestration by requesting the prepare info
|
||||
|
@ -699,55 +781,54 @@ pub async fn d_trigger_msig_info(
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_test() {
|
||||
fn create_test() -> Result<(), NevekoError> {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
let body: String = String::from("test body");
|
||||
let message = Message {
|
||||
body: body,
|
||||
body,
|
||||
..Default::default()
|
||||
};
|
||||
let j_message = utils::message_to_json(&message);
|
||||
let jwp = String::from("test-jwp");
|
||||
tokio::spawn(async move {
|
||||
let test_message = create(j_message, jwp, MessageType::Normal).await;
|
||||
let a_test_message = create(j_message, jwp, MessageType::Normal).await;
|
||||
let test_message = a_test_message.unwrap_or_default();
|
||||
let expected: Message = Default::default();
|
||||
assert_eq!(test_message.body, expected.body);
|
||||
cleanup(&test_message.mid).await;
|
||||
cleanup(&test_message.mid).unwrap();
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_test() {
|
||||
fn find_test() -> Result<(), NevekoError> {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
let body: String = String::from("test body");
|
||||
let expected_message = Message {
|
||||
body: body,
|
||||
body,
|
||||
..Default::default()
|
||||
};
|
||||
let k = "test-key";
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&expected_message))
|
||||
.await;
|
||||
let actual_message: Message = find(&String::from(k));
|
||||
assert_eq!(expected_message.body, actual_message.body);
|
||||
cleanup(&String::from(k)).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let db = &DATABASE_LOCK;
|
||||
let message = bincode::serialize(&expected_message).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let actual_message: Message = find(&String::from(k))?;
|
||||
assert_eq!(expected_message.body, actual_message.body);
|
||||
cleanup(&String::from(k))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -758,7 +839,7 @@ mod tests {
|
|||
let _enter = rt.enter();
|
||||
let body: String = String::from("test body");
|
||||
let message = Message {
|
||||
body: body,
|
||||
body,
|
||||
..Default::default()
|
||||
};
|
||||
let j_message = utils::message_to_json(&message);
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
//! Custom object relational mapping (ORM) for structs into LMBD
|
||||
|
||||
use crate::utils;
|
||||
use rocket::serde::{
|
||||
json::Json,
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Authorization {
|
||||
pub aid: String,
|
||||
|
@ -18,47 +17,7 @@ pub struct Authorization {
|
|||
pub xmr_address: String,
|
||||
}
|
||||
|
||||
impl Default for Authorization {
|
||||
fn default() -> Self {
|
||||
Authorization {
|
||||
aid: utils::empty_string(),
|
||||
created: 0,
|
||||
uid: utils::empty_string(),
|
||||
rnd: utils::empty_string(),
|
||||
token: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Authorization {
|
||||
pub fn to_db(a: &Authorization) -> String {
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}",
|
||||
a.created, a.uid, a.rnd, a.token, a.xmr_address
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Authorization {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let created_str = v.remove(0);
|
||||
let created = match created_str.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => 0,
|
||||
};
|
||||
let uid = v.remove(0);
|
||||
let rnd = v.remove(0);
|
||||
let token = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
Authorization {
|
||||
aid: k,
|
||||
created,
|
||||
uid,
|
||||
rnd,
|
||||
token,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update_uid(a: Authorization, uid: String) -> Authorization {
|
||||
Authorization {
|
||||
aid: a.aid,
|
||||
|
@ -86,7 +45,7 @@ impl Authorization {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Contact {
|
||||
pub cid: String,
|
||||
|
@ -96,46 +55,7 @@ pub struct Contact {
|
|||
pub nmpk: String,
|
||||
}
|
||||
|
||||
impl Default for Contact {
|
||||
fn default() -> Self {
|
||||
Contact {
|
||||
cid: utils::empty_string(),
|
||||
nmpk: utils::empty_string(),
|
||||
i2p_address: utils::empty_string(),
|
||||
is_vendor: false,
|
||||
xmr_address: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Contact {
|
||||
pub fn to_db(c: &Contact) -> String {
|
||||
format!(
|
||||
"{}!{}!{}!{}",
|
||||
c.nmpk, c.i2p_address, c.is_vendor, c.xmr_address
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Contact {
|
||||
let values = v.split("!");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let nmpk = v.remove(0);
|
||||
let i2p_address = v.remove(0);
|
||||
let is_vendor = match v.remove(0).parse::<bool>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => false,
|
||||
};
|
||||
let xmr_address = v.remove(0);
|
||||
Contact {
|
||||
cid: k,
|
||||
nmpk,
|
||||
i2p_address,
|
||||
is_vendor,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Message {
|
||||
pub mid: String,
|
||||
|
@ -146,47 +66,7 @@ pub struct Message {
|
|||
pub to: String,
|
||||
}
|
||||
|
||||
impl Default for Message {
|
||||
fn default() -> Self {
|
||||
Message {
|
||||
mid: utils::empty_string(),
|
||||
uid: utils::empty_string(),
|
||||
body: utils::empty_string(),
|
||||
created: 0,
|
||||
from: utils::empty_string(),
|
||||
to: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub fn to_db(m: &Message) -> String {
|
||||
format!("{}:{}:{}:{}:{}", m.uid, m.body, m.created, m.from, m.to)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Message {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let uid = v.remove(0);
|
||||
let body = v.remove(0);
|
||||
let created_str = v.remove(0);
|
||||
let created = match created_str.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => 0,
|
||||
};
|
||||
let from = v.remove(0);
|
||||
let to = v.remove(0);
|
||||
Message {
|
||||
mid: k,
|
||||
uid,
|
||||
body,
|
||||
created,
|
||||
from,
|
||||
to,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct User {
|
||||
pub uid: String,
|
||||
|
@ -194,31 +74,7 @@ pub struct User {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl Default for User {
|
||||
fn default() -> Self {
|
||||
User {
|
||||
uid: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
name: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn to_db(u: &User) -> String {
|
||||
format!("{}:{}", u.name, u.xmr_address)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> User {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let name = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
User {
|
||||
uid: k,
|
||||
name,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update(u: User, name: String) -> User {
|
||||
User {
|
||||
uid: u.uid,
|
||||
|
@ -228,7 +84,7 @@ impl User {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Product {
|
||||
pub pid: String,
|
||||
|
@ -240,61 +96,12 @@ pub struct Product {
|
|||
pub qty: u128,
|
||||
}
|
||||
|
||||
impl Default for Product {
|
||||
fn default() -> Self {
|
||||
Product {
|
||||
pid: utils::empty_string(),
|
||||
description: utils::empty_string(),
|
||||
image: Vec::new(),
|
||||
in_stock: false,
|
||||
name: utils::empty_string(),
|
||||
price: 0,
|
||||
qty: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Product {
|
||||
pub fn to_db(p: &Product) -> String {
|
||||
let image: String = hex::encode(&p.image);
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}:{}",
|
||||
p.description, image, p.in_stock, p.name, p.price, p.qty
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Product {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let description = v.remove(0);
|
||||
let image = hex::decode(v.remove(0)).unwrap_or(Vec::new());
|
||||
let in_stock = match v.remove(0).parse::<bool>() {
|
||||
Ok(b) => b,
|
||||
Err(_) => false,
|
||||
};
|
||||
let name = v.remove(0);
|
||||
let price = match v.remove(0).parse::<u128>() {
|
||||
Ok(p) => p,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let qty = match v.remove(0).parse::<u128>() {
|
||||
Ok(q) => q,
|
||||
Err(_) => 0,
|
||||
};
|
||||
Product {
|
||||
pid: k,
|
||||
description,
|
||||
image,
|
||||
in_stock,
|
||||
name,
|
||||
price,
|
||||
qty,
|
||||
}
|
||||
}
|
||||
pub fn update(p: Product, jp: &Json<Product>) -> Product {
|
||||
Product {
|
||||
pid: p.pid,
|
||||
description: String::from(&jp.description),
|
||||
image: jp.image.iter().cloned().collect(),
|
||||
image: jp.image.to_vec(),
|
||||
in_stock: jp.in_stock,
|
||||
name: String::from(&jp.name),
|
||||
price: jp.price,
|
||||
|
@ -303,7 +110,7 @@ impl Product {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Order {
|
||||
pub orid: String,
|
||||
|
@ -341,152 +148,7 @@ pub struct Order {
|
|||
pub xmr_address: String,
|
||||
}
|
||||
|
||||
impl Default for Order {
|
||||
fn default() -> Self {
|
||||
Order {
|
||||
orid: utils::empty_string(),
|
||||
cid: utils::empty_string(),
|
||||
pid: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
cust_kex_1: utils::empty_string(),
|
||||
cust_kex_2: utils::empty_string(),
|
||||
cust_kex_3: utils::empty_string(),
|
||||
cust_msig_make: utils::empty_string(),
|
||||
cust_msig_prepare: utils::empty_string(),
|
||||
cust_msig_txset: utils::empty_string(),
|
||||
date: 0,
|
||||
deliver_date: 0,
|
||||
hash: utils::empty_string(),
|
||||
adjudicator_kex_1: utils::empty_string(),
|
||||
adjudicator_kex_2: utils::empty_string(),
|
||||
adjudicator_kex_3: utils::empty_string(),
|
||||
adjudicator_msig_make: utils::empty_string(),
|
||||
adjudicator_msig_prepare: utils::empty_string(),
|
||||
ship_address: utils::empty_string(),
|
||||
ship_date: 0,
|
||||
subaddress: utils::empty_string(),
|
||||
status: utils::empty_string(),
|
||||
quantity: 0,
|
||||
vend_kex_1: utils::empty_string(),
|
||||
vend_kex_2: utils::empty_string(),
|
||||
vend_kex_3: utils::empty_string(),
|
||||
vend_msig_make: utils::empty_string(),
|
||||
vend_msig_prepare: utils::empty_string(),
|
||||
vend_msig_txset: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Order {
|
||||
pub fn to_db(o: &Order) -> String {
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
||||
o.cid,
|
||||
o.pid,
|
||||
o.cust_kex_1,
|
||||
o.cust_kex_2,
|
||||
o.cust_kex_3,
|
||||
o.cust_msig_make,
|
||||
o.cust_msig_prepare,
|
||||
o.cust_msig_txset,
|
||||
o.date,
|
||||
o.deliver_date,
|
||||
o.hash,
|
||||
o.adjudicator_msig_make,
|
||||
o.adjudicator_msig_prepare,
|
||||
o.adjudicator_kex_1,
|
||||
o.adjudicator_kex_2,
|
||||
o.adjudicator_kex_3,
|
||||
o.ship_address,
|
||||
o.ship_date,
|
||||
o.subaddress,
|
||||
o.status,
|
||||
o.quantity,
|
||||
o.vend_kex_1,
|
||||
o.vend_kex_2,
|
||||
o.vend_kex_3,
|
||||
o.vend_msig_make,
|
||||
o.vend_msig_prepare,
|
||||
o.vend_msig_txset,
|
||||
o.xmr_address,
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Order {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let orid = k;
|
||||
let cid = v.remove(0);
|
||||
let pid = v.remove(0);
|
||||
let cust_kex_1 = v.remove(0);
|
||||
let cust_kex_2 = v.remove(0);
|
||||
let cust_kex_3 = v.remove(0);
|
||||
let cust_msig_make = v.remove(0);
|
||||
let cust_msig_prepare = v.remove(0);
|
||||
let cust_msig_txset = v.remove(0);
|
||||
let date = match v.remove(0).parse::<i64>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let deliver_date = match v.remove(0).parse::<i64>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let hash = v.remove(0);
|
||||
let adjudicator_msig_make = v.remove(0);
|
||||
let adjudicator_msig_prepare = v.remove(0);
|
||||
let adjudicator_kex_1 = v.remove(0);
|
||||
let adjudicator_kex_2 = v.remove(0);
|
||||
let adjudicator_kex_3 = v.remove(0);
|
||||
let ship_address = v.remove(0);
|
||||
let ship_date = match v.remove(0).parse::<i64>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let subaddress = v.remove(0);
|
||||
let status = v.remove(0);
|
||||
let quantity = match v.remove(0).parse::<u128>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let vend_kex_1 = v.remove(0);
|
||||
let vend_kex_2 = v.remove(0);
|
||||
let vend_kex_3 = v.remove(0);
|
||||
let vend_msig_make = v.remove(0);
|
||||
let vend_msig_prepare = v.remove(0);
|
||||
let vend_msig_txset = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
Order {
|
||||
orid,
|
||||
cid,
|
||||
pid,
|
||||
cust_kex_1,
|
||||
cust_kex_2,
|
||||
cust_kex_3,
|
||||
cust_msig_make,
|
||||
cust_msig_prepare,
|
||||
cust_msig_txset,
|
||||
date,
|
||||
deliver_date,
|
||||
hash,
|
||||
adjudicator_kex_1,
|
||||
adjudicator_kex_2,
|
||||
adjudicator_kex_3,
|
||||
adjudicator_msig_make,
|
||||
adjudicator_msig_prepare,
|
||||
ship_address,
|
||||
ship_date,
|
||||
subaddress,
|
||||
status,
|
||||
quantity,
|
||||
vend_kex_1,
|
||||
vend_kex_2,
|
||||
vend_kex_3,
|
||||
vend_msig_make,
|
||||
vend_msig_prepare,
|
||||
vend_msig_txset,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update(orid: String, o: &Json<Order>) -> Order {
|
||||
Order {
|
||||
orid,
|
||||
|
@ -522,7 +184,7 @@ impl Order {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Dispute {
|
||||
pub did: String,
|
||||
|
@ -530,36 +192,3 @@ pub struct Dispute {
|
|||
pub orid: String,
|
||||
pub tx_set: String,
|
||||
}
|
||||
|
||||
impl Default for Dispute {
|
||||
fn default() -> Self {
|
||||
Dispute {
|
||||
did: utils::empty_string(),
|
||||
created: 0,
|
||||
orid: utils::empty_string(),
|
||||
tx_set: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispute {
|
||||
pub fn to_db(d: &Dispute) -> String {
|
||||
format!("{}:{}:{}", d.created, d.orid, d.tx_set)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Dispute {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let created = match v.remove(0).parse::<i64>() {
|
||||
Ok(t) => t,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let orid = v.remove(0);
|
||||
let tx_set = v.remove(0);
|
||||
Dispute {
|
||||
did: k,
|
||||
created,
|
||||
orid,
|
||||
tx_set,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use crate::{
|
||||
args,
|
||||
error::NevekoError,
|
||||
i2p,
|
||||
proof,
|
||||
reqres,
|
||||
|
@ -17,11 +18,7 @@ use log::{
|
|||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
io::Write,
|
||||
process::{
|
||||
Command,
|
||||
Stdio,
|
||||
},
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -176,7 +173,7 @@ impl LockTimeLimit {
|
|||
/// Start monerod from the `--monero-location` flag
|
||||
///
|
||||
/// default: /home/$USER/monero-xxx-xxx
|
||||
pub fn start_daemon() {
|
||||
pub fn start_daemon() -> Result<(), NevekoError> {
|
||||
info!("starting monerod");
|
||||
let blockchain_dir = get_blockchain_dir();
|
||||
let bin_dir = get_monero_location();
|
||||
|
@ -184,13 +181,13 @@ pub fn start_daemon() {
|
|||
let mut socks_proxy_host = utils::get_i2p_wallet_proxy_host();
|
||||
if socks_proxy_host.contains("http://") {
|
||||
let values = socks_proxy_host.split("http://");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
socks_proxy_host = v.remove(1);
|
||||
};
|
||||
let tx_proxy = format!("i2p,{}", socks_proxy_host);
|
||||
// proxy host can't have protocol
|
||||
let anon_in_port = get_anon_inbound_port();
|
||||
let destination = i2p::get_destination(Some(anon_in_port));
|
||||
let destination = i2p::get_destination(i2p::ServerTunnelType::App)?;
|
||||
let anon_inbound = format!("{},127.0.0.1:{}", destination, anon_in_port);
|
||||
let mut args = vec!["--data-dir", &blockchain_dir, "--detach"];
|
||||
if release_env == utils::ReleaseEnvironment::Development {
|
||||
|
@ -200,6 +197,7 @@ pub fn start_daemon() {
|
|||
.spawn()
|
||||
.expect("monerod failed to start");
|
||||
debug!("{:?}", output.stdout);
|
||||
Ok(())
|
||||
} else {
|
||||
args.push("--tx-proxy");
|
||||
args.push(&tx_proxy);
|
||||
|
@ -210,16 +208,17 @@ pub fn start_daemon() {
|
|||
.spawn()
|
||||
.expect("monerod failed to start");
|
||||
debug!("{:?}", output.stdout);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Start monero-wallet-rpc
|
||||
pub fn start_rpc() {
|
||||
info!("starting monero-wallet-rpc");
|
||||
let cli_args = args::Args::parse();
|
||||
let bin_dir = get_monero_location();
|
||||
let port = get_rpc_port();
|
||||
let login = get_rpc_creds();
|
||||
info!("starting monero-wallet-rpc from {}", &bin_dir);
|
||||
let daemon_address = cli_args.monero_rpc_daemon;
|
||||
let rpc_login = format!("{}:{}", &login.username, &login.credential);
|
||||
let release_env = utils::get_release_env();
|
||||
|
@ -241,7 +240,7 @@ pub fn start_rpc() {
|
|||
let mut proxy_host = utils::get_i2p_wallet_proxy_host();
|
||||
if proxy_host.contains("http://") {
|
||||
let values = proxy_host.split("http://");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
proxy_host = v.remove(1);
|
||||
}
|
||||
let mut args = vec![
|
||||
|
@ -281,9 +280,9 @@ pub fn start_rpc() {
|
|||
|
||||
fn get_rpc_port() -> String {
|
||||
let args = args::Args::parse();
|
||||
let rpc = String::from(args.monero_rpc_host);
|
||||
let rpc = args.monero_rpc_host;
|
||||
let values = rpc.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let port = v.remove(2);
|
||||
debug!("monero-wallet-rpc port: {}", port);
|
||||
port
|
||||
|
@ -291,28 +290,22 @@ fn get_rpc_port() -> String {
|
|||
|
||||
pub fn get_daemon_port() -> u16 {
|
||||
let args = args::Args::parse();
|
||||
let rpc = String::from(args.monero_rpc_daemon);
|
||||
let rpc = args.monero_rpc_daemon;
|
||||
let values = rpc.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let port = v.remove(2);
|
||||
debug!("monerod port: {}", port);
|
||||
match port.parse::<u16>() {
|
||||
Ok(p) => p,
|
||||
Err(_) => 0,
|
||||
}
|
||||
port.parse::<u16>().unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn get_tx_proxy_port() -> u16 {
|
||||
let args = args::Args::parse();
|
||||
let rpc = String::from(args.i2p_socks_proxy_host);
|
||||
let rpc = args.i2p_socks_proxy_host;
|
||||
let values = rpc.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let port = v.remove(2);
|
||||
debug!("i2p socks port: {}", port);
|
||||
match port.parse::<u16>() {
|
||||
Ok(p) => p,
|
||||
Err(_) => 0,
|
||||
}
|
||||
port.parse::<u16>().unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn get_anon_inbound_port() -> u16 {
|
||||
|
@ -323,22 +316,21 @@ pub fn get_anon_inbound_port() -> u16 {
|
|||
/// Get monero rpc host from command line argument
|
||||
fn get_blockchain_dir() -> String {
|
||||
let args = args::Args::parse();
|
||||
String::from(args.monero_blockchain_dir)
|
||||
args.monero_blockchain_dir
|
||||
}
|
||||
|
||||
/// Get monero download location
|
||||
fn get_monero_location() -> String {
|
||||
let args = args::Args::parse();
|
||||
let user = std::env::var("USER").unwrap_or(utils::empty_string());
|
||||
format!("/home/{}/{}", &user, &args.monero_location)
|
||||
args.monero_location.to_string()
|
||||
}
|
||||
|
||||
/// Get monero rpc host from the `--monero-rpc-host` cli arg
|
||||
fn get_rpc_host() -> String {
|
||||
let args = args::Args::parse();
|
||||
let gui_host = std::env::var(crate::MONERO_WALLET_RPC_HOST).unwrap_or(utils::empty_string());
|
||||
let rpc = if gui_host == utils::empty_string() {
|
||||
String::from(args.monero_rpc_host)
|
||||
let gui_host = std::env::var(crate::MONERO_WALLET_RPC_HOST).unwrap_or(String::new());
|
||||
let rpc = if gui_host.is_empty() {
|
||||
args.monero_rpc_host
|
||||
} else {
|
||||
gui_host
|
||||
};
|
||||
|
@ -348,8 +340,8 @@ fn get_rpc_host() -> String {
|
|||
/// Get creds from the `--monero-rpc-daemon` cli arg
|
||||
fn get_rpc_creds() -> RpcLogin {
|
||||
let args = args::Args::parse();
|
||||
let username = String::from(args.monero_rpc_username);
|
||||
let credential = String::from(args.monero_rpc_cred);
|
||||
let username = args.monero_rpc_username;
|
||||
let credential = args.monero_rpc_cred;
|
||||
RpcLogin {
|
||||
username,
|
||||
credential,
|
||||
|
@ -358,9 +350,9 @@ fn get_rpc_creds() -> RpcLogin {
|
|||
|
||||
fn get_rpc_daemon() -> String {
|
||||
let args = args::Args::parse();
|
||||
let gui_host = std::env::var(crate::MONERO_DAEMON_HOST).unwrap_or(utils::empty_string());
|
||||
if gui_host == utils::empty_string() {
|
||||
String::from(args.monero_rpc_daemon)
|
||||
let gui_host = std::env::var(crate::MONERO_DAEMON_HOST).unwrap_or(String::new());
|
||||
if gui_host.is_empty() {
|
||||
args.monero_rpc_daemon
|
||||
} else {
|
||||
gui_host
|
||||
}
|
||||
|
@ -396,7 +388,7 @@ pub async fn get_version() -> reqres::XmrRpcVersionResponse {
|
|||
}
|
||||
|
||||
/// Helper function for checking xmr rpc online during app startup
|
||||
pub async fn check_rpc_connection() -> () {
|
||||
pub async fn check_rpc_connection() {
|
||||
let res: reqres::XmrRpcVersionResponse = get_version().await;
|
||||
if res.result.version == INVALID_VERSION {
|
||||
error!("failed to connect to monero-wallet-rpc");
|
||||
|
@ -531,10 +523,10 @@ fn update_wallet_lock(filename: &String, closing: bool) -> bool {
|
|||
}
|
||||
if !closing {
|
||||
*IS_WALLET_BUSY.lock().unwrap() = true;
|
||||
return true;
|
||||
true
|
||||
} else {
|
||||
*IS_WALLET_BUSY.lock().unwrap() = false;
|
||||
return true;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,7 +568,7 @@ pub async fn open_wallet(filename: &String, password: &String) -> bool {
|
|||
if r.contains("-1") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -615,10 +607,7 @@ pub async fn close_wallet(filename: &String, password: &String) -> bool {
|
|||
// The result from wallet operation is empty
|
||||
let res = response.text().await;
|
||||
debug!("{} response: {:?}", RpcFields::Close.value(), res);
|
||||
match res {
|
||||
Ok(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
res.is_ok()
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
|
@ -662,7 +651,7 @@ pub async fn change_wallet_password(new_password: &String) -> bool {
|
|||
if r.contains("-1") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! NEVEKO modified ed25519 library extending curve25519-dalek
|
||||
|
||||
use crate::monero;
|
||||
use curve25519_dalek::{
|
||||
edwards::{
|
||||
CompressedEdwardsY,
|
||||
|
@ -16,11 +17,6 @@ use sha2::{
|
|||
Sha512,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
monero,
|
||||
utils,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Container for the Neveko Message Keys
|
||||
pub struct NevekoMessageKeys {
|
||||
|
@ -39,8 +35,8 @@ impl Default for NevekoMessageKeys {
|
|||
NevekoMessageKeys {
|
||||
nmpk: [0u8; 32],
|
||||
nmsk: [0u8; 32],
|
||||
hex_nmpk: utils::empty_string(),
|
||||
hex_nmsk: utils::empty_string(),
|
||||
hex_nmpk: String::new(),
|
||||
hex_nmsk: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +50,7 @@ fn curve_l_as_big_int() -> BigInt {
|
|||
}
|
||||
|
||||
fn big_int_to_string(b: &BigInt) -> String {
|
||||
String::from(String::from_utf8(b.to_signed_bytes_le()).unwrap_or_default())
|
||||
String::from_utf8(b.to_signed_bytes_le()).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Hash string input to scalar
|
||||
|
@ -96,7 +92,7 @@ fn hash_to_scalar(s: Vec<&str>) -> Scalar {
|
|||
/// Neveko Message Public Key (NMPK).
|
||||
pub async fn generate_neveko_message_keys() -> NevekoMessageKeys {
|
||||
log::info!("generating neveko message keys");
|
||||
let password = std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(utils::empty_string());
|
||||
let password = std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::new());
|
||||
let filename = String::from(crate::APP_NAME);
|
||||
let m_wallet = monero::open_wallet(&filename, &password).await;
|
||||
if !m_wallet {
|
||||
|
@ -110,8 +106,8 @@ pub async fn generate_neveko_message_keys() -> NevekoMessageKeys {
|
|||
let point_nmpk = EdwardsPoint::mul_base(&scalar_nmsk);
|
||||
let nmsk = *scalar_nmsk.as_bytes();
|
||||
let nmpk: [u8; 32] = *point_nmpk.compress().as_bytes();
|
||||
let hex_nmpk = hex::encode(&nmpk);
|
||||
let hex_nmsk = hex::encode(&nmsk);
|
||||
let hex_nmpk = hex::encode(nmpk);
|
||||
let hex_nmsk = hex::encode(nmsk);
|
||||
NevekoMessageKeys {
|
||||
nmpk,
|
||||
nmsk,
|
||||
|
@ -130,7 +126,7 @@ pub async fn generate_neveko_message_keys() -> NevekoMessageKeys {
|
|||
///
|
||||
/// Pass `None` to encipher parameter to perform deciphering.
|
||||
pub async fn cipher(hex_nmpk: &String, message: String, encipher: Option<String>) -> String {
|
||||
let unwrap_encipher: String = encipher.unwrap_or(utils::empty_string());
|
||||
let unwrap_encipher: String = encipher.unwrap_or(String::new());
|
||||
let keys: NevekoMessageKeys = generate_neveko_message_keys().await;
|
||||
// shared secret = nmpk * nmsk
|
||||
let scalar_nmsk = Scalar::from_bytes_mod_order(keys.nmsk);
|
||||
|
@ -143,15 +139,15 @@ pub async fn cipher(hex_nmpk: &String, message: String, encipher: Option<String>
|
|||
// x = m + h or x = m - h'
|
||||
let h = hash_to_scalar(vec![&ss_hex[..]]);
|
||||
let h_bi = BigInt::from_bytes_le(Sign::Plus, h.as_bytes());
|
||||
if unwrap_encipher == String::from(ENCIPHER) {
|
||||
let msg_bi = BigInt::from_bytes_le(Sign::Plus, &message.as_bytes());
|
||||
if unwrap_encipher == *ENCIPHER {
|
||||
let msg_bi = BigInt::from_bytes_le(Sign::Plus, message.as_bytes());
|
||||
let x = msg_bi + h_bi;
|
||||
return hex::encode(x.to_bytes_le().1);
|
||||
hex::encode(x.to_bytes_le().1)
|
||||
} else {
|
||||
let msg_bi = BigInt::from_bytes_le(Sign::Plus, &hex::decode(&message).unwrap_or_default());
|
||||
let x = msg_bi - h_bi;
|
||||
return big_int_to_string(&x);
|
||||
};
|
||||
big_int_to_string(&x)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
@ -162,7 +158,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
fn test_cipher(message: &String, encipher: Option<String>) -> String {
|
||||
let unwrap_encipher: String = encipher.unwrap_or(utils::empty_string());
|
||||
let unwrap_encipher: String = encipher.unwrap_or(String::new());
|
||||
let test_nmpk: [u8; 32] = [
|
||||
203, 2, 188, 13, 167, 96, 59, 189, 38, 238, 2, 71, 84, 155, 153, 73, 241, 137, 9, 30,
|
||||
28, 134, 91, 137, 134, 73, 231, 45, 174, 98, 103, 158,
|
||||
|
|
|
@ -4,7 +4,11 @@ use std::error::Error;
|
|||
|
||||
use crate::{
|
||||
contact,
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
i2p,
|
||||
models::*,
|
||||
monero,
|
||||
|
@ -14,6 +18,9 @@ use crate::{
|
|||
reqres,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError::{
|
||||
self,
|
||||
};
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -42,7 +49,7 @@ impl StatusType {
|
|||
}
|
||||
|
||||
/// Create a intial order
|
||||
pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
||||
pub async fn create(j_order: Json<reqres::OrderRequest>) -> Result<Order, NevekoError> {
|
||||
info!("creating order");
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
|
@ -65,147 +72,180 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
|||
..Default::default()
|
||||
};
|
||||
debug!("insert order: {:?}", new_order);
|
||||
let order_wallet_password = utils::empty_string();
|
||||
let order_wallet_password = String::new();
|
||||
let m_wallet = monero::create_wallet(&orid, &order_wallet_password).await;
|
||||
if !m_wallet {
|
||||
error!("error creating msig wallet for order {}", &orid);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
monero::close_wallet(&orid, &order_wallet_password).await;
|
||||
debug!("insert order: {:?}", &new_order);
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
// inject adjudicator separately, modifying the order model is mendokusai
|
||||
let adjudicator_k = format!("{}-{}", crate::ADJUDICATOR_DB_KEY, &orid);
|
||||
db::Interface::async_write(&s.env, &s.handle, &adjudicator_k, &j_order.adjudicator).await;
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
adjudicator_k.as_bytes(),
|
||||
j_order.adjudicator.as_bytes(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_order.orid;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Order::to_db(&new_order)).await;
|
||||
let order = bincode::serialize(&new_order).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &order)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all orders, write keys to with ol
|
||||
let list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating order index");
|
||||
}
|
||||
let order_list = [r, String::from(&orid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let order_list = [old, String::from(&orid)].join(",");
|
||||
let s_order_list = bincode::serialize(&order_list).unwrap_or_default();
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
db::Interface::async_write(&s.env, &s.handle, &String::from(list_key), &order_list).await;
|
||||
new_order
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_order_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(new_order)
|
||||
}
|
||||
|
||||
/// Backup order for customer
|
||||
pub fn backup(order: &Order) {
|
||||
pub fn backup(order: &Order) -> Result<(), NevekoError> {
|
||||
info!("creating backup of order: {}", order.orid);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &order.orid;
|
||||
db::Interface::delete(&s.env, &s.handle, k);
|
||||
db::Interface::write(&s.env, &s.handle, k, &Order::to_db(&order));
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let db = &DATABASE_LOCK;
|
||||
let order_to_db = bincode::serialize(&order).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &order_to_db)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all orders, write keys to with col
|
||||
let list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating customer order index");
|
||||
}
|
||||
let mut order_list = [String::from(&r), String::from(&order.orid)].join(",");
|
||||
let d_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let mut order_list = [String::from(&d_r), String::from(&order.orid)].join(",");
|
||||
let s_order_list = bincode::serialize(&order_list).unwrap_or_default();
|
||||
// don't duplicate order ids when backing up updates from vendor
|
||||
if String::from(&r).contains(&String::from(&order.orid)) {
|
||||
order_list = r;
|
||||
if String::from(&d_r).contains(&String::from(&order.orid)) {
|
||||
order_list = d_r;
|
||||
}
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||
let db = &DATABASE_LOCK;
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_order_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lookup order
|
||||
pub fn find(oid: &String) -> Order {
|
||||
pub fn find(oid: &String) -> Result<Order, NevekoError> {
|
||||
info!("find order: {}", &oid);
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(oid));
|
||||
if r == utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &oid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("order not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
Order::from_db(String::from(oid), r)
|
||||
let result: Order = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Lookup all orders from admin server
|
||||
pub fn find_all() -> Vec<Order> {
|
||||
let i_s = db::Interface::open();
|
||||
pub fn find_all() -> Result<Vec<Order>, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
let de: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_oid = de.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(String::from).collect();
|
||||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() {
|
||||
let order: Order = find(&o)?;
|
||||
if !order.orid.is_empty() {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
orders
|
||||
Ok(orders)
|
||||
}
|
||||
|
||||
/// Lookup all orders that customer has saved from gui
|
||||
pub fn find_all_backup() -> Vec<Order> {
|
||||
let i_s = db::Interface::open();
|
||||
pub fn find_all_backup() -> Result<Vec<Order>, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("customer order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
let de: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_oid = de.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(String::from).collect();
|
||||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
let visible = order.orid != utils::empty_string()
|
||||
let order: Order = find(&o)?;
|
||||
let visible = !order.orid.is_empty()
|
||||
&& order.status != order::StatusType::Delivered.value()
|
||||
&& order.status != order::StatusType::Cancelled.value();
|
||||
if visible {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
orders
|
||||
Ok(orders)
|
||||
}
|
||||
|
||||
/// Lookup all orders for customer
|
||||
pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
||||
pub async fn find_all_customer_orders(cid: String) -> Result<Vec<Order>, NevekoError> {
|
||||
info!("lookup orders for customer: {}", &cid);
|
||||
let i_s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
let de: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_oid = de.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(String::from).collect();
|
||||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() && order.cid == cid {
|
||||
let order: Order = find(&o)?;
|
||||
if !order.orid.is_empty() && order.cid == cid {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
orders
|
||||
Ok(orders)
|
||||
}
|
||||
|
||||
/// Lookup all orders for vendor
|
||||
pub fn find_all_vendor_orders() -> Vec<Order> {
|
||||
pub fn find_all_vendor_orders() -> Result<Vec<Order>, NevekoError> {
|
||||
info!("lookup orders for vendor");
|
||||
let i_s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
let de: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_oid = de.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(String::from).collect();
|
||||
let mut orders: Vec<Order> = Vec::new();
|
||||
let vendor_b32: String = i2p::get_destination(None);
|
||||
let vendor_b32: String = i2p::get_destination(i2p::ServerTunnelType::App)?;
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() && order.cid != vendor_b32 {
|
||||
let order: Order = find(&o)?;
|
||||
if !order.orid.is_empty() && order.cid != vendor_b32 {
|
||||
// TODO(c2m): separate functionality for archived orders
|
||||
if order.status != order::StatusType::Cancelled.value()
|
||||
&& order.status != order::StatusType::Delivered.value()
|
||||
|
@ -214,22 +254,25 @@ pub fn find_all_vendor_orders() -> Vec<Order> {
|
|||
}
|
||||
}
|
||||
}
|
||||
orders
|
||||
Ok(orders)
|
||||
}
|
||||
|
||||
/// Modify order from admin server
|
||||
pub fn modify(o: Json<Order>) -> Order {
|
||||
pub fn modify(o: Json<Order>) -> Result<Order, NevekoError> {
|
||||
info!("modify order: {}", &o.orid);
|
||||
let f_order: Order = find(&o.orid);
|
||||
if f_order.orid == utils::empty_string() {
|
||||
let f_order: Order = find(&o.orid)?;
|
||||
if f_order.orid.is_empty() {
|
||||
error!("order not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let db = &DATABASE_LOCK;
|
||||
let u_order = Order::update(String::from(&f_order.orid), &o);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_order.orid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_order.orid, &Order::to_db(&u_order));
|
||||
return u_order;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, &u_order.orid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let v = bincode::serialize(&u_order).unwrap_or_default();
|
||||
let _ = db::write_chunks(&db.env, &db.handle, &u_order.orid.as_bytes(), &v)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(u_order)
|
||||
}
|
||||
|
||||
/// Sign and submit multisig
|
||||
|
@ -238,13 +281,13 @@ pub async fn sign_and_submit_multisig(
|
|||
tx_data_hex: &String,
|
||||
) -> reqres::XmrRpcSubmitMultisigResponse {
|
||||
info!("signing and submitting multisig");
|
||||
let wallet_password = utils::empty_string();
|
||||
monero::open_wallet(&orid, &wallet_password).await;
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
let r_sign: reqres::XmrRpcSignMultisigResponse =
|
||||
monero::sign_multisig(String::from(tx_data_hex)).await;
|
||||
let r_submit: reqres::XmrRpcSubmitMultisigResponse =
|
||||
monero::submit_multisig(r_sign.result.tx_data_hex).await;
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
if r_submit.result.tx_hash_list.is_empty() {
|
||||
error!("unable to submit payment for order: {}", orid);
|
||||
}
|
||||
|
@ -259,12 +302,12 @@ pub async fn sign_and_submit_multisig(
|
|||
/// access
|
||||
///
|
||||
/// the details of said order.
|
||||
pub async fn secure_retrieval(orid: &String, signature: &String) -> Order {
|
||||
pub async fn secure_retrieval(orid: &String, signature: &String) -> Result<Order, NevekoError> {
|
||||
info!("secure order retrieval for {}", orid);
|
||||
// get customer address for NEVEKO NOT order wallet
|
||||
let m_order: Order = find(&orid);
|
||||
let m_order: Order = find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let mut xmr_address: String = String::new();
|
||||
let a_customers: Vec<Contact> = contact::find_all();
|
||||
let a_customers: Vec<Contact> = contact::find_all().map_err(|_| NevekoError::Contact)?;
|
||||
for customer in a_customers {
|
||||
if customer.i2p_address == m_order.cid {
|
||||
xmr_address = customer.xmr_address;
|
||||
|
@ -281,20 +324,20 @@ pub async fn secure_retrieval(orid: &String, signature: &String) -> Order {
|
|||
let is_valid_signature = monero::verify(xmr_address, id, sig).await;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
if !is_valid_signature {
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
m_order
|
||||
Ok(m_order)
|
||||
}
|
||||
|
||||
/// In order for the order (...ha) to only be cancelled by the customer
|
||||
///
|
||||
/// they must sign the order id with their NEVEKO wallet instance.
|
||||
pub async fn cancel_order(orid: &String, signature: &String) -> Order {
|
||||
pub async fn cancel_order(orid: &String, signature: &String) -> Result<Order, NevekoError> {
|
||||
info!("cancel order {}", orid);
|
||||
// get customer address for NEVEKO NOT order wallet
|
||||
let mut m_order: Order = find(&orid);
|
||||
let mut m_order: Order = find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let mut xmr_address: String = String::new();
|
||||
let a_customers: Vec<Contact> = contact::find_all();
|
||||
let a_customers: Vec<Contact> = contact::find_all().map_err(|_| NevekoError::Contact)?;
|
||||
for customer in a_customers {
|
||||
if customer.i2p_address == m_order.cid {
|
||||
xmr_address = customer.xmr_address;
|
||||
|
@ -311,52 +354,56 @@ pub async fn cancel_order(orid: &String, signature: &String) -> Order {
|
|||
let is_valid_signature = monero::verify(xmr_address, id, sig).await;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
if !is_valid_signature {
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
// update the order status and send to customer
|
||||
m_order.status = order::StatusType::Cancelled.value();
|
||||
order::modify(Json(m_order));
|
||||
order::find(&orid)
|
||||
order::modify(Json(m_order))?;
|
||||
order::find(orid).map_err(|_| NevekoError::Order)
|
||||
}
|
||||
|
||||
/// Check for import multisig info, validate block time and that the
|
||||
///
|
||||
/// order wallet has been funded properly. Update the order to multisig complete
|
||||
pub async fn validate_order_for_ship(orid: &String) -> reqres::FinalizeOrderResponse {
|
||||
pub async fn validate_order_for_ship(
|
||||
orid: &String,
|
||||
) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
info!("validating order for shipment");
|
||||
let m_order: Order = find(orid);
|
||||
let contact: Contact = contact::find(&m_order.cid);
|
||||
let m_order: Order = find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let contact: Contact = contact::find(&m_order.cid).map_err(|_| NevekoError::Contact)?;
|
||||
let hex_nmpk: String = contact.nmpk;
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||
let delivery_info: String = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let mut j_order: Order = find(orid);
|
||||
let m_product: Product = product::find(&m_order.pid);
|
||||
let delivery_info = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let mut j_order: Order = find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let m_product: Product = product::find(&m_order.pid).map_err(|_| NevekoError::Product)?;
|
||||
let price = m_product.price;
|
||||
let total = price * &m_order.quantity;
|
||||
let wallet_password = utils::empty_string();
|
||||
monero::open_wallet(&orid, &wallet_password).await;
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
// check balance and unlock_time
|
||||
let r_balance = monero::get_balance().await;
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
// update the order status to multisig complete
|
||||
let ready_to_ship: bool = r_balance.result.balance >= total as u128
|
||||
&& r_balance.result.blocks_to_unlock < monero::LockTimeLimit::Blocks.value();
|
||||
if ready_to_ship {
|
||||
j_order.status = StatusType::Shipped.value();
|
||||
order::modify(Json(j_order));
|
||||
order::modify(Json(j_order))?;
|
||||
}
|
||||
let d_info: String = bincode::deserialize(&delivery_info[..]).unwrap_or_default();
|
||||
let e_delivery_info: String = neveko25519::cipher(
|
||||
&hex_nmpk,
|
||||
hex::encode(delivery_info),
|
||||
hex::encode(d_info),
|
||||
Some(String::from(neveko25519::ENCIPHER)),
|
||||
)
|
||||
.await;
|
||||
reqres::FinalizeOrderResponse {
|
||||
Ok(reqres::FinalizeOrderResponse {
|
||||
orid: String::from(orid),
|
||||
delivery_info: e_delivery_info,
|
||||
vendor_update_success: false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// NASR (neveko auto-ship request)
|
||||
|
@ -405,10 +452,10 @@ pub async fn trigger_nasr(
|
|||
pub async fn upload_delivery_info(
|
||||
orid: &String,
|
||||
delivery_info: &String,
|
||||
) -> reqres::FinalizeOrderResponse {
|
||||
) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
info!("uploading delivery info");
|
||||
let lookup: Order = order::find(orid);
|
||||
let contact: Contact = contact::find(&lookup.cid);
|
||||
let lookup: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let contact: Contact = contact::find(&lookup.cid).map_err(|_| NevekoError::Contact)?;
|
||||
let hex_nmpk: String = contact.nmpk;
|
||||
let e_delivery_info: String = neveko25519::cipher(
|
||||
&hex_nmpk,
|
||||
|
@ -420,43 +467,48 @@ pub async fn upload_delivery_info(
|
|||
error!("unable to encipher delivery info");
|
||||
}
|
||||
// get draft payment txset
|
||||
let wallet_password = utils::empty_string();
|
||||
monero::open_wallet(&orid, &wallet_password).await;
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
monero::refresh().await;
|
||||
let sweep: reqres::XmrRpcSweepAllResponse =
|
||||
monero::sweep_all(String::from(&lookup.subaddress)).await;
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
if sweep.result.multisig_txset.is_empty() {
|
||||
error!("unable to create draft txset");
|
||||
return Default::default();
|
||||
return Err(NevekoError::MoneroRpc);
|
||||
}
|
||||
// update the order
|
||||
let mut m_order: Order = find(orid);
|
||||
let mut m_order: Order = find(orid).map_err(|_| NevekoError::Order)?;
|
||||
m_order.status = StatusType::Shipped.value();
|
||||
m_order.ship_date = chrono::offset::Utc::now().timestamp();
|
||||
m_order.vend_msig_txset = sweep.result.multisig_txset;
|
||||
// delivery info will be stored enciphered and separate from the rest of the
|
||||
// order
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||
db::Interface::async_write(&s.env, &s.handle, &k, &hex::encode(&delivery_info)).await;
|
||||
modify(Json(m_order));
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), delivery_info.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
modify(Json(m_order))?;
|
||||
// trigger nasr, this will cause the customer's neveko instance to request the
|
||||
// txset
|
||||
let i2p_address = i2p::get_destination(None);
|
||||
let s = db::Interface::open();
|
||||
let i2p_address = i2p::get_destination(i2p::ServerTunnelType::App)?;
|
||||
// get jwp from db
|
||||
let db = &DATABASE_LOCK;
|
||||
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &lookup.cid);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let nasr_order = trigger_nasr(&lookup.cid, &i2p_address, &jwp, orid).await;
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let nasr_order = trigger_nasr(&lookup.cid, &i2p_address, &str_jwp, orid).await;
|
||||
if nasr_order.is_err() {
|
||||
return Default::default();
|
||||
error!("failed to trigger nasr");
|
||||
return Err(NevekoError::Nasr);
|
||||
}
|
||||
reqres::FinalizeOrderResponse {
|
||||
Ok(reqres::FinalizeOrderResponse {
|
||||
delivery_info: e_delivery_info,
|
||||
orid: String::from(orid),
|
||||
vendor_update_success: false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Vendor will very txset submission and then update the order to `Delivered`
|
||||
|
@ -464,16 +516,16 @@ pub async fn upload_delivery_info(
|
|||
/// status type. Then customer will update the status on the neveko instanced
|
||||
///
|
||||
/// upon a `vendor_update_success: true` response
|
||||
pub async fn finalize_order(orid: &String) -> reqres::FinalizeOrderResponse {
|
||||
pub async fn finalize_order(orid: &String) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
info!("finalizing order: {}", orid);
|
||||
// verify recipient and unlock time
|
||||
let mut m_order: Order = order::find(orid);
|
||||
if m_order.vend_msig_txset == utils::empty_string() {
|
||||
let mut m_order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
if m_order.vend_msig_txset.is_empty() {
|
||||
error!("txset missing");
|
||||
return Default::default();
|
||||
return Err(NevekoError::MoneroRpc);
|
||||
}
|
||||
// get draft payment txset
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
monero::refresh().await;
|
||||
let address: String = String::from(&m_order.subaddress);
|
||||
|
@ -489,22 +541,22 @@ pub async fn finalize_order(orid: &String) -> reqres::FinalizeOrderResponse {
|
|||
if !valid {
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
error!("invalid txset");
|
||||
return Default::default();
|
||||
return Err(NevekoError::MoneroRpc);
|
||||
}
|
||||
// verify order wallet has been swept clean
|
||||
let balance = monero::get_balance().await;
|
||||
if balance.result.unlocked_balance != 0 {
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
error!("order wallet not swept");
|
||||
return Default::default();
|
||||
return Err(NevekoError::MoneroRpc);
|
||||
}
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
m_order.status = order::StatusType::Delivered.value();
|
||||
order::modify(Json(m_order));
|
||||
reqres::FinalizeOrderResponse {
|
||||
order::modify(Json(m_order))?;
|
||||
Ok(reqres::FinalizeOrderResponse {
|
||||
vendor_update_success: true,
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes POST /order/finalize/{orid}
|
||||
|
@ -551,41 +603,44 @@ pub async fn trigger_finalize_request(
|
|||
contact: &String,
|
||||
jwp: &String,
|
||||
orid: &String,
|
||||
) -> reqres::FinalizeOrderResponse {
|
||||
) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
info!("executing trigger_finalize_request");
|
||||
let finalize = transmit_finalize_request(contact, jwp, orid).await;
|
||||
// cache finalize order request to db
|
||||
if finalize.is_err() {
|
||||
log::error!("failed to trigger cancel request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let unwrap: reqres::FinalizeOrderResponse = finalize.unwrap();
|
||||
let mut m_order: Order = order::find(&orid);
|
||||
let mut m_order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
m_order.status = order::StatusType::Delivered.value();
|
||||
backup(&m_order);
|
||||
unwrap
|
||||
backup(&m_order)?;
|
||||
Ok(unwrap)
|
||||
}
|
||||
|
||||
/// Decomposition trigger for `finalize_order()`
|
||||
pub async fn d_trigger_finalize_request(
|
||||
contact: &String,
|
||||
orid: &String,
|
||||
) -> reqres::FinalizeOrderResponse {
|
||||
) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
info!("executing d_trigger_finalize_request");
|
||||
// request finalize if the order status is shipped
|
||||
let order: Order = order::find(&orid);
|
||||
let order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
if order.status != order::StatusType::Shipped.value() {
|
||||
let trigger = trigger_finalize_request(contact, &jwp, orid).await;
|
||||
let trigger = trigger_finalize_request(contact, &str_jwp, orid).await?;
|
||||
if trigger.vendor_update_success {
|
||||
return trigger;
|
||||
return Ok(trigger);
|
||||
}
|
||||
}
|
||||
Default::default()
|
||||
Err(NevekoError::Order)
|
||||
}
|
||||
|
||||
/// Send order request to vendor and start multisig flow
|
||||
|
@ -693,7 +748,11 @@ pub async fn transmit_sor_request(
|
|||
/// A decomposition trigger for the shipping request so that the logic
|
||||
///
|
||||
/// can be executed from the gui.
|
||||
pub async fn trigger_ship_request(contact: &String, jwp: &String, orid: &String) -> Order {
|
||||
pub async fn trigger_ship_request(
|
||||
contact: &String,
|
||||
jwp: &String,
|
||||
orid: &String,
|
||||
) -> Result<Order, NevekoError> {
|
||||
info!("executing trigger_ship_request");
|
||||
let data = String::from(orid);
|
||||
let wallet_password =
|
||||
|
@ -705,17 +764,21 @@ pub async fn trigger_ship_request(contact: &String, jwp: &String, orid: &String)
|
|||
// cache order request to db
|
||||
if order.is_err() {
|
||||
log::error!("failed to trigger shipping request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let unwrap_order: Order = order.unwrap();
|
||||
backup(&unwrap_order);
|
||||
unwrap_order
|
||||
backup(&unwrap_order)?;
|
||||
Ok(unwrap_order)
|
||||
}
|
||||
|
||||
/// A post-decomposition trigger for the cancel request so that the logic
|
||||
///
|
||||
/// can be executed from the gui.
|
||||
pub async fn trigger_cancel_request(contact: &String, jwp: &String, orid: &String) -> Order {
|
||||
pub async fn trigger_cancel_request(
|
||||
contact: &String,
|
||||
jwp: &String,
|
||||
orid: &String,
|
||||
) -> Result<Order, NevekoError> {
|
||||
info!("executing trigger_cancel_request");
|
||||
let data = String::from(orid);
|
||||
let wallet_password =
|
||||
|
@ -727,35 +790,43 @@ pub async fn trigger_cancel_request(contact: &String, jwp: &String, orid: &Strin
|
|||
// cache order request to db
|
||||
if order.is_err() {
|
||||
log::error!("failed to trigger cancel request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let unwrap_order: Order = order.unwrap();
|
||||
backup(&unwrap_order);
|
||||
unwrap_order
|
||||
backup(&unwrap_order)?;
|
||||
Ok(unwrap_order)
|
||||
}
|
||||
|
||||
/// Decomposition trigger for the shipping request
|
||||
pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Order {
|
||||
pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Result<Order, NevekoError> {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
info!("executing d_trigger_ship_request");
|
||||
// request shipment if the order status is MultisigComplete
|
||||
let trigger = trigger_ship_request(contact, &jwp, orid).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let trigger = trigger_ship_request(contact, &str_jwp, orid).await?;
|
||||
if trigger.status == order::StatusType::MulitsigComplete.value() {
|
||||
let ship_res = transmit_ship_request(contact, &jwp, orid).await;
|
||||
let ship_res = transmit_ship_request(contact, &str_jwp, orid).await;
|
||||
if ship_res.is_err() {
|
||||
error!("failure to decompose trigger_ship_request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let u_ship_res = ship_res.unwrap_or(Default::default());
|
||||
let hex_delivery_info: String = hex::encode(u_ship_res.delivery_info);
|
||||
let key = format!("{}-{}", crate::DELIVERY_INFO_DB_KEY, orid);
|
||||
db::Interface::write(&s.env, &s.handle, &key, &hex_delivery_info);
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
key.as_bytes(),
|
||||
hex_delivery_info.as_bytes(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
trigger
|
||||
Ok(trigger)
|
||||
}
|
||||
|
||||
/// Executes POST /order/cancel/orid/signature
|
||||
|
@ -800,29 +871,34 @@ pub async fn transmit_cancel_request(
|
|||
}
|
||||
|
||||
/// Decomposition trigger for the cancel request
|
||||
pub async fn d_trigger_cancel_request(contact: &String, orid: &String) -> Order {
|
||||
pub async fn d_trigger_cancel_request(
|
||||
contact: &String,
|
||||
orid: &String,
|
||||
) -> Result<Order, NevekoError> {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let db = &DATABASE_LOCK;
|
||||
let jwp = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
info!("executing d_trigger_cancel_request");
|
||||
// request cancel if the order status is not MultisigComplete
|
||||
let order: Order = order::find(&orid);
|
||||
let order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
if order.status != order::StatusType::MulitsigComplete.value() {
|
||||
let trigger = trigger_cancel_request(contact, &jwp, orid).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let trigger = trigger_cancel_request(contact, &str_jwp, orid).await?;
|
||||
if trigger.status == order::StatusType::Cancelled.value() {
|
||||
return trigger;
|
||||
return Ok(trigger);
|
||||
}
|
||||
}
|
||||
Default::default()
|
||||
Err(NevekoError::Order)
|
||||
}
|
||||
|
||||
pub async fn init_adjudicator_wallet(orid: &String) {
|
||||
let password = utils::empty_string();
|
||||
let password = String::new();
|
||||
let m_wallet = monero::create_wallet(orid, &password).await;
|
||||
if !m_wallet {
|
||||
log::error!("failed to create adjudicator wallet");
|
||||
}
|
||||
monero::close_wallet(&orid, &password).await;
|
||||
monero::close_wallet(orid, &password).await;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
//! Marketplace products upload, modification, etc module
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
models::*,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -14,87 +19,101 @@ use rocket::serde::json::Json;
|
|||
use std::error::Error;
|
||||
|
||||
/// Create a new product
|
||||
pub fn create(d: Json<Product>) -> Product {
|
||||
pub fn create(d: Json<Product>) -> Result<Product, NevekoError> {
|
||||
let pid: String = format!("{}{}", crate::PRODUCT_DB_KEY, utils::generate_rnd());
|
||||
if !validate_product(&d) {
|
||||
error!("invalid product");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let new_product = Product {
|
||||
pid: String::from(&pid),
|
||||
description: String::from(&d.description),
|
||||
image: d.image.iter().cloned().collect(),
|
||||
image: d.image.to_vec(),
|
||||
in_stock: d.in_stock,
|
||||
name: String::from(&d.name),
|
||||
price: d.price,
|
||||
qty: d.qty,
|
||||
};
|
||||
debug!("insert product: {:?}", &new_product);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_product.pid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Product::to_db(&new_product));
|
||||
let product = bincode::serialize(&new_product).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &product)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all products, write keys to with pl
|
||||
let list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating product index");
|
||||
}
|
||||
let product_list = [r, String::from(&pid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let product_list = [old, String::from(&pid)].join(",");
|
||||
let s_product_list = bincode::serialize(&product_list).unwrap_or_default();
|
||||
debug!(
|
||||
"writing product index {} for id: {}",
|
||||
product_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &product_list);
|
||||
new_product
|
||||
db::write_chunks(&db.env, &db.handle, list_key.as_bytes(), &s_product_list)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(new_product)
|
||||
}
|
||||
|
||||
/// Single Product lookup
|
||||
pub fn find(pid: &String) -> Product {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(pid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(pid: &String) -> Result<Product, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &pid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("product not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
Product::from_db(String::from(pid), r)
|
||||
let result: Product = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Product lookup for all
|
||||
pub fn find_all() -> Vec<Product> {
|
||||
let i_s = db::Interface::open();
|
||||
pub fn find_all() -> Result<Vec<Product>, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let i_list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&db.env, &db.handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("product index not found");
|
||||
}
|
||||
let i_v_pid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_pid.map(|s| String::from(s)).collect();
|
||||
let str_r: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_pid = str_r.split(",");
|
||||
let i_v: Vec<String> = i_v_pid.map(String::from).collect();
|
||||
let mut products: Vec<Product> = Vec::new();
|
||||
for p in i_v {
|
||||
let mut product: Product = find(&p);
|
||||
if product.pid != utils::empty_string() {
|
||||
let mut product: Product = find(&p)?;
|
||||
if !product.pid.is_empty() {
|
||||
// don't return images
|
||||
product.image = Vec::new();
|
||||
products.push(product);
|
||||
}
|
||||
}
|
||||
products
|
||||
Ok(products)
|
||||
}
|
||||
|
||||
/// Modify product
|
||||
pub fn modify(p: Json<Product>) -> Product {
|
||||
pub fn modify(p: Json<Product>) -> Result<Product, NevekoError> {
|
||||
// TODO(c2m): don't allow modification to products with un-delivered orders
|
||||
info!("modify product: {}", &p.pid);
|
||||
let f_prod: Product = find(&p.pid);
|
||||
if f_prod.pid == utils::empty_string() {
|
||||
let f_prod: Product = find(&p.pid)?;
|
||||
if f_prod.pid.is_empty() {
|
||||
error!("product not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let u_prod = Product::update(f_prod, &p);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_prod.pid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_prod.pid, &Product::to_db(&u_prod));
|
||||
return u_prod;
|
||||
let db = &DATABASE_LOCK;
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, u_prod.pid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let product = bincode::serialize(&u_prod).unwrap_or_default();
|
||||
let db = &DATABASE_LOCK;
|
||||
db::write_chunks(&db.env, &db.handle, u_prod.pid.as_bytes(), &product)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(u_prod)
|
||||
}
|
||||
|
||||
/// check product field lengths to prevent db spam
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
//! External authorization module via JWPs
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
error::NevekoError,
|
||||
monero,
|
||||
reqres,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
error,
|
||||
info,
|
||||
|
@ -31,7 +36,7 @@ use serde::{
|
|||
use sha2::Sha512;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct TxProof {
|
||||
pub subaddress: String,
|
||||
pub confirmations: u64,
|
||||
|
@ -40,18 +45,6 @@ pub struct TxProof {
|
|||
pub signature: String,
|
||||
}
|
||||
|
||||
impl Default for TxProof {
|
||||
fn default() -> Self {
|
||||
TxProof {
|
||||
subaddress: utils::empty_string(),
|
||||
confirmations: 0,
|
||||
hash: utils::empty_string(),
|
||||
message: utils::empty_string(),
|
||||
signature: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide neccessary information for contacts to
|
||||
///
|
||||
/// provide proof of payment.
|
||||
|
@ -89,12 +82,12 @@ pub async fn create_jwp(proof: &TxProof) -> String {
|
|||
info!("creating jwp");
|
||||
// validate the proof
|
||||
let c_txp: TxProof = validate_proof(proof).await;
|
||||
if c_txp.hash == utils::empty_string() {
|
||||
if c_txp.hash.is_empty() {
|
||||
error!("invalid transaction proof");
|
||||
return utils::empty_string();
|
||||
return String::new();
|
||||
}
|
||||
let jwp_secret_key = utils::get_jwp_secret_key();
|
||||
let key: Hmac<Sha512> = Hmac::new_from_slice(&jwp_secret_key.as_bytes()).expect("hash");
|
||||
let jwp_secret_key = utils::get_jwp_secret_key().unwrap_or_default();
|
||||
let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("hash");
|
||||
let header = Header {
|
||||
algorithm: AlgorithmType::Hs512,
|
||||
..Default::default()
|
||||
|
@ -134,10 +127,16 @@ pub async fn prove_payment(contact: String, txp: &TxProof) -> Result<reqres::Jwp
|
|||
match res {
|
||||
Ok(r) => {
|
||||
// cache the jwp for for fts
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
db::Interface::write(&s.env, &s.handle, &k, &r.jwp);
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())?;
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&k.as_bytes(),
|
||||
&r.jwp.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(r)
|
||||
}
|
||||
_ => Ok(Default::default()),
|
||||
|
@ -192,8 +191,8 @@ impl<'r> FromRequest<'r> for PaymentProof {
|
|||
match proof {
|
||||
Some(proof) => {
|
||||
// check validity of address, payment amount and tx confirmations
|
||||
let jwp_secret_key = utils::get_jwp_secret_key();
|
||||
let key: Hmac<Sha512> = Hmac::new_from_slice(&jwp_secret_key.as_bytes()).expect("");
|
||||
let jwp_secret_key = utils::get_jwp_secret_key().unwrap_or_default();
|
||||
let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("");
|
||||
let jwp: Result<
|
||||
Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>,
|
||||
jwt::Error,
|
||||
|
@ -301,5 +300,5 @@ async fn validate_subaddress(subaddress: &String) -> bool {
|
|||
for s_address in all_address {
|
||||
address_list.push(s_address.address);
|
||||
}
|
||||
return address_list.contains(&subaddress);
|
||||
address_list.contains(subaddress)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,56 +2,45 @@
|
|||
//! authenticated user
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
models::*,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
info,
|
||||
};
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
/// Create a new user
|
||||
pub fn create(address: &String) -> User {
|
||||
pub fn create(address: &String) -> Result<User, MdbError> {
|
||||
let f_uid: String = format!("{}{}", crate::USER_DB_KEY, utils::generate_rnd());
|
||||
let new_user = User {
|
||||
uid: String::from(&f_uid),
|
||||
xmr_address: String::from(address),
|
||||
name: utils::empty_string(),
|
||||
name: String::new(),
|
||||
};
|
||||
debug!("insert user: {:?}", &new_user);
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = &new_user.uid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &User::to_db(&new_user));
|
||||
new_user
|
||||
let v = bincode::serialize(&new_user).unwrap_or_default();
|
||||
let _ = db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)?;
|
||||
Ok(new_user)
|
||||
}
|
||||
|
||||
/// User lookup
|
||||
pub fn find(uid: &String) -> User {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(uid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(uid: &String) -> Result<User, MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &uid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("user not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
User::from_db(String::from(uid), r)
|
||||
}
|
||||
|
||||
/// Modify user - not implemented
|
||||
fn _modify(u: Json<User>) -> User {
|
||||
info!("modify user: {}", u.uid);
|
||||
let f_cust: User = find(&u.uid);
|
||||
if f_cust.uid == utils::empty_string() {
|
||||
error!("user not found");
|
||||
return Default::default();
|
||||
}
|
||||
let u_user = User::update(f_cust, String::from(&u.name));
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_user.uid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_user.uid, &User::to_db(&u_user));
|
||||
todo!()
|
||||
let user: User = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
@ -59,42 +48,35 @@ fn _modify(u: Json<User>) -> User {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_test() {
|
||||
fn create_test() -> Result<(), MdbError> {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
let test_user = create(&address);
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &test_user.uid).await;
|
||||
let id = String::from(&test_user.uid);
|
||||
let cleanup_id = String::from(&test_user.uid);
|
||||
let expected_user = User::from_db(id, r);
|
||||
assert_eq!(test_user.xmr_address, expected_user.xmr_address);
|
||||
cleanup(&cleanup_id).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let test_user = create(&address)?;
|
||||
let db = &DATABASE_LOCK;
|
||||
let r =
|
||||
db::DatabaseEnvironment::read(&db.env, &db.handle, &test_user.uid.as_bytes().to_vec())?;
|
||||
let cleanup_id = String::from(&test_user.uid);
|
||||
let expected_user: User = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
assert_eq!(test_user.xmr_address, expected_user.xmr_address);
|
||||
cleanup(&cleanup_id)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
fn find_test() -> Result<(), MdbError> {
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
|
@ -103,13 +85,12 @@ mod tests {
|
|||
xmr_address: address,
|
||||
..Default::default()
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &User::to_db(&expected_user)).await;
|
||||
let actual_user: User = find(&String::from(k));
|
||||
assert_eq!(expected_user.xmr_address, actual_user.xmr_address);
|
||||
cleanup(&String::from(k)).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = bincode::serialize(&expected_user).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)?;
|
||||
let actual_user: User = find(&String::from(k))?;
|
||||
assert_eq!(expected_user.xmr_address, actual_user.xmr_address);
|
||||
cleanup(&String::from(k))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,24 @@
|
|||
use crate::{
|
||||
args,
|
||||
contact,
|
||||
db,
|
||||
db::{
|
||||
self,
|
||||
DATABASE_LOCK,
|
||||
},
|
||||
dispute,
|
||||
i2p,
|
||||
error::NevekoError,
|
||||
i2p::{
|
||||
self,
|
||||
ProxyStatus,
|
||||
},
|
||||
message,
|
||||
models,
|
||||
monero,
|
||||
neveko25519,
|
||||
reqres,
|
||||
utils,
|
||||
};
|
||||
use clap::Parser;
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -49,35 +56,13 @@ pub struct ContactStatus {
|
|||
impl Default for ContactStatus {
|
||||
fn default() -> Self {
|
||||
ContactStatus {
|
||||
exp: utils::empty_string(),
|
||||
h_exp: utils::empty_string(),
|
||||
i2p: utils::empty_string(),
|
||||
exp: String::new(),
|
||||
h_exp: String::new(),
|
||||
i2p: String::new(),
|
||||
is_vendor: false,
|
||||
jwp: utils::empty_string(),
|
||||
jwp: String::new(),
|
||||
nick: String::from("anon"),
|
||||
txp: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum for selecting hash validation
|
||||
#[derive(PartialEq)]
|
||||
enum ExternalSoftware {
|
||||
I2PZero,
|
||||
XMR,
|
||||
}
|
||||
|
||||
/// Handles the state for the installation manager popup
|
||||
pub struct Installations {
|
||||
pub xmr: bool,
|
||||
pub i2p_zero: bool,
|
||||
}
|
||||
|
||||
impl Default for Installations {
|
||||
fn default() -> Self {
|
||||
Installations {
|
||||
xmr: false,
|
||||
i2p_zero: false,
|
||||
txp: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,9 +73,6 @@ pub struct Connections {
|
|||
pub daemon_host: String,
|
||||
pub i2p_proxy_host: String,
|
||||
pub i2p_socks_host: String,
|
||||
/// path to manually created tunnels json
|
||||
pub i2p_tunnels_json: String,
|
||||
pub i2p_zero_dir: String,
|
||||
pub is_remote_node: bool,
|
||||
pub is_i2p_advanced: bool,
|
||||
pub mainnet: bool,
|
||||
|
@ -104,18 +86,16 @@ impl Default for Connections {
|
|||
fn default() -> Self {
|
||||
Connections {
|
||||
blockchain_dir: String::from("/home/user/.bitmonero"),
|
||||
daemon_host: String::from("http://127.0.0.1:38081"),
|
||||
i2p_proxy_host: String::from("http://127.0.0.1:4444"),
|
||||
i2p_socks_host: String::from("http://127.0.0.1:9051"),
|
||||
i2p_tunnels_json: String::from("/home/user/neveko/i2p-manual"),
|
||||
i2p_zero_dir: String::from("/home/user/i2p-zero-linux.v1.21"),
|
||||
daemon_host: String::from("http://127.0.0.1:18081"),
|
||||
i2p_proxy_host: String::from("http://127.0.0.1:4456"),
|
||||
i2p_socks_host: String::from("http://127.0.0.1:9056"),
|
||||
is_remote_node: false,
|
||||
is_i2p_advanced: false,
|
||||
mainnet: false,
|
||||
monero_location: String::from("/home/user/monero-x86_64-linux-gnu-v0.18.3.3"),
|
||||
mainnet: true,
|
||||
monero_location: String::from("/home/user/monero-x86_64-linux-gnu-v0.18.3.4"),
|
||||
rpc_credential: String::from("pass"),
|
||||
rpc_username: String::from("user"),
|
||||
rpc_host: String::from("http://127.0.0.1:38083"),
|
||||
rpc_host: String::from("http://127.0.0.1:18083"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,14 +156,10 @@ pub fn start_core(conn: &Connections) {
|
|||
&conn.rpc_username,
|
||||
"--monero-rpc-cred",
|
||||
&conn.rpc_credential,
|
||||
"--i2p-zero-dir",
|
||||
&conn.i2p_zero_dir,
|
||||
"-r",
|
||||
env,
|
||||
remote_node,
|
||||
i2p_advanced,
|
||||
"--i2p-tunnels-json",
|
||||
&conn.i2p_tunnels_json,
|
||||
"--i2p-proxy-host",
|
||||
&conn.i2p_proxy_host,
|
||||
"--i2p-socks-proxy-host",
|
||||
|
@ -191,16 +167,12 @@ pub fn start_core(conn: &Connections) {
|
|||
];
|
||||
if conn.is_i2p_advanced {
|
||||
// set the i2p proxy host for advanced user re-use
|
||||
std::env::set_var(crate::NEVEKO_I2P_PROXY_HOST, &conn.i2p_proxy_host.clone());
|
||||
std::env::set_var(
|
||||
crate::NEVEKO_I2P_TUNNELS_JSON,
|
||||
&conn.i2p_tunnels_json.clone(),
|
||||
);
|
||||
std::env::set_var(crate::NEVEKO_I2P_PROXY_HOST, conn.i2p_proxy_host.clone());
|
||||
std::env::set_var(crate::NEVEKO_I2P_ADVANCED_MODE, String::from("1"));
|
||||
}
|
||||
if conn.is_remote_node {
|
||||
std::env::set_var(crate::MONERO_DAEMON_HOST, &conn.daemon_host.clone());
|
||||
std::env::set_var(crate::MONERO_WALLET_RPC_HOST, &conn.rpc_host.clone());
|
||||
std::env::set_var(crate::MONERO_DAEMON_HOST, conn.daemon_host.clone());
|
||||
std::env::set_var(crate::MONERO_WALLET_RPC_HOST, conn.rpc_host.clone());
|
||||
std::env::set_var(crate::GUI_REMOTE_NODE, crate::GUI_SET_REMOTE_NODE)
|
||||
}
|
||||
let output = std::process::Command::new("./neveko")
|
||||
|
@ -230,11 +202,11 @@ pub fn generate_rnd() -> String {
|
|||
/// Helper for separation of dev and prod concerns
|
||||
pub fn get_release_env() -> ReleaseEnvironment {
|
||||
let args = args::Args::parse();
|
||||
let env = String::from(args.release_env);
|
||||
let env = args.release_env;
|
||||
if env == "prod" {
|
||||
return ReleaseEnvironment::Production;
|
||||
ReleaseEnvironment::Production
|
||||
} else {
|
||||
return ReleaseEnvironment::Development;
|
||||
ReleaseEnvironment::Development
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,8 +219,8 @@ pub fn get_app_port() -> u16 {
|
|||
/// i2p http proxy
|
||||
pub fn get_i2p_http_proxy() -> String {
|
||||
let args = args::Args::parse();
|
||||
let advanced_proxy = std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(empty_string());
|
||||
if advanced_proxy == empty_string() {
|
||||
let advanced_proxy = std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(String::new());
|
||||
if advanced_proxy.is_empty() {
|
||||
args.i2p_proxy_host
|
||||
} else {
|
||||
advanced_proxy
|
||||
|
@ -314,7 +286,7 @@ pub fn message_to_json(m: &models::Message) -> Json<models::Message> {
|
|||
let r_message: models::Message = models::Message {
|
||||
body: String::from(&m.body),
|
||||
mid: String::from(&m.mid),
|
||||
uid: utils::empty_string(),
|
||||
uid: String::new(),
|
||||
created: m.created,
|
||||
from: String::from(&m.from),
|
||||
to: String::from(&m.to),
|
||||
|
@ -327,7 +299,7 @@ pub fn product_to_json(m: &models::Product) -> Json<models::Product> {
|
|||
let r_product: models::Product = models::Product {
|
||||
pid: String::from(&m.pid),
|
||||
description: String::from(&m.description),
|
||||
image: m.image.iter().cloned().collect(),
|
||||
image: m.image.to_vec(),
|
||||
in_stock: m.in_stock,
|
||||
name: String::from(&m.name),
|
||||
price: m.price,
|
||||
|
@ -357,11 +329,6 @@ pub fn dispute_to_json(d: &models::Dispute) -> Json<models::Dispute> {
|
|||
Json(dispute)
|
||||
}
|
||||
|
||||
/// Instead of putting `String::from("")`
|
||||
pub fn empty_string() -> String {
|
||||
String::from("")
|
||||
}
|
||||
|
||||
// DoS prevention
|
||||
pub const fn string_limit() -> usize {
|
||||
512
|
||||
|
@ -418,87 +385,147 @@ async fn gen_app_wallet(password: &String) {
|
|||
}
|
||||
|
||||
/// Secret keys for signing internal/external auth tokens
|
||||
fn gen_signing_keys() {
|
||||
fn gen_signing_keys() -> Result<(), NevekoError> {
|
||||
info!("generating signing keys");
|
||||
let jwp = get_jwp_secret_key();
|
||||
let jwt = get_jwt_secret_key();
|
||||
let jwp = get_jwp_secret_key().unwrap_or_default();
|
||||
let jwt = get_jwt_secret_key().unwrap_or_default();
|
||||
// send to db
|
||||
let s = db::Interface::open();
|
||||
if jwp == utils::empty_string() {
|
||||
let rnd_jwp = generate_rnd();
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY, &rnd_jwp);
|
||||
if jwp.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let db = &DATABASE_LOCK;
|
||||
let h = hex::encode(data);
|
||||
let v = bincode::serialize(&h).unwrap_or_default();
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
crate::NEVEKO_JWP_SECRET_KEY.as_bytes(),
|
||||
&v,
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
if jwt == utils::empty_string() {
|
||||
let rnd_jwt = generate_rnd();
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY, &rnd_jwt);
|
||||
if jwt.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let db = &DATABASE_LOCK;
|
||||
let h = hex::encode(data);
|
||||
let v = bincode::serialize(&h).unwrap_or_default();
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
crate::NEVEKO_JWT_SECRET_KEY.as_bytes(),
|
||||
&v,
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// TODO(c2m): add a button to gui to call this
|
||||
///
|
||||
/// dont' forget to generate new keys as well
|
||||
pub fn revoke_signing_keys() {
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
db::Interface::delete(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
pub fn revoke_signing_keys() -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, crate::NEVEKO_JWT_SECRET_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let db = &DATABASE_LOCK;
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, crate::NEVEKO_JWP_SECRET_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_jwt_secret_key() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
if r == utils::empty_string() {
|
||||
pub fn get_jwt_secret_key() -> Result<String, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::NEVEKO_JWT_SECRET_KEY.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("JWT key not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::Panic));
|
||||
}
|
||||
r
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_jwp_secret_key() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
if r == utils::empty_string() {
|
||||
pub fn get_jwp_secret_key() -> Result<String, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::NEVEKO_JWP_SECRET_KEY.as_bytes().to_vec(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("JWP key not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
r
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Returns the hex encoded neveko message public key from LMDB
|
||||
pub fn get_nmpk() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_NMPK);
|
||||
if r == utils::empty_string() {
|
||||
pub fn get_nmpk() -> Result<String, NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r =
|
||||
db::DatabaseEnvironment::read(&db.env, &db.handle, &crate::NEVEKO_NMPK.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("neveko message public key not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Database(MdbError::Panic));
|
||||
}
|
||||
r
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn generate_nmpk() {
|
||||
async fn generate_nmpk() -> Result<(), NevekoError> {
|
||||
info!("generating neveko message public key");
|
||||
let nmpk: String = get_nmpk();
|
||||
let nmpk: String = get_nmpk().unwrap_or_default();
|
||||
// send to db
|
||||
let s = db::Interface::open();
|
||||
if nmpk == utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
if nmpk.is_empty() {
|
||||
let nmk: neveko25519::NevekoMessageKeys = neveko25519::generate_neveko_message_keys().await;
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_NMPK, &nmk.hex_nmpk);
|
||||
let v = bincode::serialize(&nmk.hex_nmpk).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, crate::NEVEKO_NMPK.as_bytes(), &v)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_i2p_status() -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = bincode::serialize(&ProxyStatus::Opening).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, crate::I2P_STATUS.as_bytes(), &v)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put all app pre-checks here
|
||||
pub async fn start_up() {
|
||||
pub async fn start_up() -> Result<(), NevekoError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
crate::NEVEKO_NMPK.as_bytes(),
|
||||
&Vec::new(),
|
||||
)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
|
||||
info!("neveko is starting up");
|
||||
let _ = reset_i2p_status()?;
|
||||
warn!("monero multisig is experimental and usage of neveko may lead to loss of funds");
|
||||
let args = args::Args::parse();
|
||||
if args.clear_fts {
|
||||
clear_fts();
|
||||
clear_fts()?;
|
||||
}
|
||||
if args.clear_disputes {
|
||||
clear_disputes();
|
||||
clear_disputes()?;
|
||||
}
|
||||
gen_signing_keys();
|
||||
gen_signing_keys()?;
|
||||
if !is_using_remote_node() {
|
||||
monero::start_daemon();
|
||||
let _ = monero::start_daemon();
|
||||
}
|
||||
create_wallet_dir();
|
||||
// wait for daemon for a bit
|
||||
|
@ -507,9 +534,8 @@ pub async fn start_up() {
|
|||
// wait for rpc server for a bit
|
||||
tokio::time::sleep(std::time::Duration::new(5, 0)).await;
|
||||
monero::check_rpc_connection().await;
|
||||
let mut wallet_password =
|
||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(empty_string());
|
||||
if wallet_password == empty_string() {
|
||||
let mut wallet_password = std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or_default();
|
||||
if wallet_password.is_empty() {
|
||||
print!(
|
||||
"MONERO_WALLET_PASSWORD not set, enter neveko wallet password for monero-wallet-rpc: "
|
||||
);
|
||||
|
@ -517,20 +543,39 @@ pub async fn start_up() {
|
|||
wallet_password = read_password().unwrap();
|
||||
std::env::set_var(crate::MONERO_WALLET_PASSWORD, &wallet_password);
|
||||
}
|
||||
generate_nmpk().await;
|
||||
let env: String = get_release_env().value();
|
||||
if !args.i2p_advanced {
|
||||
i2p::start().await;
|
||||
let i2p = i2p::start();
|
||||
if i2p.is_err() {
|
||||
panic!("failed to start i2p");
|
||||
}
|
||||
}
|
||||
gen_app_wallet(&wallet_password).await;
|
||||
// start async background tasks here
|
||||
{
|
||||
tokio::spawn(async {
|
||||
message::retry_fts().await;
|
||||
dispute::settle_dispute().await;
|
||||
tokio::spawn(async move {
|
||||
let _ = message::retry_fts().await;
|
||||
// wait for the i2p http proxy tunnel since remote nodes are forced over i2p
|
||||
if is_using_remote_node() {
|
||||
loop {
|
||||
let is_i2p_online = i2p::check_connection().await;
|
||||
let i2p_status = is_i2p_online.unwrap_or(ProxyStatus::Opening);
|
||||
if i2p_status == ProxyStatus::Opening {
|
||||
log::error!("i2p has not warmed up yet, check wrapper.log");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_secs(60));
|
||||
}
|
||||
}
|
||||
gen_app_wallet(&wallet_password).await;
|
||||
generate_nmpk()
|
||||
.await
|
||||
.unwrap_or_else(|_| log::debug!("unable to generate neveko message keys"));
|
||||
let _ = dispute::settle_dispute().await;
|
||||
});
|
||||
}
|
||||
info!("{} - neveko is online", env);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// TODO(?): get rid of this after implementing monero bindings
|
||||
|
@ -566,120 +611,33 @@ pub fn kill_child_processes(cm: bool) {
|
|||
/// We can restart fts from since it gets terminated when empty
|
||||
pub fn restart_retry_fts() {
|
||||
tokio::spawn(async move {
|
||||
message::retry_fts().await;
|
||||
let _ = message::retry_fts().await;
|
||||
});
|
||||
}
|
||||
|
||||
/// We can restart dispute auto-settle from since it gets terminated when empty
|
||||
pub fn restart_dispute_auto_settle() {
|
||||
tokio::spawn(async move {
|
||||
dispute::settle_dispute().await;
|
||||
let _ = dispute::settle_dispute().await;
|
||||
});
|
||||
}
|
||||
|
||||
/// Called on app startup if `--clear-fts` flag is passed.
|
||||
fn clear_fts() {
|
||||
fn clear_fts() -> Result<(), NevekoError> {
|
||||
info!("clear fts");
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::FTS_DB_KEY);
|
||||
let db = &DATABASE_LOCK;
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, crate::FTS_DB_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Called on app startup if `--clear-dispute` flag is passed.
|
||||
fn clear_disputes() {
|
||||
fn clear_disputes() -> Result<(), NevekoError> {
|
||||
info!("clear_disputes");
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::DISPUTE_LIST_DB_KEY);
|
||||
}
|
||||
|
||||
/// TODO(?): get rid of this after implementing monero bindings
|
||||
///
|
||||
/// Handle the request from user to additional software
|
||||
///
|
||||
/// from gui startup. Power users will most like install
|
||||
///
|
||||
/// software on their own. Note that software pull is over
|
||||
///
|
||||
/// clearnet. TODO(c2m): remove this after monero and i2pd
|
||||
///
|
||||
/// are completed.
|
||||
pub async fn install_software(installations: Installations) -> bool {
|
||||
let mut valid_i2p_zero_hash = true;
|
||||
let mut valid_xmr_hash = true;
|
||||
if installations.i2p_zero {
|
||||
info!("installing i2p-zero");
|
||||
let i2p_version = crate::I2P_ZERO_RELEASE_VERSION;
|
||||
let i2p_zero_zip = format!("i2p-zero-linux.{}.zip", i2p_version);
|
||||
let link = format!(
|
||||
"https://github.com/creating2morrow/i2p-zero/releases/download/{}-neveko/{}",
|
||||
i2p_version, i2p_zero_zip
|
||||
);
|
||||
let curl = std::process::Command::new("curl")
|
||||
.args(["-LO#", &link])
|
||||
.status();
|
||||
match curl {
|
||||
Ok(curl_output) => {
|
||||
debug!("{:?}", curl_output);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let unzip_output = std::process::Command::new("unzip")
|
||||
.arg(&i2p_zero_zip)
|
||||
.spawn()
|
||||
.expect("i2p unzip failed");
|
||||
debug!("{:?}", unzip_output.stdout);
|
||||
}
|
||||
_ => error!("i2p-zero download failed"),
|
||||
}
|
||||
valid_i2p_zero_hash = validate_installation_hash(ExternalSoftware::I2PZero, &i2p_zero_zip);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
if installations.xmr {
|
||||
info!("installing monero");
|
||||
let link = format!(
|
||||
"https://downloads.getmonero.org/cli/{}",
|
||||
crate::MONERO_RELEASE_VERSION
|
||||
);
|
||||
let curl = std::process::Command::new("curl")
|
||||
.args(["-O#", &link])
|
||||
.status();
|
||||
match curl {
|
||||
Ok(curl_output) => {
|
||||
debug!("{:?}", curl_output);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let tar_output = std::process::Command::new("tar")
|
||||
.args(["-xvf", crate::MONERO_RELEASE_VERSION])
|
||||
.spawn()
|
||||
.expect("monero tar extraction failed");
|
||||
debug!("{:?}", tar_output.stdout);
|
||||
}
|
||||
_ => error!("monero download failed"),
|
||||
}
|
||||
valid_xmr_hash = validate_installation_hash(
|
||||
ExternalSoftware::XMR,
|
||||
&String::from(crate::MONERO_RELEASE_VERSION),
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
valid_i2p_zero_hash && valid_xmr_hash
|
||||
}
|
||||
|
||||
/// Linux specific hash validation using the command `sha256sum`
|
||||
fn validate_installation_hash(sw: ExternalSoftware, filename: &String) -> bool {
|
||||
debug!("validating hash");
|
||||
let expected_hash = if sw == ExternalSoftware::I2PZero {
|
||||
String::from(crate::I2P_ZERO_RELEASH_HASH)
|
||||
} else {
|
||||
String::from(crate::MONERO_RELEASE_HASH)
|
||||
};
|
||||
let sha_output = std::process::Command::new("sha256sum")
|
||||
.arg(filename)
|
||||
.output()
|
||||
.expect("hash validation failed");
|
||||
let str_sha = String::from_utf8(sha_output.stdout).unwrap();
|
||||
let split1 = str_sha.split(" ");
|
||||
let mut v: Vec<String> = split1.map(|s| String::from(s)).collect();
|
||||
let actual_hash = v.remove(0);
|
||||
debug!("actual hash: {}", actual_hash);
|
||||
debug!("expected hash: {}", expected_hash);
|
||||
actual_hash == expected_hash
|
||||
let db = &DATABASE_LOCK;
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, crate::DISPUTE_LIST_DB_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ### The highly ineffecient fee estimator.
|
||||
|
@ -707,8 +665,8 @@ pub async fn estimate_fee() -> u128 {
|
|||
let mut count: u64 = 1;
|
||||
let mut v_fee: Vec<u128> = Vec::new();
|
||||
let mut r_height: reqres::XmrDaemonGetHeightResponse = Default::default();
|
||||
let remote_var = std::env::var(crate::GUI_REMOTE_NODE).unwrap_or(utils::empty_string());
|
||||
let remote_set = remote_var == String::from(crate::GUI_SET_REMOTE_NODE);
|
||||
let remote_var = std::env::var(crate::GUI_REMOTE_NODE).unwrap_or(String::new());
|
||||
let remote_set = remote_var == *crate::GUI_SET_REMOTE_NODE;
|
||||
if remote_set {
|
||||
let p_height = monero::p_get_height().await;
|
||||
r_height = p_height.unwrap_or(r_height);
|
||||
|
@ -726,12 +684,12 @@ pub async fn estimate_fee() -> u128 {
|
|||
}
|
||||
// TODO(?): determine a more effecient fix than this for slow fee estimation
|
||||
// over i2p
|
||||
if v_fee.len() >= 1 && remote_set {
|
||||
if !v_fee.is_empty() && remote_set {
|
||||
break;
|
||||
}
|
||||
height = r_height.height - count;
|
||||
let mut block: reqres::XmrDaemonGetBlockResponse = Default::default();
|
||||
if remote_var == String::from(crate::GUI_SET_REMOTE_NODE) {
|
||||
if remote_var == *crate::GUI_SET_REMOTE_NODE {
|
||||
let p_block = monero::p_get_block(height).await;
|
||||
block = p_block.unwrap_or(block);
|
||||
} else {
|
||||
|
@ -748,10 +706,10 @@ pub async fn estimate_fee() -> u128 {
|
|||
}
|
||||
for tx in transactions.txs_as_json {
|
||||
let pre_fee_split = tx.split("txnFee\":");
|
||||
let mut v1: Vec<String> = pre_fee_split.map(|s| String::from(s)).collect();
|
||||
let mut v1: Vec<String> = pre_fee_split.map(String::from).collect();
|
||||
let fee_split = v1.remove(1);
|
||||
let post_fee_split = fee_split.split(",");
|
||||
let mut v2: Vec<String> = post_fee_split.map(|s| String::from(s)).collect();
|
||||
let mut v2: Vec<String> = post_fee_split.map(String::from).collect();
|
||||
let fee: u128 = match v2.remove(0).trim().parse::<u128>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => 0,
|
||||
|
@ -785,47 +743,58 @@ pub async fn can_transfer(invoice: u128) -> bool {
|
|||
}
|
||||
|
||||
/// Gui toggle for vendor mode
|
||||
pub fn toggle_vendor_enabled() -> bool {
|
||||
pub fn toggle_vendor_enabled() -> Result<bool, MdbError> {
|
||||
// TODO(c2m): Dont toggle vendors with orders status != Delivered
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED);
|
||||
if r != contact::NEVEKO_VENDOR_MODE_ON {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&contact::NEVEKO_VENDOR_ENABLED.as_bytes().to_vec(),
|
||||
)?;
|
||||
let mode: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
if mode != contact::NEVEKO_VENDOR_MODE_ON {
|
||||
info!("neveko vendor mode enabled");
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED,
|
||||
contact::NEVEKO_VENDOR_MODE_ON,
|
||||
);
|
||||
return true;
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
|
||||
contact::NEVEKO_VENDOR_MODE_ON.as_bytes(),
|
||||
)?;
|
||||
Ok(true)
|
||||
} else {
|
||||
info!("neveko vendor mode disabled");
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED,
|
||||
contact::NEVEKO_VENDOR_MODE_OFF,
|
||||
);
|
||||
return false;
|
||||
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
|
||||
contact::NEVEKO_VENDOR_MODE_OFF.as_bytes(),
|
||||
)?;
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search_gui_db(f: String, data: String) -> String {
|
||||
let s = db::Interface::open();
|
||||
pub fn search_gui_db(f: String, data: String) -> Result<String, MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", f, data);
|
||||
db::Interface::read(&s.env, &s.handle, &k)
|
||||
let r = db::DatabaseEnvironment::read(&db.env, &db.handle, &k.as_bytes().to_vec())?;
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn write_gui_db(f: String, key: String, data: String) {
|
||||
let s = db::Interface::open();
|
||||
pub fn write_gui_db(f: String, key: String, data: String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", f, key);
|
||||
db::Interface::write(&s.env, &s.handle, &k, &data);
|
||||
let v = bincode::serialize(&data).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear_gui_db(f: String, key: String) {
|
||||
let s = db::Interface::open();
|
||||
pub fn clear_gui_db(f: String, key: String) -> Result<(), MdbError> {
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = format!("{}-{}", f, key);
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
@ -853,7 +822,7 @@ mod tests {
|
|||
#[test]
|
||||
fn release_env_test() {
|
||||
let actual = get_release_env();
|
||||
let expected = ReleaseEnvironment::Development;
|
||||
let expected = ReleaseEnvironment::Production;
|
||||
assert_eq!(expected, actual)
|
||||
}
|
||||
|
||||
|
|
28
neveko-gui/.gitignore
vendored
28
neveko-gui/.gitignore
vendored
|
@ -2,4 +2,30 @@
|
|||
/core
|
||||
notes.txt
|
||||
.env
|
||||
neveko
|
||||
neveko
|
||||
*.ping
|
||||
/wallet
|
||||
/.build
|
||||
genkey-batch
|
||||
monero-wallet-rpc.log
|
||||
notes.txt
|
||||
.vscode/settings.json
|
||||
*.bz2
|
||||
*.zip
|
||||
monero-x86_64-linux-gnu-v*/
|
||||
*.jar
|
||||
opt/*
|
||||
*.so
|
||||
*.config
|
||||
*.log
|
||||
*.key
|
||||
router.info
|
||||
router.keys.dat
|
||||
prngseed.rnd
|
||||
hostsdb.blockfile
|
||||
certificates/
|
||||
netDb/*
|
||||
peerProfiles/*
|
||||
*.dat
|
||||
*.txt
|
||||
*.txt.gz
|
597
neveko-gui/Cargo.lock
generated
597
neveko-gui/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@ wgpu = ["eframe/wgpu", "bytemuck"]
|
|||
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
chrono = { version = "0.4", features = ["js-sys", "wasmbind"] }
|
||||
eframe = { version = "0.21.0", path = "./crates/eframe", default-features = false }
|
||||
egui = { version = "0.21.0", path = "./crates/egui", features = [
|
||||
|
|
|
@ -13,7 +13,7 @@ use egui_winit::winit;
|
|||
|
||||
use crate::{epi, Result};
|
||||
|
||||
use super::epi_integration::{self, EpiIntegration};
|
||||
use super::epi_integration::{self};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -58,10 +58,6 @@ enum EventResult {
|
|||
}
|
||||
|
||||
trait WinitApp {
|
||||
fn is_focused(&self) -> bool;
|
||||
|
||||
fn integration(&self) -> Option<&EpiIntegration>;
|
||||
|
||||
fn window(&self) -> Option<&winit::window::Window>;
|
||||
|
||||
fn save_and_destroy(&mut self);
|
||||
|
@ -736,14 +732,6 @@ mod glow_integration {
|
|||
}
|
||||
|
||||
impl WinitApp for GlowWinitApp {
|
||||
fn is_focused(&self) -> bool {
|
||||
self.is_focused
|
||||
}
|
||||
|
||||
fn integration(&self) -> Option<&EpiIntegration> {
|
||||
self.running.as_ref().map(|r| &r.integration)
|
||||
}
|
||||
|
||||
fn window(&self) -> Option<&winit::window::Window> {
|
||||
self.running.as_ref().map(|r| r.gl_window.window())
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct WindowSettings {
|
|||
impl WindowSettings {
|
||||
pub fn from_display(window: &winit::window::Window) -> Self {
|
||||
let inner_size_points = window.inner_size().to_logical::<f32>(window.scale_factor());
|
||||
let position = if cfg!(macos) {
|
||||
let position = if cfg!(unix) || cfg!(windows) {
|
||||
// MacOS uses inner position when positioning windows.
|
||||
window
|
||||
.inner_position()
|
||||
|
|
|
@ -217,8 +217,6 @@ impl TextureAtlas {
|
|||
if required_height > self.max_height() {
|
||||
// This is a bad place to be - we need to start reusing space :/
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
tracing::wan!("epaint texture atlas overflowed!");
|
||||
|
||||
self.cursor = (0, self.image.height() / 3); // Restart a bit down - the top of the atlas has too many important things in it
|
||||
self.overflowed = true; // this will signal the user that we need to recreate the texture atlas next frame.
|
||||
|
|
|
@ -18,8 +18,8 @@ struct Compose {
|
|||
impl Default for Compose {
|
||||
fn default() -> Self {
|
||||
Compose {
|
||||
message: utils::empty_string(),
|
||||
to: utils::empty_string(),
|
||||
message: String::new(),
|
||||
to: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ impl Default for AddressBookApp {
|
|||
let (payment_tx, payment_rx) = std::sync::mpsc::channel();
|
||||
let (send_message_tx, send_message_rx) = std::sync::mpsc::channel();
|
||||
AddressBookApp {
|
||||
add_nick: utils::empty_string(),
|
||||
add_nick: String::new(),
|
||||
approve_contact: false,
|
||||
approve_payment: false,
|
||||
added: false,
|
||||
|
@ -94,7 +94,7 @@ impl Default for AddressBookApp {
|
|||
can_transfer_rx,
|
||||
can_transfer_tx,
|
||||
compose: Default::default(),
|
||||
contact: utils::empty_string(),
|
||||
contact: String::new(),
|
||||
contacts: Vec::new(),
|
||||
contacts_init: false,
|
||||
contact_add_tx,
|
||||
|
@ -103,7 +103,7 @@ impl Default for AddressBookApp {
|
|||
contact_info_rx,
|
||||
contact_timeout_tx,
|
||||
contact_timeout_rx,
|
||||
find_contact: utils::empty_string(),
|
||||
find_contact: String::new(),
|
||||
invoice_tx,
|
||||
invoice_rx,
|
||||
is_adding: false,
|
||||
|
@ -134,7 +134,7 @@ impl eframe::App for AddressBookApp {
|
|||
//-----------------------------------------------------------------------------------
|
||||
if let Ok(contact_info) = self.contact_info_rx.try_recv() {
|
||||
self.s_contact = contact_info;
|
||||
if self.s_contact.xmr_address != utils::empty_string() && !self.showing_status {
|
||||
if !self.s_contact.xmr_address.is_empty() && !self.showing_status {
|
||||
self.approve_contact = true;
|
||||
}
|
||||
if self.showing_status {
|
||||
|
@ -144,7 +144,7 @@ impl eframe::App for AddressBookApp {
|
|||
|
||||
if let Ok(added_contact) = self.contact_add_rx.try_recv() {
|
||||
self.s_added_contact = added_contact;
|
||||
if self.s_added_contact.cid != utils::empty_string() {
|
||||
if !self.s_added_contact.cid.is_empty() {
|
||||
self.added = true;
|
||||
self.is_loading = false;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ impl eframe::App for AddressBookApp {
|
|||
self.is_loading = false;
|
||||
self.is_adding = false;
|
||||
self.approve_contact = false;
|
||||
self.contact = utils::empty_string();
|
||||
self.contact = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ impl eframe::App for AddressBookApp {
|
|||
if self.is_message_sent {
|
||||
self.is_loading = false;
|
||||
self.is_composing = false;
|
||||
self.compose.message = utils::empty_string();
|
||||
self.compose.message = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ impl eframe::App for AddressBookApp {
|
|||
|
||||
// initial contact load
|
||||
if !self.contacts_init {
|
||||
self.contacts = contact::find_all();
|
||||
self.contacts = contact::find_all().unwrap_or_default();
|
||||
self.contacts_init = true;
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ impl eframe::App for AddressBookApp {
|
|||
});
|
||||
if !self.is_loading {
|
||||
self.compose.to = self.status.i2p.clone();
|
||||
if self.status.jwp != utils::empty_string() {
|
||||
if !self.status.jwp.is_empty() {
|
||||
if ui.button("Send").clicked() {
|
||||
self.is_loading = true;
|
||||
send_message_req(
|
||||
|
@ -242,8 +242,7 @@ impl eframe::App for AddressBookApp {
|
|||
|
||||
// Payment approval window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_approving_payment =
|
||||
self.approve_payment && self.s_invoice.address != utils::empty_string();
|
||||
let mut is_approving_payment = self.approve_payment && !self.s_invoice.address.is_empty();
|
||||
let address = self.s_invoice.address.clone();
|
||||
let amount = self.s_invoice.pay_threshold;
|
||||
let expire = self.s_invoice.conf_threshold;
|
||||
|
@ -265,7 +264,7 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("pay to: {}", address));
|
||||
ui.label(format!("amount: {} piconero(s)", amount));
|
||||
ui.label(format!("expiration: {} blocks", expire));
|
||||
let show_approve = self.s_invoice.address != utils::empty_string()
|
||||
let show_approve = !self.s_invoice.address.is_empty()
|
||||
&& self.can_transfer
|
||||
&& !self.is_estimating_fee;
|
||||
if !self.is_loading {
|
||||
|
@ -316,7 +315,7 @@ impl eframe::App for AddressBookApp {
|
|||
ui.add(egui::Spinner::new());
|
||||
ui.label(spinner_text);
|
||||
}
|
||||
let status = if self.s_contact.xmr_address != utils::empty_string() {
|
||||
let status = if !self.s_contact.xmr_address.is_empty() {
|
||||
"online"
|
||||
} else {
|
||||
"offline"
|
||||
|
@ -326,10 +325,10 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("tx proof: {}", self.status.txp));
|
||||
ui.label(format!("jwp: {}", self.status.jwp));
|
||||
ui.label(format!("expiration: {}", self.status.h_exp));
|
||||
if self.status.jwp == utils::empty_string()
|
||||
if self.status.jwp.is_empty()
|
||||
&& !self.is_pinging
|
||||
&& status == "online"
|
||||
&& self.status.txp == utils::empty_string()
|
||||
&& self.status.txp.is_empty()
|
||||
{
|
||||
if ui.button("Create JWP").clicked() {
|
||||
self.s_invoice = Default::default();
|
||||
|
@ -343,20 +342,19 @@ impl eframe::App for AddressBookApp {
|
|||
self.is_approving_jwp = true;
|
||||
}
|
||||
}
|
||||
let failed_to_prove = self.status.txp != utils::empty_string()
|
||||
&& self.status.jwp == utils::empty_string();
|
||||
if self.status.jwp != utils::empty_string() || failed_to_prove {
|
||||
let failed_to_prove = !self.status.txp.is_empty() && self.status.jwp.is_empty();
|
||||
if !self.status.jwp.is_empty() || failed_to_prove {
|
||||
if ui.button("Clear stale JWP").clicked() {
|
||||
utils::clear_gui_db(String::from("gui-txp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-jwp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-exp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-txp"), self.status.i2p.clone())
|
||||
.unwrap();
|
||||
utils::clear_gui_db(String::from("gui-jwp"), self.status.i2p.clone())
|
||||
.unwrap();
|
||||
utils::clear_gui_db(String::from("gui-exp"), self.status.i2p.clone())
|
||||
.unwrap();
|
||||
self.showing_status = false;
|
||||
}
|
||||
}
|
||||
if self.status.txp != utils::empty_string()
|
||||
&& self.status.jwp == utils::empty_string()
|
||||
&& status == "online"
|
||||
{
|
||||
if !self.status.txp.is_empty() && self.status.jwp.is_empty() && status == "online" {
|
||||
if ui.button("Prove Retry").clicked() {
|
||||
send_payment_req(
|
||||
self.payment_tx.clone(),
|
||||
|
@ -376,7 +374,7 @@ impl eframe::App for AddressBookApp {
|
|||
});
|
||||
if ui.button("Change nick").clicked() {
|
||||
change_nick_req(self.status.i2p.clone(), self.add_nick.clone());
|
||||
self.add_nick = utils::empty_string();
|
||||
self.add_nick = String::new();
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.showing_status = false;
|
||||
|
@ -419,10 +417,10 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("i2p address: {}", self.s_added_contact.i2p_address));
|
||||
if ui.button("Exit").clicked() {
|
||||
self.added = false;
|
||||
self.contact = utils::empty_string();
|
||||
self.contact = String::new();
|
||||
self.is_adding = false;
|
||||
self.approve_contact = false;
|
||||
self.contacts = contact::find_all();
|
||||
self.contacts = contact::find_all().unwrap_or_default();
|
||||
for c in &self.contacts {
|
||||
ui.label(format!("{}", c.i2p_address));
|
||||
}
|
||||
|
@ -541,10 +539,11 @@ impl eframe::App for AddressBookApp {
|
|||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
let nick = if nick_db == utils::empty_string() {
|
||||
let u_nick = nick_db.unwrap_or_default();
|
||||
let nick = if u_nick.is_empty() {
|
||||
String::from("anon")
|
||||
} else {
|
||||
nick_db
|
||||
u_nick
|
||||
};
|
||||
self.status.nick = nick;
|
||||
self.status.i2p = String::from(&c.i2p_address);
|
||||
|
@ -552,16 +551,19 @@ impl eframe::App for AddressBookApp {
|
|||
self.status.txp = utils::search_gui_db(
|
||||
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
)
|
||||
.unwrap_or_default();
|
||||
// get the jwp
|
||||
self.status.jwp = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let r_exp = utils::search_gui_db(
|
||||
String::from(crate::GUI_EXP_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
)
|
||||
.unwrap_or_default();
|
||||
self.status.exp = r_exp;
|
||||
let expire = match self.status.exp.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
|
@ -587,7 +589,7 @@ impl eframe::App for AddressBookApp {
|
|||
Err(_e) => 0,
|
||||
};
|
||||
if now < expire
|
||||
&& self.status.jwp != utils::empty_string()
|
||||
&& !self.status.jwp.is_empty()
|
||||
&& c.i2p_address == self.status.i2p
|
||||
{
|
||||
if ui.button("Compose").clicked() {
|
||||
|
@ -622,8 +624,8 @@ fn send_create_contact_req(tx: Sender<models::Contact>, ctx: egui::Context, c: m
|
|||
log::debug!("async send_create_contact_req");
|
||||
tokio::spawn(async move {
|
||||
let j_contact = utils::contact_to_json(&c);
|
||||
let a_contact: models::Contact = contact::create(&j_contact).await;
|
||||
let _ = tx.send(a_contact);
|
||||
let a_contact = contact::create(&j_contact).await;
|
||||
let _ = tx.send(a_contact.unwrap_or_default());
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
@ -662,9 +664,9 @@ fn send_payment_req(
|
|||
log::debug!("cleaning stale jwp values");
|
||||
tokio::spawn(async move {
|
||||
if !retry {
|
||||
utils::clear_gui_db(String::from("gui-txp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-jwp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-exp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-txp"), String::from(&contact)).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-jwp"), String::from(&contact)).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-exp"), String::from(&contact)).unwrap();
|
||||
let ptxp_address = String::from(&d.address);
|
||||
let ftxp_address = String::from(&d.address);
|
||||
log::debug!("sending {} piconero(s) to: {}", &d.amount, &d.address);
|
||||
|
@ -683,14 +685,13 @@ fn send_payment_req(
|
|||
subaddress: ptxp_address,
|
||||
confirmations: 0,
|
||||
hash: ptxp_hash,
|
||||
message: utils::empty_string(),
|
||||
signature: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature: String::new(),
|
||||
};
|
||||
log::debug!("creating transaction proof for: {}", &ptxp.hash);
|
||||
// if we made it this far we can now request a JWP from our friend
|
||||
// wait a bit for the tx to propogate, i2p takes longer
|
||||
let wait = if std::env::var(neveko_core::GUI_REMOTE_NODE)
|
||||
.unwrap_or(utils::empty_string())
|
||||
let wait = if std::env::var(neveko_core::GUI_REMOTE_NODE).unwrap_or(String::new())
|
||||
== String::from(neveko_core::GUI_SET_REMOTE_NODE)
|
||||
{
|
||||
crate::I2P_PROPAGATION_TIME_IN_SECS_EST
|
||||
|
@ -705,29 +706,33 @@ fn send_payment_req(
|
|||
subaddress: ftxp_address,
|
||||
confirmations: 0,
|
||||
hash: ftxp_hash,
|
||||
message: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature: get_txp.result.signature,
|
||||
};
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.signature),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_HASH_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.hash),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_SIGNATURE_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.signature),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_SUBADDRESS_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.subaddress),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
log::debug!(
|
||||
"proving payment to {} for: {}",
|
||||
String::from(&contact),
|
||||
|
@ -739,7 +744,8 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&result.jwp),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
// this is just an estimate expiration but should suffice
|
||||
let seconds: i64 = expire as i64 * 2 * 60;
|
||||
let unix: i64 = chrono::offset::Utc::now().timestamp() + seconds;
|
||||
|
@ -747,7 +753,8 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_EXP_DB_KEY),
|
||||
String::from(&contact),
|
||||
format!("{}", unix),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
ctx.request_repaint();
|
||||
}
|
||||
_ => log::error!("failed to obtain jwp"),
|
||||
|
@ -758,14 +765,15 @@ fn send_payment_req(
|
|||
let k_hash = String::from(crate::GUI_TX_HASH_DB_KEY);
|
||||
let k_sig = String::from(crate::GUI_TX_SIGNATURE_DB_KEY);
|
||||
let k_subaddress = String::from(crate::GUI_TX_SUBADDRESS_DB_KEY);
|
||||
let hash = utils::search_gui_db(k_hash, String::from(&contact));
|
||||
let signature = utils::search_gui_db(k_sig, String::from(&contact));
|
||||
let subaddress = utils::search_gui_db(k_subaddress, String::from(&contact));
|
||||
let hash = utils::search_gui_db(k_hash, String::from(&contact)).unwrap_or_default();
|
||||
let signature = utils::search_gui_db(k_sig, String::from(&contact)).unwrap_or_default();
|
||||
let subaddress =
|
||||
utils::search_gui_db(k_subaddress, String::from(&contact)).unwrap_or_default();
|
||||
let ftxp: proof::TxProof = proof::TxProof {
|
||||
subaddress,
|
||||
confirmations: 0,
|
||||
hash: String::from(&hash),
|
||||
message: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature,
|
||||
};
|
||||
log::debug!(
|
||||
|
@ -779,7 +787,8 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&result.jwp),
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
ctx.request_repaint();
|
||||
}
|
||||
_ => log::error!("failed to obtain jwp"),
|
||||
|
@ -795,17 +804,18 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
let m: models::Message = models::Message {
|
||||
body: body,
|
||||
to,
|
||||
mid: utils::empty_string(),
|
||||
uid: utils::empty_string(),
|
||||
mid: String::new(),
|
||||
uid: String::new(),
|
||||
created: 0,
|
||||
from: i2p::get_destination(None),
|
||||
from: i2p::get_destination(i2p::ServerTunnelType::App).unwrap_or_default(),
|
||||
};
|
||||
let j_message = utils::message_to_json(&m);
|
||||
tokio::spawn(async move {
|
||||
let m_type = message::MessageType::Normal;
|
||||
let result = message::create(j_message, jwp, m_type).await;
|
||||
if result.mid != utils::empty_string() {
|
||||
log::info!("sent message: {}", result.mid);
|
||||
let u_res = result.unwrap_or_default();
|
||||
if !u_res.mid.is_empty() {
|
||||
log::info!("sent message: {}", u_res.mid);
|
||||
let _ = tx.send(true);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
|
@ -814,12 +824,13 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
|
||||
fn change_nick_req(contact: String, nick: String) {
|
||||
log::debug!("change nick");
|
||||
utils::clear_gui_db(String::from(crate::GUI_NICK_DB_KEY), String::from(&contact));
|
||||
utils::clear_gui_db(String::from(crate::GUI_NICK_DB_KEY), String::from(&contact)).unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&contact),
|
||||
nick,
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn send_can_transfer_req(tx: Sender<bool>, ctx: egui::Context, invoice: u128) {
|
||||
|
|
|
@ -18,16 +18,13 @@ use std::{
|
|||
};
|
||||
|
||||
pub struct HomeApp {
|
||||
b32_destination: String,
|
||||
/// blocks fetched during last wallet refresh
|
||||
blocks_fetched: u64,
|
||||
wallet_height: u64,
|
||||
connections: utils::Connections,
|
||||
core_timeout_tx: Sender<bool>,
|
||||
core_timeout_rx: Receiver<bool>,
|
||||
has_install_failed: bool,
|
||||
installations: utils::Installations,
|
||||
installation_tx: Sender<bool>,
|
||||
installation_rx: Receiver<bool>,
|
||||
is_core_running: bool,
|
||||
is_editing_connections: bool,
|
||||
is_init: bool,
|
||||
|
@ -69,10 +66,10 @@ pub struct HomeApp {
|
|||
|
||||
impl Default for HomeApp {
|
||||
fn default() -> Self {
|
||||
let b32_destination = i2p::get_destination(i2p::ServerTunnelType::App)
|
||||
.unwrap_or(String::from("error: b32 address not found."));
|
||||
let blocks_fetched = 0;
|
||||
let connections = Default::default();
|
||||
let has_install_failed = false;
|
||||
let installations = Default::default();
|
||||
let is_core_running = false;
|
||||
let is_editing_connections = false;
|
||||
let is_init = true;
|
||||
|
@ -91,7 +88,6 @@ impl Default for HomeApp {
|
|||
let (wallet_height_tx, wallet_height_rx) = std::sync::mpsc::channel();
|
||||
let (can_refresh_tx, can_refresh_rx) = std::sync::mpsc::channel();
|
||||
let (i2p_status_tx, i2p_status_rx) = std::sync::mpsc::channel();
|
||||
let (installation_tx, installation_rx) = std::sync::mpsc::channel();
|
||||
let contents = std::fs::read("./assets/qr.png").unwrap_or(Vec::new());
|
||||
let s_xmr_rpc_ver = Default::default();
|
||||
let s_xmr_address = Default::default();
|
||||
|
@ -107,14 +103,11 @@ impl Default for HomeApp {
|
|||
egui_extras::RetainedImage::from_image_bytes("./assets/i2p.png", &c_i2p_logo).unwrap();
|
||||
let wallet_height = 0;
|
||||
Self {
|
||||
b32_destination,
|
||||
blocks_fetched,
|
||||
connections,
|
||||
core_timeout_rx,
|
||||
core_timeout_tx,
|
||||
has_install_failed,
|
||||
installations,
|
||||
installation_rx,
|
||||
installation_tx,
|
||||
is_core_running,
|
||||
is_editing_connections,
|
||||
is_init,
|
||||
|
@ -183,13 +176,6 @@ impl eframe::App for HomeApp {
|
|||
if let Ok(info) = self.xmrd_get_info_rx.try_recv() {
|
||||
self.s_xmrd_get_info = info;
|
||||
}
|
||||
if let Ok(install) = self.installation_rx.try_recv() {
|
||||
self.is_installing = !install;
|
||||
if !install && self.is_loading {
|
||||
self.has_install_failed = true
|
||||
}
|
||||
self.is_loading = false;
|
||||
}
|
||||
if let Ok(timeout) = self.core_timeout_rx.try_recv() {
|
||||
self.is_timeout = true;
|
||||
if timeout {
|
||||
|
@ -207,8 +193,9 @@ impl eframe::App for HomeApp {
|
|||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(ctx, |ui| {
|
||||
let mut i2p_address = i2p::get_destination(None);
|
||||
if !self.is_qr_set && i2p_address != utils::empty_string() {
|
||||
let mut i2p_address =
|
||||
i2p::get_destination(i2p::ServerTunnelType::App).unwrap_or_default();
|
||||
if !self.is_qr_set && !i2p_address.is_empty() {
|
||||
let code = QrCode::new(&i2p_address).unwrap();
|
||||
let image = code.render::<Luma<u8>>().build();
|
||||
let file_path = format!(
|
||||
|
@ -232,22 +219,6 @@ impl eframe::App for HomeApp {
|
|||
}
|
||||
});
|
||||
|
||||
// Installation Error window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut has_install_failed = self.has_install_failed;
|
||||
egui::Window::new("error")
|
||||
.open(&mut has_install_failed)
|
||||
.title_bar(false)
|
||||
.vscroll(false)
|
||||
.show(&ctx, |ui| {
|
||||
ui.heading("Installation Failure");
|
||||
if ui.button("Exit").clicked() {
|
||||
self.has_install_failed = false;
|
||||
self.is_installing = false;
|
||||
self.is_loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Connection Manager window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_editing_connections = self.is_editing_connections;
|
||||
|
@ -287,13 +258,6 @@ impl eframe::App for HomeApp {
|
|||
ui.text_edit_singleline(&mut self.connections.monero_location)
|
||||
.labelled_by(cm_xmr_dir_label.id);
|
||||
});
|
||||
if !self.connections.is_i2p_advanced {
|
||||
ui.horizontal(|ui| {
|
||||
let cm_i2p_dir_label = ui.label("i2p-zero path: \t");
|
||||
ui.text_edit_singleline(&mut self.connections.i2p_zero_dir)
|
||||
.labelled_by(cm_i2p_dir_label.id);
|
||||
});
|
||||
}
|
||||
if self.connections.is_i2p_advanced {
|
||||
ui.horizontal(|ui| {
|
||||
let cm_i2p_proxy_label = ui.label("i2p proxy host: \t");
|
||||
|
@ -305,11 +269,6 @@ impl eframe::App for HomeApp {
|
|||
ui.text_edit_singleline(&mut self.connections.i2p_socks_host)
|
||||
.labelled_by(cm_i2p_socks_label.id);
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
let cm_i2p_tunnels_label = ui.label("tunnels.json dir: ");
|
||||
ui.text_edit_singleline(&mut self.connections.i2p_tunnels_json)
|
||||
.labelled_by(cm_i2p_tunnels_label.id);
|
||||
});
|
||||
}
|
||||
let mut is_remote_node = self.connections.is_remote_node;
|
||||
if ui.checkbox(&mut is_remote_node, "remote node").changed() {
|
||||
|
@ -343,42 +302,6 @@ impl eframe::App for HomeApp {
|
|||
}
|
||||
});
|
||||
|
||||
// Installation Manager window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_installing = self.is_installing;
|
||||
egui::Window::new("installation")
|
||||
.open(&mut is_installing)
|
||||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(&ctx, |ui| {
|
||||
ui.heading("Installation Manager");
|
||||
let mut wants_i2p_zero = self.installations.i2p_zero;
|
||||
let mut wants_xmr = self.installations.xmr;
|
||||
if ui.checkbox(&mut wants_i2p_zero, "i2p-zero").changed() {
|
||||
self.installations.i2p_zero = !self.installations.i2p_zero;
|
||||
}
|
||||
if ui.checkbox(&mut wants_xmr, "xmr").changed() {
|
||||
self.installations.xmr = !self.installations.xmr;
|
||||
}
|
||||
let install = &self.installations;
|
||||
if install.i2p_zero || install.xmr {
|
||||
if !self.is_loading {
|
||||
if ui.button("Install").clicked() {
|
||||
self.is_loading = true;
|
||||
install_software_req(
|
||||
self.installation_tx.clone(),
|
||||
ctx.clone(),
|
||||
&self.installations,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.is_installing = false;
|
||||
self.is_loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
if !self.is_updated {
|
||||
|
@ -420,9 +343,8 @@ impl eframe::App for HomeApp {
|
|||
ui.horizontal(|ui| {
|
||||
self.logo_i2p.show(ui);
|
||||
ui.horizontal(|ui| {
|
||||
let i2p_address = i2p::get_destination(None);
|
||||
ui.label(
|
||||
RichText::new(format!("- status: {}\n- address: {}", str_i2p_status, i2p_address))
|
||||
RichText::new(format!("- status: {}\n- address: {}", str_i2p_status, self.b32_destination))
|
||||
.size(16.0)
|
||||
.color(color),
|
||||
).on_hover_text(hover_txt);
|
||||
|
@ -467,14 +389,6 @@ impl eframe::App for HomeApp {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !self.is_core_running && !self.is_installing && !self.connections.is_remote_node && !self.connections.is_i2p_advanced
|
||||
&& (self.s_xmr_rpc_ver.result.version == 0 || self.s_i2p_status == i2p::ProxyStatus::Opening) {
|
||||
if !self.is_loading {
|
||||
if ui.button("Install Software").clicked() {
|
||||
self.is_installing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -483,8 +397,7 @@ impl eframe::App for HomeApp {
|
|||
//-------------------------------------------------------------------------------------------------
|
||||
fn send_xmrd_get_info_req(tx: Sender<reqres::XmrDaemonGetInfoResponse>, ctx: egui::Context) {
|
||||
tokio::spawn(async move {
|
||||
let remote_var =
|
||||
std::env::var(neveko_core::GUI_REMOTE_NODE).unwrap_or(utils::empty_string());
|
||||
let remote_var = std::env::var(neveko_core::GUI_REMOTE_NODE).unwrap_or(String::new());
|
||||
if remote_var == String::from(neveko_core::GUI_SET_REMOTE_NODE) {
|
||||
let p_info = monero::p_get_info().await;
|
||||
let info = p_info.unwrap_or(Default::default());
|
||||
|
@ -533,7 +446,7 @@ fn send_wallet_req(
|
|||
fn send_i2p_status_req(tx: Sender<i2p::ProxyStatus>, ctx: egui::Context) {
|
||||
tokio::spawn(async move {
|
||||
let status = i2p::check_connection().await;
|
||||
let _ = tx.send(status);
|
||||
let _ = tx.send(status.unwrap_or(i2p::ProxyStatus::Opening));
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
@ -561,19 +474,3 @@ fn start_core_timeout(tx: Sender<bool>, ctx: egui::Context) {
|
|||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
||||
fn install_software_req(
|
||||
tx: Sender<bool>,
|
||||
ctx: egui::Context,
|
||||
installations: &utils::Installations,
|
||||
) {
|
||||
let req_install: utils::Installations = utils::Installations {
|
||||
i2p_zero: installations.i2p_zero,
|
||||
xmr: installations.xmr,
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let did_install = utils::install_software(req_install).await;
|
||||
let _ = tx.send(did_install);
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::CREDENTIAL_KEY;
|
||||
use db::DATABASE_LOCK;
|
||||
use neveko_core::*;
|
||||
use sha2::{
|
||||
Digest,
|
||||
|
@ -15,7 +16,7 @@ struct LockScreen {
|
|||
impl Default for LockScreen {
|
||||
fn default() -> Self {
|
||||
LockScreen {
|
||||
credential: utils::empty_string(),
|
||||
credential: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,13 +63,19 @@ impl eframe::App for LockScreenApp {
|
|||
self.lock_screen.credential.clone(),
|
||||
);
|
||||
// Get the credential hash from lmdb
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, CREDENTIAL_KEY);
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&CREDENTIAL_KEY.as_bytes().to_vec(),
|
||||
)
|
||||
.unwrap();
|
||||
// hash the text entered and compare
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.lock_screen.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
let hex = hex::encode(&result[..]);
|
||||
let r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
if hex == r {
|
||||
self.is_locked = false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Default for MailBoxApp {
|
|||
let (refresh_on_delete_tx, refresh_on_delete_rx) = std::sync::mpsc::channel();
|
||||
let (deciphered_tx, deciphered_rx) = std::sync::mpsc::channel();
|
||||
MailBoxApp {
|
||||
deciphered: utils::empty_string(),
|
||||
deciphered: String::new(),
|
||||
is_showing_decipher: false,
|
||||
messages: Vec::new(),
|
||||
message_init: false,
|
||||
|
@ -51,7 +51,7 @@ impl eframe::App for MailBoxApp {
|
|||
|
||||
// initial message load
|
||||
if !self.message_init {
|
||||
self.messages = message::find_all();
|
||||
self.messages = message::find_all().unwrap_or_default();
|
||||
self.message_init = true;
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,14 @@ impl eframe::App for MailBoxApp {
|
|||
ui.label(format!("{}", self.deciphered));
|
||||
ui.label("\n");
|
||||
if ui.button("Exit").clicked() {
|
||||
self.deciphered = utils::empty_string();
|
||||
self.deciphered = String::new();
|
||||
self.is_showing_decipher = false;
|
||||
}
|
||||
});
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
if ui.button("Refresh").clicked() {
|
||||
self.messages = message::find_all();
|
||||
self.messages = message::find_all().unwrap_or_default();
|
||||
}
|
||||
ui.label("\n");
|
||||
use egui_extras::{
|
||||
|
@ -144,7 +144,7 @@ impl eframe::App for MailBoxApp {
|
|||
}
|
||||
}
|
||||
if ui.button("Delete").clicked() {
|
||||
message::delete(&m.mid);
|
||||
message::delete(&m.mid).unwrap();
|
||||
refresh_on_delete_req(
|
||||
self.refresh_on_delete_tx.clone(),
|
||||
ctx.clone(),
|
||||
|
@ -173,7 +173,7 @@ fn decipher_req(m: &Message, tx: Sender<String>, ctx: egui::Context) {
|
|||
let body: String = String::from(&m.body);
|
||||
tokio::spawn(async move {
|
||||
log::info!("async decipher_req");
|
||||
let contact = contact::find_by_i2p_address(&from);
|
||||
let contact = contact::find_by_i2p_address(&from).unwrap_or_default();
|
||||
let deciphered = neveko25519::cipher(&contact.nmpk, body, None).await;
|
||||
let _ = tx.send(deciphered);
|
||||
ctx.request_repaint();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,4 @@
|
|||
use db::DATABASE_LOCK;
|
||||
use neveko_core::*;
|
||||
use sha2::{
|
||||
Digest,
|
||||
|
@ -22,7 +23,7 @@ impl Default for SettingsApp {
|
|||
fn default() -> Self {
|
||||
let (change_wallet_password_tx, change_wallet_password_rx) = std::sync::mpsc::channel();
|
||||
SettingsApp {
|
||||
credential: utils::empty_string(),
|
||||
credential: String::new(),
|
||||
change_wallet_password_rx,
|
||||
change_wallet_password_tx,
|
||||
is_loading: false,
|
||||
|
@ -63,20 +64,27 @@ impl eframe::App for SettingsApp {
|
|||
}
|
||||
if ui.button("Change").clicked() {
|
||||
self.is_loading = true;
|
||||
let s = db::Interface::open();
|
||||
let db = &DATABASE_LOCK;
|
||||
let k = CREDENTIAL_KEY;
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
let _ = db::DatabaseEnvironment::delete(&db.env, &db.handle, k.as_bytes())
|
||||
.unwrap_or_else(|_| log::error!("failed to delete credential"));
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
db::Interface::write(&s.env, &s.handle, &k, &hex::encode(&result[..]));
|
||||
db::write_chunks(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
k.as_bytes(),
|
||||
hex::encode(&result[..]).as_bytes(),
|
||||
)
|
||||
.unwrap_or_else(|_| log::error!("failed to write credential"));
|
||||
// update wallet rpc
|
||||
change_wallet_password(
|
||||
self.change_wallet_password_tx.clone(),
|
||||
&self.credential,
|
||||
ctx.clone(),
|
||||
);
|
||||
self.credential = utils::empty_string();
|
||||
self.credential = String::new();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,12 +34,12 @@ impl Default for WalletApp {
|
|||
is_showing_qr: false,
|
||||
is_showing_sweep_result: false,
|
||||
qr: egui_extras::RetainedImage::from_image_bytes("qr.png", &contents).unwrap(),
|
||||
sweep_address: utils::empty_string(),
|
||||
sweep_address: String::new(),
|
||||
xmr_address_rx,
|
||||
xmr_address_tx,
|
||||
xmr_sweep_all_rx,
|
||||
xmr_sweep_all_tx,
|
||||
s_xmr_address: utils::empty_string(),
|
||||
s_xmr_address: String::new(),
|
||||
x_xmr_sweep_res: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl eframe::App for WalletApp {
|
|||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(ctx, |ui| {
|
||||
if !self.is_qr_set && self.s_xmr_address != utils::empty_string() {
|
||||
if !self.is_qr_set && !self.s_xmr_address.is_empty() {
|
||||
let code = QrCode::new(&self.s_xmr_address.clone()).unwrap();
|
||||
let image = code.render::<Luma<u8>>().build();
|
||||
let file_path = format!(
|
||||
|
@ -135,7 +135,7 @@ impl eframe::App for WalletApp {
|
|||
ctx.clone(),
|
||||
self.sweep_address.clone(),
|
||||
);
|
||||
self.sweep_address = utils::empty_string();
|
||||
self.sweep_address = String::new();
|
||||
self.is_showing_sweep_result = true;
|
||||
self.is_loading = true;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ pub const I2P_PROPAGATION_TIME_IN_SECS_EST: u64 = PROPAGATION_TIME_IN_SECS_EST *
|
|||
/// time to wait before giving up on adding a contact
|
||||
pub const ADD_CONTACT_TIMEOUT_SECS: u64 = 0x5A;
|
||||
/// time to wait before giving up on neveko core
|
||||
pub const START_CORE_TIMEOUT_SECS: u64 = 0x79;
|
||||
pub const START_CORE_TIMEOUT_SECS: u64 = 0x4B0;
|
||||
/// bytes in a a GB for calculating space on home page
|
||||
pub const BYTES_IN_GB: u64 = 1000000000;
|
||||
/// Useful flag to keep services running in background
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::CREDENTIAL_KEY;
|
||||
use db::DATABASE_LOCK;
|
||||
use neveko_core::*;
|
||||
use sha2::{
|
||||
Digest,
|
||||
|
@ -14,7 +15,7 @@ pub struct LoginApp {
|
|||
|
||||
impl Default for LoginApp {
|
||||
fn default() -> Self {
|
||||
let credential = utils::empty_string();
|
||||
let credential = String::new();
|
||||
let is_cred_generated = false;
|
||||
let is_not_showing_password = true;
|
||||
LoginApp {
|
||||
|
@ -54,9 +55,11 @@ impl eframe::App for LoginApp {
|
|||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
let s = db::Interface::open();
|
||||
db::Interface::write(&s.env, &s.handle, k, &hex::encode(&result[..]));
|
||||
self.credential = utils::empty_string();
|
||||
let db = &DATABASE_LOCK;
|
||||
let v = bincode::serialize(&hex::encode(&result[..])).unwrap_or_default();
|
||||
db::write_chunks(&db.env, &db.handle, k.as_bytes(), &v)
|
||||
.unwrap_or_else(|_| log::error!("failed to set credential"));
|
||||
self.credential = String::new();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use db::DATABASE_LOCK;
|
||||
#[cfg(feature = "glow")]
|
||||
use eframe::glow;
|
||||
use neveko_core::*;
|
||||
|
@ -236,9 +237,14 @@ impl WrapApp {
|
|||
ctx.set_pixels_per_point(1.5);
|
||||
// initial cred check, is there a better way to do this?
|
||||
if !self.state.is_cred_set {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if r != utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::CREDENTIAL_KEY.as_bytes().to_vec(),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
if !r.is_empty() {
|
||||
self.state.is_cred_set = true;
|
||||
self.state.is_checking_cred = false;
|
||||
}
|
||||
|
@ -308,9 +314,14 @@ impl WrapApp {
|
|||
loop {
|
||||
log::debug!("check for cred");
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if r == utils::empty_string() {
|
||||
let db = &DATABASE_LOCK;
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&db.env,
|
||||
&db.handle,
|
||||
&crate::CREDENTIAL_KEY.as_bytes().to_vec(),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
if r.is_empty() {
|
||||
log::debug!("credential not found");
|
||||
let _ = tx.send(false);
|
||||
ctx.request_repaint();
|
||||
|
|
760
neveko-market/Cargo.lock
generated
760
neveko-market/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -19,15 +19,15 @@ pub async fn create_product(
|
|||
req_product: Json<models::Product>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::create(req_product);
|
||||
Custom(Status::Created, Json(m_product))
|
||||
let m_product = product::create(req_product);
|
||||
Custom(Status::Created, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get a product by passing id
|
||||
#[get("/<pid>")]
|
||||
pub async fn get_product(pid: String, _token: auth::BearerToken) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Update product information
|
||||
|
@ -36,29 +36,29 @@ pub async fn update_product(
|
|||
product: Json<models::Product>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::modify(product);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product = product::modify(product);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Return all products
|
||||
#[get("/")]
|
||||
pub async fn get_products(_token: auth::BearerToken) -> Custom<Json<Vec<models::Product>>> {
|
||||
let m_products: Vec<models::Product> = product::find_all();
|
||||
Custom(Status::Ok, Json(m_products))
|
||||
let m_products = product::find_all();
|
||||
Custom(Status::Ok, Json(m_products.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get a order by passing id
|
||||
#[get("/<orid>")]
|
||||
pub async fn get_order(orid: String, _token: auth::BearerToken) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::find(&orid);
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
let m_order = order::find(&orid);
|
||||
Custom(Status::Ok, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get all orders
|
||||
#[get("/")]
|
||||
pub async fn get_orders(_token: auth::BearerToken) -> Custom<Json<Vec<models::Order>>> {
|
||||
let m_orders: Vec<models::Order> = order::find_all();
|
||||
Custom(Status::Ok, Json(m_orders))
|
||||
let m_orders = order::find_all();
|
||||
Custom(Status::Ok, Json(m_orders.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Update order information
|
||||
|
@ -67,8 +67,8 @@ pub async fn update_order(
|
|||
order: Json<models::Order>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::modify(order);
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
let m_order = order::modify(order);
|
||||
Custom(Status::Ok, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Create a dispute
|
||||
|
@ -77,15 +77,15 @@ pub async fn create_dispute(
|
|||
dispute: Json<models::Dispute>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::create(dispute);
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
let m_dispute = dispute::create(dispute);
|
||||
Custom(Status::Ok, Json(m_dispute.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Fetch a dispute
|
||||
#[get("/<did>")]
|
||||
pub async fn get_dispute(_token: auth::BearerToken, did: String) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::find(&did);
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
let m_dispute = dispute::find(&did);
|
||||
Custom(Status::Ok, Json(m_dispute.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Sign and submit multisig
|
||||
|
@ -113,12 +113,12 @@ pub async fn upload_delivery_info(
|
|||
r_data: Json<reqres::FinalizeOrderResponse>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let upload: reqres::FinalizeOrderResponse =
|
||||
order::upload_delivery_info(&orid, &r_data.delivery_info).await;
|
||||
if upload.delivery_info.is_empty() {
|
||||
let upload = order::upload_delivery_info(&orid, &r_data.delivery_info).await;
|
||||
let u_upload = upload.unwrap_or_default();
|
||||
if u_upload.delivery_info.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(upload))
|
||||
Custom(Status::Ok, Json(u_upload))
|
||||
}
|
||||
|
||||
/// toggle vendor mode
|
||||
|
@ -126,7 +126,7 @@ pub async fn upload_delivery_info(
|
|||
pub async fn toggle_vendor_mode(
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::VendorModeResponse>> {
|
||||
let mode = utils::toggle_vendor_enabled();
|
||||
let mode = utils::toggle_vendor_enabled().unwrap_or_default();
|
||||
Custom(Status::Ok, Json(reqres::VendorModeResponse { mode }))
|
||||
}
|
||||
// END JSON APIs
|
||||
|
|
468
neveko-message/Cargo.lock
generated
468
neveko-message/Cargo.lock
generated
|
@ -17,7 +17,7 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -127,10 +127,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -140,9 +143,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.0.2"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
@ -180,6 +183,12 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -286,7 +295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -301,9 +310,34 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -316,15 +350,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.2"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"fiat-crypto",
|
||||
"platforms",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
|
@ -411,7 +444,7 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
|
||||
dependencies = [
|
||||
"bitflags 2.0.2",
|
||||
"bitflags 2.6.0",
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
|
@ -463,6 +496,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
|
@ -486,7 +525,7 @@ checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
|||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
@ -498,7 +537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -509,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -571,6 +610,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
|
@ -579,6 +624,7 @@ checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
@ -601,12 +647,34 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
|
@ -628,6 +696,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
|
@ -649,8 +718,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.44.0",
|
||||
]
|
||||
|
@ -672,7 +741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
|
@ -719,7 +788,7 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -887,7 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
@ -915,6 +984,67 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "j4-i2p-rs"
|
||||
version = "0.2.0-alpha"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"j4rs",
|
||||
"log",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "j4rs"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "689ae4f2bd4eba82601592f3d22b7e7147b1df52d3b525223f5218990501b4eb"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"glob",
|
||||
"java-locator",
|
||||
"jni-sys",
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.158",
|
||||
"libloading",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "java-locator"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c30a312d782b8d56a1e0897d45c1af33f31f9b4a4d13d31207a8675e0223b818"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c199962dfd5610ced8eca382606e349f7940a4ac7d867b58a046123411cbb4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
|
@ -939,6 +1069,18 @@ dependencies = [
|
|||
"sha2 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kn0sys-lmdb-rs"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fbf491e9e95a325cbfe1459734cec781c0145c0d5cb7c4ced71af742364d19"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc 0.2.158",
|
||||
"liblmdb-sys",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
|
@ -959,9 +1101,9 @@ checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "liblmdb-sys"
|
||||
|
@ -970,7 +1112,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -988,18 +1140,6 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-rs"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4aefe7b433f795629ce42f35ccf7a620c38bd457238bfaa2489dafc7e36167e7"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0",
|
||||
"libc 0.2.140",
|
||||
"liblmdb-sys",
|
||||
"log 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
@ -1012,21 +1152,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
|
@ -1081,8 +1209,8 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1098,7 +1226,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"http",
|
||||
"httparse",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"mime",
|
||||
"spin",
|
||||
|
@ -1114,8 +1242,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"libc 0.2.140",
|
||||
"log 0.4.17",
|
||||
"libc 0.2.158",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
|
@ -1129,6 +1257,7 @@ dependencies = [
|
|||
name = "neveko_core"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"curve25519-dalek",
|
||||
|
@ -1136,10 +1265,11 @@ dependencies = [
|
|||
"env_logger",
|
||||
"hex",
|
||||
"hmac",
|
||||
"j4-i2p-rs",
|
||||
"jwt",
|
||||
"kn0sys-lmdb-rs",
|
||||
"lazy_static 1.4.0",
|
||||
"lmdb-rs",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"num",
|
||||
"rand",
|
||||
"rand_core",
|
||||
|
@ -1150,6 +1280,8 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -1158,11 +1290,20 @@ name = "neveko_message"
|
|||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"neveko_core",
|
||||
"rocket",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1256,7 +1397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1280,7 +1421,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
|
@ -1311,7 +1452,7 @@ checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -1339,7 +1480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -1392,12 +1533,6 @@ version = "0.3.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
|
@ -1441,7 +1576,7 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
@ -1465,6 +1600,26 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -1547,7 +1702,7 @@ dependencies = [
|
|||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
|
@ -1582,7 +1737,7 @@ dependencies = [
|
|||
"futures",
|
||||
"indexmap",
|
||||
"is-terminal",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"multer",
|
||||
"num_cpus",
|
||||
|
@ -1633,7 +1788,7 @@ dependencies = [
|
|||
"http",
|
||||
"hyper",
|
||||
"indexmap",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"memchr",
|
||||
"pear",
|
||||
"percent-encoding",
|
||||
|
@ -1676,7 +1831,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1738,7 +1893,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
|
@ -1749,7 +1904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1840,7 +1995,7 @@ version = "1.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1864,7 +2019,7 @@ version = "0.4.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -1926,6 +2081,20 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.158",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
@ -1957,6 +2126,26 @@ dependencies = [
|
|||
"libc 0.1.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
|
@ -1973,7 +2162,7 @@ version = "0.1.45"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2028,7 +2217,7 @@ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc 0.2.140",
|
||||
"libc 0.2.158",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
|
@ -2139,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
|
@ -2266,7 +2455,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
|
@ -2299,7 +2488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log 0.4.17",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2407,6 +2596,59 @@ dependencies = [
|
|||
"windows-targets 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -2461,6 +2703,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2473,6 +2731,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2485,6 +2749,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2497,6 +2767,18 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2509,6 +2791,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -2521,6 +2809,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -2533,6 +2827,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -2545,6 +2845,12 @@ version = "0.47.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
|
|
|
@ -29,23 +29,23 @@ pub async fn send_message(
|
|||
} else {
|
||||
message::MessageType::Normal
|
||||
};
|
||||
let res: Message = message::create(m_req, token.get_jwp(), m_type).await;
|
||||
Custom(Status::Ok, Json(res))
|
||||
let res = message::create(m_req, token.get_jwp(), m_type).await;
|
||||
Custom(Status::Ok, Json(res.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Return all messages
|
||||
#[get("/")]
|
||||
pub async fn get_messages(_token: auth::BearerToken) -> Custom<Json<Vec<Message>>> {
|
||||
let messages = message::find_all();
|
||||
Custom(Status::Ok, Json(messages))
|
||||
Custom(Status::Ok, Json(messages.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Delete a message by mid
|
||||
#[delete("/<mid>")]
|
||||
pub async fn remove_message(mid: String, _token: auth::BearerToken) -> Custom<Json<Vec<Message>>> {
|
||||
message::delete(&mid);
|
||||
let _ = message::delete(&mid);
|
||||
let messages = message::find_all();
|
||||
Custom(Status::Ok, Json(messages))
|
||||
Custom(Status::Ok, Json(messages.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// decipher a message body
|
||||
|
@ -55,5 +55,5 @@ pub async fn decipher(
|
|||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::DecipheredMessageBody>> {
|
||||
let d_message = message::decipher_body(mid).await;
|
||||
Custom(Status::Ok, Json(d_message))
|
||||
Custom(Status::Ok, Json(d_message.unwrap_or_default()))
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ pub async fn get_version(_jwp: proof::PaymentProof) -> Custom<Json<reqres::XmrRp
|
|||
/// This also functions as a health check
|
||||
#[get("/status")]
|
||||
pub async fn get_i2p_status() -> Custom<Json<i2p::HttpProxyStatus>> {
|
||||
let status: i2p::ProxyStatus = i2p::check_connection().await;
|
||||
if status == i2p::ProxyStatus::Open {
|
||||
let status = i2p::check_connection().await;
|
||||
if status.unwrap_or(i2p::ProxyStatus::Opening) == i2p::ProxyStatus::Open {
|
||||
Custom(Status::Ok, Json(i2p::HttpProxyStatus { open: true }))
|
||||
} else {
|
||||
Custom(Status::Ok, Json(i2p::HttpProxyStatus { open: false }))
|
||||
|
@ -44,8 +44,8 @@ pub async fn get_i2p_status() -> Custom<Json<i2p::HttpProxyStatus>> {
|
|||
/// Protected: false
|
||||
#[get("/")]
|
||||
pub async fn share_contact_info() -> Custom<Json<models::Contact>> {
|
||||
let info: models::Contact = contact::share().await;
|
||||
Custom(Status::Ok, Json(info))
|
||||
let info = contact::share().await;
|
||||
Custom(Status::Ok, Json(info.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Recieve messages here
|
||||
|
@ -56,7 +56,7 @@ pub async fn rx_message(
|
|||
_jwp: proof::PaymentProof,
|
||||
message: Json<models::Message>,
|
||||
) -> Custom<Json<models::Message>> {
|
||||
message::rx(message).await;
|
||||
let _ = message::rx(message).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,8 @@ pub async fn gen_jwp(proof: Json<proof::TxProof>) -> Custom<Json<reqres::Jwp>> {
|
|||
/// Get a product by passing id
|
||||
#[get("/<pid>")]
|
||||
pub async fn get_product(pid: String, _jwp: proof::PaymentProof) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get all products
|
||||
|
@ -93,7 +93,7 @@ pub async fn get_product(pid: String, _jwp: proof::PaymentProof) -> Custom<Json<
|
|||
/// Protected: true
|
||||
#[get("/products")]
|
||||
pub async fn get_products(_jwp: proof::PaymentProof) -> Custom<Json<Vec<models::Product>>> {
|
||||
let m_products: Vec<models::Product> = product::find_all();
|
||||
let m_products: Vec<models::Product> = product::find_all().unwrap_or_default();
|
||||
Custom(Status::Ok, Json(m_products))
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,8 @@ pub async fn create_order(
|
|||
r_order: Json<reqres::OrderRequest>,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::create(r_order).await;
|
||||
Custom(Status::Created, Json(m_order))
|
||||
let m_order = order::create(r_order).await;
|
||||
Custom(Status::Created, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Customer order retreival. Must send `signature`
|
||||
|
@ -120,8 +120,9 @@ pub async fn retrieve_order(
|
|||
signature: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::secure_retrieval(&orid, &signature).await;
|
||||
if m_order.cid == utils::empty_string() {
|
||||
let r_m_order = order::secure_retrieval(&orid, &signature).await;
|
||||
let m_order = r_m_order.unwrap_or_default();
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Created, Json(m_order))
|
||||
|
@ -135,21 +136,22 @@ pub async fn get_multisig_info(
|
|||
r_info: Json<reqres::MultisigInfoRequest>,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let info: Vec<String> = r_info.info.iter().cloned().collect();
|
||||
if r_info.msig_type == String::from(message::PREPARE_MSIG) {
|
||||
let info: Vec<String> = r_info.info.to_vec();
|
||||
if r_info.msig_type == *message::PREPARE_MSIG {
|
||||
// adjudicator won't have wallet for order yet do that first
|
||||
if r_info.init_adjudicator {
|
||||
order::init_adjudicator_wallet(&r_info.orid).await;
|
||||
}
|
||||
message::send_prepare_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == String::from(message::MAKE_MSIG) {
|
||||
message::send_make_info(&r_info.orid, &r_info.contact, info).await;
|
||||
} else if r_info.msig_type == String::from(message::EXPORT_MSIG) {
|
||||
message::send_export_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == String::from(message::IMPORT_MSIG) {
|
||||
message::send_import_info(&r_info.orid, &r_info.info).await;
|
||||
let _ = message::send_prepare_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == *message::MAKE_MSIG {
|
||||
let _ = message::send_make_info(&r_info.orid, &r_info.contact, info).await;
|
||||
} else if r_info.msig_type == *message::EXPORT_MSIG {
|
||||
let _ = message::send_export_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == *message::IMPORT_MSIG {
|
||||
let _ = message::send_import_info(&r_info.orid, &r_info.info).await;
|
||||
} else {
|
||||
message::send_exchange_info(&r_info.orid, &r_info.contact, info, r_info.kex_init).await;
|
||||
let _ =
|
||||
message::send_exchange_info(&r_info.orid, &r_info.contact, info, r_info.kex_init).await;
|
||||
}
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
@ -162,7 +164,7 @@ pub async fn rx_multisig_message(
|
|||
_jwp: proof::PaymentProof,
|
||||
message: Json<models::Message>,
|
||||
) -> Custom<Json<models::Message>> {
|
||||
message::rx_multisig(message).await;
|
||||
let _ = message::rx_multisig(message).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,8 @@ pub async fn request_shipment(
|
|||
orid: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let finalize: reqres::FinalizeOrderResponse = order::validate_order_for_ship(&orid).await;
|
||||
let r_finalize = order::validate_order_for_ship(&orid).await;
|
||||
let finalize = r_finalize.unwrap_or_default();
|
||||
if finalize.delivery_info.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -204,8 +207,9 @@ pub async fn trigger_nasr(
|
|||
vendor: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let order: models::Order = order::d_trigger_ship_request(&vendor, &orid).await;
|
||||
if order.orid == utils::empty_string() {
|
||||
let r_order = order::d_trigger_ship_request(&vendor, &orid).await;
|
||||
let order = r_order.unwrap_or_default();
|
||||
if order.orid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(order))
|
||||
|
@ -222,8 +226,9 @@ pub async fn cancel_order(
|
|||
signature: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::cancel_order(&orid, &signature).await;
|
||||
if m_order.cid == utils::empty_string() {
|
||||
let r_m_order = order::cancel_order(&orid, &signature).await;
|
||||
let m_order = r_m_order.unwrap_or_default();
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
|
@ -239,7 +244,8 @@ pub async fn finalize_order(
|
|||
orid: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let finalize = order::finalize_order(&orid).await;
|
||||
let r_finalize = order::finalize_order(&orid).await;
|
||||
let finalize = r_finalize.unwrap_or_default();
|
||||
if !finalize.vendor_update_success {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -252,7 +258,8 @@ pub async fn create_dispute(
|
|||
dispute: Json<models::Dispute>,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::create(dispute);
|
||||
let r_m_dispute = dispute::create(dispute);
|
||||
let m_dispute = r_m_dispute.unwrap_or_default();
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ async fn rocket() -> _ {
|
|||
..rocket::Config::debug_default()
|
||||
};
|
||||
env_logger::init();
|
||||
utils::start_up().await;
|
||||
let _ = utils::start_up().await;
|
||||
rocket::custom(&config)
|
||||
.register(
|
||||
"/",
|
||||
|
|
Loading…
Reference in a new issue