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
help Print this message or the help of the given subcommand(s) widget-url Compute PoW by fetching parameters from CAPTCHA URL
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,14 +31,114 @@ 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 {
async fn extract_url(self) -> Option<WidgetUrl> {
let c = Client::default();
let text = c.get(self.url).send().await.unwrap().text().await.unwrap();
let fragement = Html::parse_fragment(&text);
let selector = Selector::parse("label#mcaptcha__token-label").unwrap();
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 });
}
}
}
None
}
}
#[derive(Deserialize, Parser, Serialize, Clone, Debug)]
/// Compute PoW by fetching parameters from CAPTCHA URL
struct WidgetUrl {
url: Url,
}
impl WidgetUrl {
async fn run(&self) {
let c = Client::default();
let sitekey = self.extract_sitekey();
if sitekey.is_none() {
println!("ERROR: Sitekey not found in URL. Please enter correct URL");
return;
}
let sitekey = sitekey.unwrap();
let url = self.get_config_url();
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ConfigRequest {
key: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ConfigResp {
string: String,
difficulty_factor: u32,
salt: String,
}
let req = ConfigRequest {
key: sitekey.to_string(),
};
let resp: ConfigResp = c
.post(url)
.json(&req)
.send()
.await
.unwrap()
.json()
.await
.unwrap();
let start = Instant::now();
let work = prove_work(resp.string.clone(), resp.salt, resp.difficulty_factor);
let finish = Instant::now();
let time_elapsed = finish.duration_since(start);
let time = time_elapsed.as_millis() as usize;
#[derive(Clone, Debug, Serialize, Deserialize)]
struct VerifyRequest {
key: String,
nonce: u64,
result: String,
string: String,
time: usize,
worker_type: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct VerifyResp {
token: String,
}
let req = VerifyRequest {
key: sitekey.clone(),
nonce: work.nonce,
result: work.result,
string: resp.string,
time,
worker_type: String::from("mCaptcha CLI"),
};
let url = self.get_verify_url();
let resp: VerifyResp = c
.post(url)
.json(&req)
.send()
.await
.unwrap()
.json()
.await
.unwrap();
println!("Authorization token: {}", resp.token);
}
fn extract_sitekey(&self) -> Option<String> { fn extract_sitekey(&self) -> Option<String> {
let mut sitekey = None; let mut sitekey = None;
for (k, v) in self.url.query_pairs() { for (k, v) in self.url.query_pairs() {
@ -67,7 +168,8 @@ impl Online {
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
enum Args { enum Args {
Offline(Offline), Offline(Offline),
Online(Online), ProtectedPage(ProtectedPage),
WidgetUrl(WidgetUrl),
} }
fn prove_work(phrase: String, salt: String, difficulty_factor: u32) -> PoW<String> { fn prove_work(phrase: String, salt: String, difficulty_factor: u32) -> PoW<String> {
@ -92,82 +194,16 @@ async fn main() {
println!("original phrase: {}", &phrase); println!("original phrase: {}", &phrase);
println!("result: {}", &work.result); println!("result: {}", &work.result);
} }
Args::Online(matches) => { Args::WidgetUrl(matches) => {
let sitekey = matches.extract_sitekey(); matches.run().await;
}
if sitekey.is_none() { Args::ProtectedPage(matches) => {
println!("ERROR: Sitekey not found in URL. Please enter correct URL"); let widget = matches
return; .extract_url()
}
let sitekey = sitekey.unwrap();
let c = Client::default();
let url = matches.get_config_url();
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ConfigRequest {
key: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ConfigResp {
string: String,
difficulty_factor: u32,
salt: String,
}
let req = ConfigRequest {
key: sitekey.to_string(),
};
let resp: ConfigResp = c
.post(url)
.json(&req)
.send()
.await .await
.unwrap() .unwrap_or_else(|| panic!("No mCaptcha widget found in the web page"));
.json() widget.run().await;
.await
.unwrap();
let start = Instant::now();
let work = prove_work(resp.string.clone(), resp.salt, resp.difficulty_factor);
let finish = Instant::now();
let time_elapsed = finish.duration_since(start);
let time = time_elapsed.as_millis() as usize;
#[derive(Clone, Debug, Serialize, Deserialize)]
struct VerifyRequest {
key: String,
nonce: u64,
result: String,
string: String,
time: usize,
worker_type: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct VerifyResp {
token: String,
}
let req = VerifyRequest {
key: sitekey.clone(),
nonce: work.nonce,
result: work.result,
string: resp.string,
time,
worker_type: String::from("mCaptcha CLI"),
};
let url = matches.get_verify_url();
let resp: VerifyResp = c
.post(url)
.json(&req)
.send()
.await
.unwrap()
.json()
.await
.unwrap();
println!("Authorization token: {}", resp.token);
} }
} }
} }