Merge pull request 'feat: parse webpage and compute PoW for widget' (#1) from feat-parse-webpage into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Reviewed-on: #1
This commit is contained in:
Aravinth Manivannan 2023-10-27 03:46:44 +05:30
commit 8601f32e52
4 changed files with 593 additions and 91 deletions

457
Cargo.lock generated
View file

@ -17,6 +17,19 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.4" version = "0.6.4"
@ -141,6 +154,12 @@ version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.5.0" version = "1.5.0"
@ -252,6 +271,29 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "cssparser"
version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be"
dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa",
"phf 0.11.2",
"smallvec",
]
[[package]]
name = "cssparser-macros"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [
"quote",
"syn 2.0.38",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.14.4" version = "0.14.4"
@ -318,6 +360,17 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@ -328,6 +381,27 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "dtoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
[[package]]
name = "dtoa-short"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74"
dependencies = [
"dtoa",
]
[[package]]
name = "ego-tree"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.33" version = "0.8.33"
@ -393,6 +467,16 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "futf"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
dependencies = [
"mac",
"new_debug_unreachable",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.28" version = "0.3.28"
@ -432,6 +516,15 @@ dependencies = [
"pin-utils", "pin-utils",
] ]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.7"
@ -442,6 +535,26 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.0" version = "0.28.0"
@ -485,6 +598,20 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "html5ever"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
dependencies = [
"log",
"mac",
"markup5ever",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.9" version = "0.2.9"
@ -621,12 +748,42 @@ version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.20" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "markup5ever"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
dependencies = [
"log",
"phf 0.10.1",
"phf_codegen",
"string_cache",
"string_cache_codegen",
"tendril",
]
[[package]] [[package]]
name = "mcaptcha-cli" name = "mcaptcha-cli"
version = "0.2.0" version = "0.2.0"
@ -634,6 +791,7 @@ dependencies = [
"clap", "clap",
"mcaptcha_pow_sha256", "mcaptcha_pow_sha256",
"reqwest", "reqwest",
"scraper",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
@ -703,6 +861,12 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]] [[package]]
name = "num" name = "num"
version = "0.4.1" version = "0.4.1"
@ -860,12 +1024,115 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.4.1",
"smallvec",
"windows-targets",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "phf"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
dependencies = [
"phf_shared 0.10.0",
]
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_macros",
"phf_shared 0.11.2",
]
[[package]]
name = "phf_codegen"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
dependencies = [
"phf_generator 0.10.0",
"phf_shared 0.10.0",
]
[[package]]
name = "phf_generator"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
dependencies = [
"phf_shared 0.10.0",
"rand",
]
[[package]]
name = "phf_generator"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared 0.11.2",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
dependencies = [
"phf_generator 0.11.2",
"phf_shared 0.11.2",
"proc-macro2",
"quote",
"syn 2.0.38",
]
[[package]]
name = "phf_shared"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [
"siphasher",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
"siphasher",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.13" version = "0.2.13"
@ -884,6 +1151,18 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.69"
@ -902,6 +1181,36 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -911,6 +1220,15 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.22" version = "0.11.22"
@ -985,6 +1303,28 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "scraper"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3693f9a0203d49a7ba8f38aa915316b3d535c1862d03dae7009cb71a3408b36a"
dependencies = [
"ahash",
"cssparser",
"ego-tree",
"getopts",
"html5ever",
"once_cell",
"selectors",
"tendril",
]
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "2.9.2" version = "2.9.2"
@ -1008,6 +1348,25 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "selectors"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
dependencies = [
"bitflags 2.4.1",
"cssparser",
"derive_more",
"fxhash",
"log",
"new_debug_unreachable",
"phf 0.10.1",
"phf_codegen",
"precomputed-hash",
"servo_arc",
"smallvec",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.189" version = "1.0.189"
@ -1051,6 +1410,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "servo_arc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44"
dependencies = [
"stable_deref_trait",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.8" version = "0.10.8"
@ -1062,6 +1430,12 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.9"
@ -1071,6 +1445,12 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "smallvec"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.10" version = "0.4.10"
@ -1091,6 +1471,38 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "string_cache"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
dependencies = [
"new_debug_unreachable",
"once_cell",
"parking_lot",
"phf_shared 0.10.0",
"precomputed-hash",
"serde",
]
[[package]]
name = "string_cache_codegen"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
dependencies = [
"phf_generator 0.10.0",
"phf_shared 0.10.0",
"proc-macro2",
"quote",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"
@ -1148,11 +1560,22 @@ checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"redox_syscall", "redox_syscall 0.3.5",
"rustix", "rustix",
"windows-sys", "windows-sys",
] ]
[[package]]
name = "tendril"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
dependencies = [
"futf",
"mac",
"utf-8",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -1278,6 +1701,12 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]] [[package]]
name = "url" name = "url"
version = "2.4.1" version = "2.4.1"
@ -1290,6 +1719,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
version = "0.2.1" version = "0.2.1"
@ -1496,3 +1931,23 @@ dependencies = [
"cfg-if", "cfg-if",
"windows-sys", "windows-sys",
] ]
[[package]]
name = "zerocopy"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
]

View file

@ -1,8 +1,8 @@
[package] [package]
name = "mcaptcha-cli" name = "mcaptcha-cli"
description = "CLI tool to solve mCaptcha" description = "CLI tool to solve mCaptcha"
version = "0.2.0" version = "0.3.0"
repository = "https://github.com/mCaptcha/cli" repository = "https://git.batsense.net/mCaptcha/cli"
documentation = "https://mcaptcha.org/docs/" documentation = "https://mcaptcha.org/docs/"
authors = ["realaravinth <realaravinth@batsense.net>"] authors = ["realaravinth <realaravinth@batsense.net>"]
license = "AGPL-3.0" license = "AGPL-3.0"
@ -17,3 +17,4 @@ reqwest = { version = "0.11.18", features = ["json", "gzip", "native-tls-vendore
serde = { version = "1.0.189", features = ["derive"] } serde = { version = "1.0.189", features = ["derive"] }
serde_json = "1.0.107" serde_json = "1.0.107"
url = { version = "2.4.1", features = ["serde"] } url = { version = "2.4.1", features = ["serde"] }
scraper = "0.18.0"

View file

@ -17,22 +17,23 @@
### Modes: ### Modes:
1. Offline: Computes PoW over given CAPTCHA parameters 1. Offline: Computes PoW over given CAPTCHA parameters
2. Online: CLI alternative for people using browsers without JavaScript 2. Protected Page: Compute mCaptcha challenge for the CAPTCHA at a
support protected page
3. Widget URL: Compute PoW for captcha at widget URL
```bash ```bash
CLI tool to solve mCaptcha
Usage: mcaptcha-cli <COMMAND> Usage: mcaptcha-cli <COMMAND>
Commands: Commands:
offline Compute PoW with offline parameters offline Compute PoW with offline parameters
online Compute PoW by fetching parameters from CAPTCHA URL protected-page Compute PoW by fetching parameters from protected page URL
widget-url Compute PoW by fetching parameters from CAPTCHA URL
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
Options: Options:
-h, --help Print help -h, --help Print help
-V, --version Print version -V, --version Print version
``` ```
#### Offline #### Offline
@ -65,7 +66,16 @@ result: 340276562956196291522979356090220150471
[this](https://github.com/realaravinth/dotfiles/blob/6fc6c87cc912e17488a35c0d3327ecf393221270/scripts/rand#L20) [this](https://github.com/realaravinth/dotfiles/blob/6fc6c87cc912e17488a35c0d3327ecf393221270/scripts/rand#L20)
script) script)
#### Online #### Protected Page
Used to generate authorization tokens for CAPTCHA at a protected page
```bash
03:39 atm@lab cli ±|feat-parse-webpage ✗|→ mcaptcha-cli protected-page https://showcase.mcaptcha.org/
Authorization token: eRAZJiMrW58uDYA1s64Tmwq1u30HutuF
```
#### Widget URL
Fetches CAPTCHA parameters from CAPTCHA URL, computes PoW, validates Fetches CAPTCHA parameters from CAPTCHA URL, computes PoW, validates
against given mCaptcha server and returns authorization token against given mCaptcha server and returns authorization token

View file

@ -10,6 +10,7 @@ use clap::*;
use mcaptcha_pow_sha256::ConfigBuilder; use mcaptcha_pow_sha256::ConfigBuilder;
use mcaptcha_pow_sha256::PoW; use mcaptcha_pow_sha256::PoW;
use reqwest::Client; use reqwest::Client;
use scraper::{Html, Selector};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
@ -30,70 +31,40 @@ struct Offline {
} }
#[derive(Deserialize, Parser, Serialize, Clone, Debug)] #[derive(Deserialize, Parser, Serialize, Clone, Debug)]
/// Compute PoW by fetching parameters from CAPTCHA URL /// Compute PoW by fetching parameters from protected page URL
struct Online { struct ProtectedPage {
/// URL of the CAPTCHA. Example: https://example.org/widget?sitekey=foo /// URL of the protected page. Example: https://example.org/protected.html
#[arg(short, long)]
url: Url, url: Url,
} }
impl Online { impl ProtectedPage {
fn extract_sitekey(&self) -> Option<String> { async fn extract_url(self) -> Option<WidgetUrl> {
let mut sitekey = None; let c = Client::default();
for (k, v) in self.url.query_pairs() { let text = c.get(self.url).send().await.unwrap().text().await.unwrap();
if &k == "sitekey" { let fragement = Html::parse_fragment(&text);
let x: &str = &v; let selector = Selector::parse("label#mcaptcha__token-label").unwrap();
sitekey = Some(x.to_string()) if let Some(label) = fragement.select(&selector).next() {
if let Some(val) = label.value().attr("data-mcaptcha_url") {
if let Ok(url) = Url::parse(val) {
return Some(WidgetUrl { url });
}
} }
} }
sitekey None
}
fn get_config_url(&self) -> Url {
let mut url = self.url.clone();
url.set_path("/api/v1/pow/config");
url
}
fn get_verify_url(&self) -> Url {
let mut url = self.url.clone();
url.set_path("/api/v1/pow/verify");
url
} }
} }
#[derive(Deserialize, Parser, Serialize, Clone, Debug)] #[derive(Deserialize, Parser, Serialize, Clone, Debug)]
#[command(author, version, about, long_about = None)] /// Compute PoW by fetching parameters from CAPTCHA URL
enum Args { struct WidgetUrl {
Offline(Offline), url: Url,
Online(Online),
} }
fn prove_work(phrase: String, salt: String, difficulty_factor: u32) -> PoW<String> { impl WidgetUrl {
let config = ConfigBuilder::default().salt(salt).build().unwrap(); async fn run(&self) {
config.prove_work(&phrase, difficulty_factor).unwrap() let c = Client::default();
} let sitekey = self.extract_sitekey();
#[tokio::main]
async fn main() {
let args = Args::parse();
match args {
Args::Offline(matches) => {
let phrase = matches.phrase;
let salt = matches.salt;
let difficulty_factor = matches.difficulty_factor;
let work = prove_work(phrase.clone(), salt, difficulty_factor);
// let config = ConfigBuilder::default().salt(salt.into()).build().unwrap();
// let work = config.prove_work(&phrase, difficulty_factor).unwrap();
println!("difficulty: {}", &difficulty_factor);
println!("nonce: {}", &work.nonce);
println!("original phrase: {}", &phrase);
println!("result: {}", &work.result);
}
Args::Online(matches) => {
let sitekey = matches.extract_sitekey();
if sitekey.is_none() { if sitekey.is_none() {
println!("ERROR: Sitekey not found in URL. Please enter correct URL"); println!("ERROR: Sitekey not found in URL. Please enter correct URL");
@ -101,8 +72,7 @@ async fn main() {
} }
let sitekey = sitekey.unwrap(); let sitekey = sitekey.unwrap();
let c = Client::default(); let url = self.get_config_url();
let url = matches.get_config_url();
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
struct ConfigRequest { struct ConfigRequest {
@ -157,7 +127,7 @@ async fn main() {
time, time,
worker_type: String::from("mCaptcha CLI"), worker_type: String::from("mCaptcha CLI"),
}; };
let url = matches.get_verify_url(); let url = self.get_verify_url();
let resp: VerifyResp = c let resp: VerifyResp = c
.post(url) .post(url)
.json(&req) .json(&req)
@ -169,5 +139,71 @@ async fn main() {
.unwrap(); .unwrap();
println!("Authorization token: {}", resp.token); println!("Authorization token: {}", resp.token);
} }
fn extract_sitekey(&self) -> Option<String> {
let mut sitekey = None;
for (k, v) in self.url.query_pairs() {
if &k == "sitekey" {
let x: &str = &v;
sitekey = Some(x.to_string())
}
}
sitekey
}
fn get_config_url(&self) -> Url {
let mut url = self.url.clone();
url.set_path("/api/v1/pow/config");
url
}
fn get_verify_url(&self) -> Url {
let mut url = self.url.clone();
url.set_path("/api/v1/pow/verify");
url
}
}
#[derive(Deserialize, Parser, Serialize, Clone, Debug)]
#[command(author, version, about, long_about = None)]
enum Args {
Offline(Offline),
ProtectedPage(ProtectedPage),
WidgetUrl(WidgetUrl),
}
fn prove_work(phrase: String, salt: String, difficulty_factor: u32) -> PoW<String> {
let config = ConfigBuilder::default().salt(salt).build().unwrap();
config.prove_work(&phrase, difficulty_factor).unwrap()
}
#[tokio::main]
async fn main() {
let args = Args::parse();
match args {
Args::Offline(matches) => {
let phrase = matches.phrase;
let salt = matches.salt;
let difficulty_factor = matches.difficulty_factor;
let work = prove_work(phrase.clone(), salt, difficulty_factor);
// let config = ConfigBuilder::default().salt(salt.into()).build().unwrap();
// let work = config.prove_work(&phrase, difficulty_factor).unwrap();
println!("difficulty: {}", &difficulty_factor);
println!("nonce: {}", &work.nonce);
println!("original phrase: {}", &phrase);
println!("result: {}", &work.result);
}
Args::WidgetUrl(matches) => {
matches.run().await;
}
Args::ProtectedPage(matches) => {
let widget = matches
.extract_url()
.await
.unwrap_or_else(|| panic!("No mCaptcha widget found in the web page"));
widget.run().await;
}
} }
} }