mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
Compare commits
22 Commits
fix-59
...
wip-mail-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f029d2945 | ||
|
|
e7b01a5b06 | ||
|
|
0cfffed52e | ||
|
|
c53fe2e3ff | ||
|
|
78de0b266f | ||
|
|
6ede578ad5 | ||
|
|
efed5f5f93 | ||
|
|
4a6850631a | ||
|
|
0adbb0aa2f | ||
|
|
8f3faaa279 | ||
|
|
5324969bd2 | ||
|
|
43dab030df | ||
|
|
9cc667851c | ||
|
|
9fc7c31083 | ||
|
|
90e60b0486 | ||
|
|
58f93cb602 | ||
|
|
fae50b19f8 | ||
|
|
e890ba0f57 | ||
|
|
744d94cf8d | ||
|
|
31d12206aa | ||
|
|
7764eda05d | ||
|
|
f78669955c |
6
.github/workflows/linux.yml
vendored
6
.github/workflows/linux.yml
vendored
@@ -104,6 +104,9 @@ jobs:
|
|||||||
profile: minimal
|
profile: minimal
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
- name: install nightwatch dep
|
||||||
|
run: sudo apt-get install xvfb
|
||||||
|
|
||||||
- name: Run migrations
|
- name: Run migrations
|
||||||
run: make migrate
|
run: make migrate
|
||||||
env:
|
env:
|
||||||
@@ -128,6 +131,9 @@ jobs:
|
|||||||
POSTGRES_DATABASE_URL: "${{ env.POSTGRES_DATABASE_URL }}"
|
POSTGRES_DATABASE_URL: "${{ env.POSTGRES_DATABASE_URL }}"
|
||||||
MARIA_DATABASE_URL: "${{ env.MARIA_DATABASE_URL }}"
|
MARIA_DATABASE_URL: "${{ env.MARIA_DATABASE_URL }}"
|
||||||
|
|
||||||
|
- name: run integration tests
|
||||||
|
run: make test.integration
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
if: (github.ref == 'refs/heads/master' || github.event_name == 'push') && github.repository == 'mCaptcha/mCaptcha'
|
if: (github.ref == 'refs/heads/master' || github.event_name == 'push') && github.repository == 'mCaptcha/mCaptcha'
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
|
|||||||
199
Cargo.lock
generated
199
Cargo.lock
generated
@@ -376,13 +376,19 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arc-swap"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argon2-creds"
|
name = "argon2-creds"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "git+https://github.com/realaravinth/argon2-creds?branch=master#9f43fd564448cae609d148a700de91e2aea6474c"
|
source = "git+https://github.com/realaravinth/argon2-creds?branch=master#9f43fd564448cae609d148a700de91e2aea6474c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"derive_builder 0.11.1",
|
"derive_builder",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -597,7 +603,7 @@ version = "0.2.0"
|
|||||||
source = "git+https://github.com/realaravinth/cache-buster#7ca4545722fb99be30698a5e72c7d982a70fa11f"
|
source = "git+https://github.com/realaravinth/cache-buster#7ca4545722fb99be30698a5e72c7d982a70fa11f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"derive_builder 0.11.1",
|
"derive_builder",
|
||||||
"mime",
|
"mime",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"serde 1.0.143",
|
"serde 1.0.143",
|
||||||
@@ -867,6 +873,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -904,34 +911,13 @@ dependencies = [
|
|||||||
"pem-rfc7468",
|
"pem-rfc7468",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_builder"
|
|
||||||
version = "0.10.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30"
|
|
||||||
dependencies = [
|
|
||||||
"derive_builder_macro 0.10.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_builder"
|
name = "derive_builder"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11d918e7dabe374a51dae0f29d818fece3b218b8b4eabec3bc4d42c537e7ed8f"
|
checksum = "11d918e7dabe374a51dae0f29d818fece3b218b8b4eabec3bc4d42c537e7ed8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_builder_macro 0.11.1",
|
"derive_builder_macro",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_builder_core"
|
|
||||||
version = "0.10.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5"
|
|
||||||
dependencies = [
|
|
||||||
"darling",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -946,23 +932,13 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_builder_macro"
|
|
||||||
version = "0.10.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73"
|
|
||||||
dependencies = [
|
|
||||||
"derive_builder_core 0.10.2",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_builder_macro"
|
name = "derive_builder_macro"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8a2ac71b4a9a590dde6cee3ca4687aca5e7ce06f4ee297c5a959de5f1e42b2e"
|
checksum = "a8a2ac71b4a9a590dde6cee3ca4687aca5e7ce06f4ee297c5a959de5f1e42b2e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_builder_core 0.11.1",
|
"derive_builder_core",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1108,7 +1084,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"windows-sys",
|
"windows-sys 0.36.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1593,9 +1569,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.129"
|
version = "0.2.140"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64de3cc433455c14174d42e554d4027ee631c4d046d43e3ecc6efc4636cdc7a7"
|
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
@@ -1606,11 +1582,11 @@ checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "libmcaptcha"
|
name = "libmcaptcha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "git+https://github.com/mCaptcha/libmcaptcha?branch=master#4efe8cdfee94766dd85647ad6f1ecc1b486b40a7"
|
source = "git+https://github.com/mCaptcha/libmcaptcha?branch=master#22e3cb1a1c774ed352da17e4919e1ee177264e07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix",
|
"actix",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"derive_builder 0.10.2",
|
"derive_builder",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"log",
|
"log",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
@@ -1725,7 +1701,7 @@ dependencies = [
|
|||||||
"db-core",
|
"db-core",
|
||||||
"db-sqlx-maria",
|
"db-sqlx-maria",
|
||||||
"db-sqlx-postgres",
|
"db-sqlx-postgres",
|
||||||
"derive_builder 0.11.1",
|
"derive_builder",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"futures",
|
"futures",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -1805,7 +1781,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys",
|
"windows-sys 0.36.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2002,9 +1978,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.41"
|
version = "0.10.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
@@ -2043,9 +2019,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.75"
|
version = "0.9.83"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -2100,7 +2076,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-sys",
|
"windows-sys 0.36.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2220,7 +2196,7 @@ version = "0.3.1"
|
|||||||
source = "git+https://github.com/mcaptcha/pow_sha256?tag=0.3.1#3b4e28706a8946987ba02f98e1f816d9fa156dad"
|
source = "git+https://github.com/mcaptcha/pow_sha256?tag=0.3.1#3b4e28706a8946987ba02f98e1f816d9fa156dad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"derive_builder 0.11.1",
|
"derive_builder",
|
||||||
"num",
|
"num",
|
||||||
"serde 1.0.143",
|
"serde 1.0.143",
|
||||||
"sha2 0.10.2",
|
"sha2 0.10.2",
|
||||||
@@ -2229,10 +2205,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pow_sha256"
|
name = "pow_sha256"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/mcaptcha/pow_sha256#3b4e28706a8946987ba02f98e1f816d9fa156dad"
|
source = "git+https://github.com/mcaptcha/pow_sha256#148f1cb70d19114d1340661a77b2b679e95715f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"derive_builder 0.11.1",
|
"derive_builder",
|
||||||
"num",
|
"num",
|
||||||
"serde 1.0.143",
|
"serde 1.0.143",
|
||||||
"sha2 0.10.2",
|
"sha2 0.10.2",
|
||||||
@@ -2320,6 +2296,17 @@ version = "0.4.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f"
|
checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r2d2"
|
||||||
|
version = "0.8.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"scheduled-thread-pool",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -2356,15 +2343,18 @@ version = "0.21.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a80b5f38d7f5a020856a0e16e40a9cfabf88ae8f0e4c2dcd8a3114c1e470852"
|
checksum = "1a80b5f38d7f5a020856a0e16e40a9cfabf88ae8f0e4c2dcd8a3114c1e470852"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"combine",
|
"combine",
|
||||||
"crc16",
|
"crc16",
|
||||||
"dtoa",
|
"dtoa",
|
||||||
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"itoa 0.4.8",
|
"itoa 0.4.8",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"r2d2",
|
||||||
"rand",
|
"rand",
|
||||||
"sha1 0.6.1",
|
"sha1 0.6.1",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -2596,7 +2586,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
|
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys",
|
"windows-sys 0.36.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scheduled-thread-pool"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
|
||||||
|
dependencies = [
|
||||||
|
"parking_lot 0.12.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2813,9 +2812,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.4"
|
version = "0.4.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi",
|
"winapi",
|
||||||
@@ -3199,22 +3198,20 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.20.1"
|
version = "1.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581"
|
checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"once_cell",
|
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"winapi",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3396,6 +3393,16 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"serde 1.0.143",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "validator"
|
name = "validator"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
@@ -3597,43 +3604,109 @@ version = "0.36.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.36.1",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.36.1",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.36.1",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.36.1",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.36.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.45.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc 0.42.2",
|
||||||
|
"windows_i686_gnu 0.42.2",
|
||||||
|
"windows_i686_msvc 0.42.2",
|
||||||
|
"windows_x86_64_gnu 0.42.2",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc 0.42.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.42.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ lettre = { version = "0.10.0-rc.3", features = [
|
|||||||
"smtp-transport"
|
"smtp-transport"
|
||||||
]}
|
]}
|
||||||
|
|
||||||
openssl = { version = "0.10.29", features = ["vendored"] }
|
openssl = { version = "0.10.48", features = ["vendored"] }
|
||||||
|
|
||||||
|
|
||||||
[dependencies.db-core]
|
[dependencies.db-core]
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -123,6 +123,9 @@ test: frontend-test frontend ## Run all available tests
|
|||||||
cargo test --no-fail-fast
|
cargo test --no-fail-fast
|
||||||
# ./scripts/tests.sh
|
# ./scripts/tests.sh
|
||||||
|
|
||||||
|
test.integration: ## run integration tests with nightwatch.js
|
||||||
|
./scripts/integration.sh
|
||||||
|
|
||||||
xml-test-coverage: migrate ## Generate code coverage report in XML format
|
xml-test-coverage: migrate ## Generate code coverage report in XML format
|
||||||
$(call cache_bust)
|
$(call cache_bust)
|
||||||
cargo tarpaulin -t 1200 --out Xml
|
cargo tarpaulin -t 1200 --out Xml
|
||||||
|
|||||||
61
README.md
61
README.md
@@ -32,18 +32,18 @@ yourself!](https://demo.mcaptcha.org/widget/?sitekey=pHy0AktWyOKuxZDzFfoaewncWec
|
|||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
|
|
||||||
mCaptcha uses SHA256 based proof-of-work(PoW) to rate limit users.
|
mCaptcha uses SHA256 based proof-of-work (PoW) to rate limit users.
|
||||||
|
|
||||||
When a user wants to do something on an mCaptcha-protected website,
|
When a user wants to do something on a mCaptcha-protected website,
|
||||||
|
|
||||||
1. they will have to generate proof-of-work(a bunch of math that will takes
|
1. they will have to generate proof-of-work (a bunch of math that will takes
|
||||||
time to compute) and submit it to mCaptcha.
|
time to compute) and submit it to mCaptcha.
|
||||||
|
|
||||||
2. We'll validate the proof:
|
2. We'll validate the proof:
|
||||||
|
|
||||||
- **if validation is unsuccessful**, they will be prevented from
|
- **if validation is unsuccessful**, they will be prevented from
|
||||||
accessing their target website
|
accessing their target website
|
||||||
- **if validation is successful**, read on,
|
- **if validation is successful**, read on,
|
||||||
|
|
||||||
3. They will be issued a token that they should submit along
|
3. They will be issued a token that they should submit along
|
||||||
with their request/form submission to the target website.
|
with their request/form submission to the target website.
|
||||||
@@ -54,8 +54,8 @@ When a user wants to do something on an mCaptcha-protected website,
|
|||||||
The whole process is automated from the user's POV. All they have to do
|
The whole process is automated from the user's POV. All they have to do
|
||||||
is click on a button to initiate the process.
|
is click on a button to initiate the process.
|
||||||
|
|
||||||
mCaptcha makes interacting with websites (computationally)expensive for
|
mCaptcha makes interacting with websites (computationally) expensive for
|
||||||
the user. A well-behaving user will experience a slight delay(no delay
|
the user. A well-behaving user will experience a slight delay (no delay
|
||||||
when under moderate load to 2s when under attack; PoW difficulty is
|
when under moderate load to 2s when under attack; PoW difficulty is
|
||||||
variable) but if someone wants to hammer your site, they will have to do
|
variable) but if someone wants to hammer your site, they will have to do
|
||||||
more work to send requests than your server will have to do to respond
|
more work to send requests than your server will have to do to respond
|
||||||
@@ -63,14 +63,14 @@ to their request.
|
|||||||
|
|
||||||
## Why use mCaptcha?
|
## Why use mCaptcha?
|
||||||
|
|
||||||
- [x] **Free software, privacy focused**
|
- [x] **Free software, privacy focused**
|
||||||
- [x] **Seamless UX** - No more annoying CAPTCHAs!
|
- [x] **Seamless UX** - No more annoying CAPTCHAs!
|
||||||
- [x] **No tracking:** Our CAPTCHA routes are cookie free!
|
- [x] **No tracking:** Our CAPTCHA routes are cookie free!
|
||||||
- [x] **IP address independent:** your users are behind a NAT? We got you covered!
|
- [x] **IP address independent:** your users are behind a NAT? We got you covered!
|
||||||
- [x] **Resistant to replay attacks:** proof-of-work configurations have
|
- [x] **Resistant to replay attacks:** proof-of-work configurations have
|
||||||
short lifetimes(30s) and can be used only once. If a user submits a
|
short lifetimes (30s) and can be used only once. If a user submits a
|
||||||
PoW to an already used configuration or an expired one, their proof
|
PoW to an already used configuration or an expired one, their proof
|
||||||
will be rejected.
|
will be rejected.
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
@@ -87,15 +87,15 @@ monitor console and network activity.
|
|||||||
|
|
||||||
### Demo servers are available at:
|
### Demo servers are available at:
|
||||||
|
|
||||||
- https://demo.mcaptcha.org/
|
- https://demo.mcaptcha.org/
|
||||||
- https://demo2.mcaptcha.org/ (runs on a Raspberry Pi!)
|
- https://demo2.mcaptcha.org/ (runs on a Raspberry Pi!)
|
||||||
|
|
||||||
> Core functionality is working but it's still very much
|
> Core functionality is working but it's still very much
|
||||||
> work-in-progress. Since we don't have a stable release yet, hosted
|
> work-in-progress. Since we don't have a stable release yet, hosted
|
||||||
> demo servers might be a few versions behind `master`. Please check footer for
|
> demo servers might be a few versions behind `master`. Please check footer for
|
||||||
> build commit.
|
> build commit.
|
||||||
|
|
||||||
Feel free to provide bogus information while signing up(project under
|
Feel free to provide bogus information while signing up (project under
|
||||||
development, database frequently wiped).
|
development, database frequently wiped).
|
||||||
|
|
||||||
### Self-hosted:
|
### Self-hosted:
|
||||||
@@ -109,9 +109,8 @@ docker-compose up -d
|
|||||||
|
|
||||||
After the containers are up, visit [http://localhost:7000](http://localhost:7000) and login with the default credentials:
|
After the containers are up, visit [http://localhost:7000](http://localhost:7000) and login with the default credentials:
|
||||||
|
|
||||||
- username: aaronsw
|
- username: aaronsw
|
||||||
- password: password
|
- password: password
|
||||||
|
|
||||||
|
|
||||||
It takes a while to build the image so please be patient :)
|
It takes a while to build the image so please be patient :)
|
||||||
|
|
||||||
@@ -129,3 +128,21 @@ See [DEPLOYMENT.md](./docs/DEPLOYMENT.md)
|
|||||||
## Configuration:
|
## Configuration:
|
||||||
|
|
||||||
See [CONFIGURATION.md](./docs/CONFIGURATION.md)
|
See [CONFIGURATION.md](./docs/CONFIGURATION.md)
|
||||||
|
|
||||||
|
## Funding
|
||||||
|
|
||||||
|
### NLnet
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<img
|
||||||
|
height="150px"
|
||||||
|
alt="NLnet NGIZero logo"
|
||||||
|
src="./docs/third-party/NGIZero-green.hex.svg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
2023 development is funded through the [NGI0 Entrust
|
||||||
|
Fund](https://nlnet.nl/entrust), via [NLnet](https://nlnet.nl/). Please
|
||||||
|
see [here](https://nlnet.nl/project/mCaptcha/) for more details.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ serde = { version = "1", features = ["derive"]}
|
|||||||
url = { version = "2.2.2", features = ["serde"] }
|
url = { version = "2.2.2", features = ["serde"] }
|
||||||
#libmcaptcha = { version = "0.2.2", git = "https://github.com/mCaptcha/libmcaptcha", features = ["minimal"], default-features = false, tag = "0.2.2"}
|
#libmcaptcha = { version = "0.2.2", git = "https://github.com/mCaptcha/libmcaptcha", features = ["minimal"], default-features = false, tag = "0.2.2"}
|
||||||
libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
|
libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
|
||||||
|
uuid = { version = "1.3.3", features = ["v4", "serde"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
@@ -31,7 +31,10 @@
|
|||||||
//! - [errors](crate::auth): error data structures used in this crate
|
//! - [errors](crate::auth): error data structures used in this crate
|
||||||
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
||||||
//! connection from pool
|
//! connection from pool
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub use libmcaptcha::defense::Level;
|
pub use libmcaptcha::defense::Level;
|
||||||
|
|
||||||
@@ -97,6 +100,73 @@ pub struct NameHash {
|
|||||||
pub hash: String,
|
pub hash: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
/// Email challenge reason
|
||||||
|
pub enum ChallengeReason {
|
||||||
|
/// challenge created to verify a newly registered user
|
||||||
|
EmailVerification,
|
||||||
|
/// Challenge created to verify a password reset request
|
||||||
|
PasswordReset,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChallengeReason {
|
||||||
|
pub fn to_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::EmailVerification => "email_verification",
|
||||||
|
Self::PasswordReset => "password_resset",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for ChallengeReason {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.to_str().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ChallengeReason {
|
||||||
|
type Err = ();
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
for reason in [Self::PasswordReset, Self::EmailVerification].iter() {
|
||||||
|
if s == reason.to_str() {
|
||||||
|
return Ok(reason.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
/// Minimal user representation for use in challenge verification
|
||||||
|
pub struct ChallengeUser {
|
||||||
|
/// username of the user
|
||||||
|
pub username: String,
|
||||||
|
/// email ID of the user
|
||||||
|
pub email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
/// Email challenge
|
||||||
|
pub struct Challenge {
|
||||||
|
/// challenge unique identifier
|
||||||
|
pub challenge: Uuid,
|
||||||
|
/// reason why the challenge was create
|
||||||
|
pub reason: ChallengeReason,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Challenge {
|
||||||
|
/// create new Challenge instance for a given reason. Challenge text is auto-generated
|
||||||
|
pub fn new(reason: ChallengeReason) -> Self {
|
||||||
|
let challenge = Uuid::new_v4();
|
||||||
|
Self { challenge, reason }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate new ID (useful when ID clashes)
|
||||||
|
pub fn new_id(&mut self) {
|
||||||
|
self.challenge = Uuid::new_v4();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
/// mCaptcha's database requirements. To implement support for $Database, kindly implement this
|
/// mCaptcha's database requirements. To implement support for $Database, kindly implement this
|
||||||
/// trait.
|
/// trait.
|
||||||
@@ -250,6 +320,19 @@ pub trait MCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase {
|
|||||||
|
|
||||||
/// fetch PoWConfig confirms
|
/// fetch PoWConfig confirms
|
||||||
async fn fetch_confirm(&self, user: &str, key: &str) -> DBResult<Vec<i64>>;
|
async fn fetch_confirm(&self, user: &str, key: &str) -> DBResult<Vec<i64>>;
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn new_challenge(&self, user: &str, challenge: &mut Challenge)
|
||||||
|
-> DBResult<()>;
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn fetch_challenge_user(
|
||||||
|
&self,
|
||||||
|
challenge: &Challenge,
|
||||||
|
) -> DBResult<ChallengeUser>;
|
||||||
|
|
||||||
|
/// Delete a challenge from database
|
||||||
|
async fn delete_challenge(&self, challenge: &Challenge) -> DBResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
|
||||||
|
|||||||
@@ -295,4 +295,13 @@ pub async fn database_works<'a, T: MCDatabase>(
|
|||||||
// delete captcha; updated key = p.username so invoke delete with it
|
// delete captcha; updated key = p.username so invoke delete with it
|
||||||
db.delete_captcha(p.username, p.username).await.unwrap();
|
db.delete_captcha(p.username, p.username).await.unwrap();
|
||||||
assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());
|
assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());
|
||||||
|
|
||||||
|
let mut challenge = Challenge::new(ChallengeReason::PasswordReset);
|
||||||
|
db.new_challenge(p.username, &mut challenge).await.unwrap();
|
||||||
|
db.new_challenge(p.username, &mut challenge).await.unwrap();
|
||||||
|
let c = db.fetch_challenge_user(&challenge).await.unwrap();
|
||||||
|
assert_eq!(c.username, p.username);
|
||||||
|
assert_eq!(&c.email, p.email.as_ref().unwrap());
|
||||||
|
db.delete_challenge(&challenge).await.unwrap();
|
||||||
|
assert!(db.fetch_challenge_user(&challenge).await.is_err())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge_reason (
|
||||||
|
id INT auto_increment,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
name VARCHAR(40) NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge (
|
||||||
|
id INT auto_increment,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
reason INT NOT NULL,
|
||||||
|
challenge_id varchar(40) NOT NULL UNIQUE,
|
||||||
|
received timestamp NOT NULL DEFAULT now(),
|
||||||
|
user_id INT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT `fk_mcaptcha_challenge_user`
|
||||||
|
FOREIGN KEY (user_id)
|
||||||
|
REFERENCES mcaptcha_users (ID)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
|
||||||
|
CONSTRAINT `fk_mcaptcha_mcaptcha_challenge_reason`
|
||||||
|
FOREIGN KEY (reason)
|
||||||
|
REFERENCES mcaptcha_challenge_reason (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
|
||||||
|
);
|
||||||
@@ -1,5 +1,53 @@
|
|||||||
{
|
{
|
||||||
"db": "MySQL",
|
"db": "MySQL",
|
||||||
|
"04e79a67bc8c1b18eca95fc4d2602ed5dd41b6d864796f034540efec3da05fa8": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT IGNORE INTO\n mcaptcha_challenge_reason (name)\n VALUES (?)"
|
||||||
|
},
|
||||||
|
"12a7d765fb683c8134d032563f2d101e2fd70c261e71696e7a90387507e0ef43": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": {
|
||||||
|
"char_set": 224,
|
||||||
|
"flags": {
|
||||||
|
"bits": 4101
|
||||||
|
},
|
||||||
|
"max_size": 400,
|
||||||
|
"type": "VarString"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": {
|
||||||
|
"char_set": 224,
|
||||||
|
"flags": {
|
||||||
|
"bits": 4
|
||||||
|
},
|
||||||
|
"max_size": 400,
|
||||||
|
"type": "VarString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "SELECT name, email\n FROM mcaptcha_users\n WHERE ID = (SELECT user_id \n FROM mcaptcha_challenge\n WHERE\n challenge_id = ?\n AND reason = (\n SELECT id FROM mcaptcha_challenge_reason WHERE name = ?\n )\n );"
|
||||||
|
},
|
||||||
"1367dceb151a766a901b5dd771d0b75d0bc61d2fef17a94a90c8ffa0065e2c44": {
|
"1367dceb151a766a901b5dd771d0b75d0bc61d2fef17a94a90c8ffa0065e2c44": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -247,6 +295,16 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT difficulty_factor, visitor_threshold FROM mcaptcha_levels WHERE\n config_id = (\n SELECT config_id FROM mcaptcha_config where captcha_key= (?)\n ) ORDER BY difficulty_factor ASC;"
|
"query": "SELECT difficulty_factor, visitor_threshold FROM mcaptcha_levels WHERE\n config_id = (\n SELECT config_id FROM mcaptcha_config where captcha_key= (?)\n ) ORDER BY difficulty_factor ASC;"
|
||||||
},
|
},
|
||||||
|
"740ed2dab8c07c718c1b0e8e4262251bbf2501cdebfc4872fb903f70ec3d0dc8": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT INTO mcaptcha_challenge (challenge_id, received, reason, user_id)\n VALUES (?, ?,\n (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?),\n (SELECT id FROM mcaptcha_users WHERE name = ?)\n );\n "
|
||||||
|
},
|
||||||
"74d68a86f852d3d85957e94ed04e8acd8e6144744f7b13e383ebcb2bcf3360ae": {
|
"74d68a86f852d3d85957e94ed04e8acd8e6144744f7b13e383ebcb2bcf3360ae": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
@@ -873,6 +931,16 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT name, password FROM mcaptcha_users WHERE email = ?"
|
"query": "SELECT name, password FROM mcaptcha_users WHERE email = ?"
|
||||||
},
|
},
|
||||||
|
"f47c05c0a7da41a2176f08a44c6c945dabb84558a4d09369b6108bfce8b9d2bf": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "DELETE\n FROM mcaptcha_challenge\n WHERE\n challenge_id = ?\n AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);"
|
||||||
|
},
|
||||||
"fc717ff0827ccfaa1cc61a71cc7f71c348ebb03d35895c54b011c03121ad2385": {
|
"fc717ff0827ccfaa1cc61a71cc7f71c348ebb03d35895c54b011c03121ad2385": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
|||||||
@@ -95,6 +95,22 @@ impl Migrate for Database {
|
|||||||
.run(&self.pool)
|
.run(&self.pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
|
||||||
|
for reason in [
|
||||||
|
ChallengeReason::EmailVerification,
|
||||||
|
ChallengeReason::PasswordReset,
|
||||||
|
] {
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT IGNORE INTO
|
||||||
|
mcaptcha_challenge_reason (name)
|
||||||
|
VALUES (?)",
|
||||||
|
reason.to_str()
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,6 +911,93 @@ impl MCDatabase for Database {
|
|||||||
|
|
||||||
Ok(Date::dates_to_unix(records))
|
Ok(Date::dates_to_unix(records))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn new_challenge(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
challenge: &mut Challenge,
|
||||||
|
) -> DBResult<()> {
|
||||||
|
let now = now_unix_time_stamp();
|
||||||
|
loop {
|
||||||
|
let res = sqlx::query!(
|
||||||
|
"INSERT INTO mcaptcha_challenge (challenge_id, received, reason, user_id)
|
||||||
|
VALUES (?, ?,
|
||||||
|
(SELECT id FROM mcaptcha_challenge_reason WHERE name = ?),
|
||||||
|
(SELECT id FROM mcaptcha_users WHERE name = ?)
|
||||||
|
);
|
||||||
|
",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
now,
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
user
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
if let Err(Error::Database(err)) = res {
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
if err.code() == Some(Cow::from("23505")) {
|
||||||
|
let msg = err.message();
|
||||||
|
if msg.contains("for key 'challenge_id'") {
|
||||||
|
challenge.new_id();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn fetch_challenge_user(
|
||||||
|
&self,
|
||||||
|
challenge: &Challenge,
|
||||||
|
) -> DBResult<ChallengeUser> {
|
||||||
|
struct C {
|
||||||
|
name: String,
|
||||||
|
email: Option<String>,
|
||||||
|
}
|
||||||
|
let res = sqlx::query_as!(
|
||||||
|
C,
|
||||||
|
"SELECT name, email
|
||||||
|
FROM mcaptcha_users
|
||||||
|
WHERE ID = (SELECT user_id
|
||||||
|
FROM mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = ?
|
||||||
|
AND reason = (
|
||||||
|
SELECT id FROM mcaptcha_challenge_reason WHERE name = ?
|
||||||
|
)
|
||||||
|
);",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(map_register_err)?;
|
||||||
|
Ok(ChallengeUser {
|
||||||
|
username: res.name,
|
||||||
|
email: res.email.unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete a challenge from database
|
||||||
|
async fn delete_challenge(&self, challenge: &Challenge) -> DBResult<()> {
|
||||||
|
let _ = sqlx::query!(
|
||||||
|
"DELETE
|
||||||
|
FROM mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = ?
|
||||||
|
AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge_reason (
|
||||||
|
id SERIAL PRIMARY KEY NOT NULL,
|
||||||
|
name VARCHAR(40) NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge (
|
||||||
|
id SERIAL PRIMARY KEY NOT NULL,
|
||||||
|
reason INTEGER NOT NULL references mcaptcha_challenge_reason(ID) ON DELETE CASCADE,
|
||||||
|
user_id INTEGER NOT NULL references mcaptcha_users(ID) ON DELETE CASCADE,
|
||||||
|
challenge_id varchar(40) NOT NULL UNIQUE,
|
||||||
|
received timestamptz NOT NULL DEFAULT now()
|
||||||
|
);
|
||||||
@@ -81,6 +81,33 @@
|
|||||||
},
|
},
|
||||||
"query": "DELETE FROM mcaptcha_sitekey_user_provided_avg_traffic\n WHERE config_id = (\n SELECT config_id \n FROM \n mcaptcha_config \n WHERE\n key = ($1) \n AND \n user_id = (SELECT ID FROM mcaptcha_users WHERE name = $2)\n );"
|
"query": "DELETE FROM mcaptcha_sitekey_user_provided_avg_traffic\n WHERE config_id = (\n SELECT config_id \n FROM \n mcaptcha_config \n WHERE\n key = ($1) \n AND \n user_id = (SELECT ID FROM mcaptcha_users WHERE name = $2)\n );"
|
||||||
},
|
},
|
||||||
|
"0fe29ca10e9a83f2064b1b98f570161d339891a74c637077b94d138a4360340e": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Varchar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Varchar"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Text",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "SELECT\n email, name\n FROM\n mcaptcha_users\n WHERE\n ID = (\n SELECT\n user_id\n FROM\n mcaptcha_challenge\n WHERE\n challenge_id = $1\n AND reason = (SELECT ID FROM mcaptcha_challenge_reason WHERE name = $2)\n );"
|
||||||
|
},
|
||||||
"16864df9cf9a69c299d9ab68bac559c48f4fc433541a10f7c1b60717df2b820e": {
|
"16864df9cf9a69c299d9ab68bac559c48f4fc433541a10f7c1b60717df2b820e": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -119,6 +146,21 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT key, name, config_id, duration FROM mcaptcha_config WHERE\n user_id = (SELECT ID FROM mcaptcha_users WHERE name = $1) "
|
"query": "SELECT key, name, config_id, duration FROM mcaptcha_config WHERE\n user_id = (SELECT ID FROM mcaptcha_users WHERE name = $1) "
|
||||||
},
|
},
|
||||||
|
"1e08fab612b17ab3cf3f76cd1543fb4d4006f7c20e09ecb58e1a1cfd5a7e70a2": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Varchar",
|
||||||
|
"Timestamptz",
|
||||||
|
"Text",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT INTO mcaptcha_challenge (challenge_id, received, reason, user_id)\n VALUES ($1, $2, \n (SELECT ID FROM mcaptcha_challenge_reason WHERE name = $3),\n (SELECT ID FROM mcaptcha_users WHERE name = $4)\n );\n "
|
||||||
|
},
|
||||||
"1e9fe69b23e4bfa7bb369455753100307e334e8dbaf02ff37cda08992fe95910": {
|
"1e9fe69b23e4bfa7bb369455753100307e334e8dbaf02ff37cda08992fe95910": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
@@ -427,6 +469,19 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT time FROM mcaptcha_pow_solved_stats \n WHERE config_id = (\n SELECT config_id FROM mcaptcha_config \n WHERE \n key = $1\n AND\n user_id = (\n SELECT \n ID FROM mcaptcha_users WHERE name = $2)) \n ORDER BY time DESC"
|
"query": "SELECT time FROM mcaptcha_pow_solved_stats \n WHERE config_id = (\n SELECT config_id FROM mcaptcha_config \n WHERE \n key = $1\n AND\n user_id = (\n SELECT \n ID FROM mcaptcha_users WHERE name = $2)) \n ORDER BY time DESC"
|
||||||
},
|
},
|
||||||
|
"8a624372ec26200acdbc1c6c330dad841581e9abad586fa7f5a117a7cd289bd9": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Text",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "DELETE\n FROM mcaptcha_challenge\n WHERE\n challenge_id = $1\n AND reason = (SELECT ID FROM mcaptcha_challenge_reason WHERE name = $2);"
|
||||||
|
},
|
||||||
"9753721856a47438c5e72f28fd9d149db10c48e677b4613bf3f1e8487908aac8": {
|
"9753721856a47438c5e72f28fd9d149db10c48e677b4613bf3f1e8487908aac8": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -453,6 +508,18 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT difficulty_factor, visitor_threshold FROM mcaptcha_levels WHERE\n config_id = (\n SELECT config_id FROM mcaptcha_config WHERE key = ($1)\n ) ORDER BY difficulty_factor ASC;"
|
"query": "SELECT difficulty_factor, visitor_threshold FROM mcaptcha_levels WHERE\n config_id = (\n SELECT config_id FROM mcaptcha_config WHERE key = ($1)\n ) ORDER BY difficulty_factor ASC;"
|
||||||
},
|
},
|
||||||
|
"a209d14eb2c2eba8a750d66f74f8edcdbb02cf7c6c5249b226db30f52541a79b": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Varchar"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT INTO\n mcaptcha_challenge_reason (name)\n VALUES ($1) ON CONFLICT DO NOTHING\n "
|
||||||
|
},
|
||||||
"ad196ab3ef9dc32f6de2313577ccd6c26eae9ab19df5f71ce182651983efb99a": {
|
"ad196ab3ef9dc32f6de2313577ccd6c26eae9ab19df5f71ce182651983efb99a": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
|
|||||||
@@ -95,6 +95,23 @@ impl Migrate for Database {
|
|||||||
.run(&self.pool)
|
.run(&self.pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
|
||||||
|
for reason in [
|
||||||
|
ChallengeReason::EmailVerification,
|
||||||
|
ChallengeReason::PasswordReset,
|
||||||
|
] {
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO
|
||||||
|
mcaptcha_challenge_reason (name)
|
||||||
|
VALUES ($1) ON CONFLICT DO NOTHING
|
||||||
|
",
|
||||||
|
reason.to_str()
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -901,6 +918,99 @@ impl MCDatabase for Database {
|
|||||||
|
|
||||||
Ok(Date::dates_to_unix(records))
|
Ok(Date::dates_to_unix(records))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn new_challenge(
|
||||||
|
&self,
|
||||||
|
user: &str,
|
||||||
|
challenge: &mut Challenge,
|
||||||
|
) -> DBResult<()> {
|
||||||
|
let now = now_unix_time_stamp();
|
||||||
|
loop {
|
||||||
|
let res = sqlx::query!(
|
||||||
|
"INSERT INTO mcaptcha_challenge (challenge_id, received, reason, user_id)
|
||||||
|
VALUES ($1, $2,
|
||||||
|
(SELECT ID FROM mcaptcha_challenge_reason WHERE name = $3),
|
||||||
|
(SELECT ID FROM mcaptcha_users WHERE name = $4)
|
||||||
|
);
|
||||||
|
",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
now,
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
user
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
if let Err(Error::Database(err)) = res {
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
if err.code() == Some(Cow::from("23505")) {
|
||||||
|
let msg = err.message();
|
||||||
|
if msg.contains("mcaptcha_challenge_challenge_id_key") {
|
||||||
|
challenge.new_id();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn fetch_challenge_user(
|
||||||
|
&self,
|
||||||
|
challenge: &Challenge,
|
||||||
|
) -> DBResult<ChallengeUser> {
|
||||||
|
struct U {
|
||||||
|
name: String,
|
||||||
|
email: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = sqlx::query_as!(
|
||||||
|
U,
|
||||||
|
"SELECT
|
||||||
|
email, name
|
||||||
|
FROM
|
||||||
|
mcaptcha_users
|
||||||
|
WHERE
|
||||||
|
ID = (
|
||||||
|
SELECT
|
||||||
|
user_id
|
||||||
|
FROM
|
||||||
|
mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = $1
|
||||||
|
AND reason = (SELECT ID FROM mcaptcha_challenge_reason WHERE name = $2)
|
||||||
|
);",
|
||||||
|
challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(map_register_err)?;
|
||||||
|
|
||||||
|
Ok(ChallengeUser {
|
||||||
|
username: res.name,
|
||||||
|
email: res.email.unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete a challenge from database
|
||||||
|
async fn delete_challenge(&self, challenge: &Challenge) -> DBResult<()> {
|
||||||
|
let _ = sqlx::query!(
|
||||||
|
"DELETE
|
||||||
|
FROM mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = $1
|
||||||
|
AND reason = (SELECT ID FROM mcaptcha_challenge_reason WHERE name = $2);",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ you will be overriding the values set in the configuration files.
|
|||||||
| `MCAPTCHA_DATEBASE_USERNAME` | database username |
|
| `MCAPTCHA_DATEBASE_USERNAME` | database username |
|
||||||
| `MCAPTCHA_DATEBASE_POOL` | database connection pool size |
|
| `MCAPTCHA_DATEBASE_POOL` | database connection pool size |
|
||||||
| `MCAPTCHA_DATEBASE_DATABASE_TYPE` | database tpye: "postgres" or "maria" |
|
| `MCAPTCHA_DATEBASE_DATABASE_TYPE` | database tpye: "postgres" or "maria" |
|
||||||
| `DATABSE_URL` (overrides above vars) | database URL in `postgres://user:pass@host:port/dbname` format |
|
| `DATABASE_URL` (overrides above vars) | database URL in `postgres://user:pass@host:port/dbname` format |
|
||||||
|
|
||||||
#### Redis
|
#### Redis
|
||||||
|
|
||||||
|
|||||||
@@ -1799,9 +1799,9 @@ minimatch@3.0.4, minimatch@^3.0.4:
|
|||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.5:
|
minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||||
|
|
||||||
mkdirp@^1.0.4:
|
mkdirp@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
|
|||||||
103
docs/third-party/NGIZero-green.hex.svg
vendored
Normal file
103
docs/third-party/NGIZero-green.hex.svg
vendored
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Ebene_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="165.92125"
|
||||||
|
height="191.45087"
|
||||||
|
viewBox="0 0 165.92125 191.45086"
|
||||||
|
enable-background="new 0 0 198.425 198.425"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="NGIZero-green.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
|
||||||
|
id="metadata4142"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4140" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
id="namedview4138"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.6820179"
|
||||||
|
inkscape:cx="-191.39267"
|
||||||
|
inkscape:cy="54.855534"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Ebene_1"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0" />
|
||||||
|
<polygon
|
||||||
|
points="36.911,63.104 36.911,66.116 36.911,132.309 36.911,135.321 39.346,136.825 96.715,169.921 99.273,171.419 101.853,169.921 159.319,136.825 161.938,135.321 161.938,132.309 161.938,66.116 161.938,63.104 159.308,61.6 101.841,28.504 99.234,27.006 96.629,28.504 39.347,61.6 "
|
||||||
|
id="polygon4013"
|
||||||
|
style="fill:#96c00a;fill-opacity:1"
|
||||||
|
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)" />
|
||||||
|
<polygon
|
||||||
|
points="161.712,62.925 161.712,131.589 99.212,167.589 36.712,131.589 36.712,62.925 99.212,26.925 "
|
||||||
|
id="polygon4015"
|
||||||
|
style="fill:#97bf00;fill-opacity:0.91764706"
|
||||||
|
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)" />
|
||||||
|
<polygon
|
||||||
|
stroke-miterlimit="10"
|
||||||
|
points="157.712,65.379 157.712,133.046 99.212,166.88 40.712,133.046 40.712,65.379 99.212,31.546 "
|
||||||
|
id="Outerline"
|
||||||
|
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:2;stroke-miterlimit:10"
|
||||||
|
inkscape:label="#outerline" />
|
||||||
|
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g4281"
|
||||||
|
transform="matrix(1.3249745,0,0,1.3249745,-47.067006,-23.859001)"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path42"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55783975"
|
||||||
|
d="m 133.45691,60.461638 v 0 c 2.27263,0 4.11462,1.841988 4.11462,4.114628 v 27.330241 c 0,2.27264 -1.84199,4.114628 -4.11462,4.114628 -2.27264,0 -4.11463,-1.841988 -4.11463,-4.114628 V 64.576266 c 0,-2.27264 1.84199,-4.114628 4.11463,-4.114628" /><g
|
||||||
|
transform="matrix(0.55783976,0,0,-0.55783976,120.13631,77.682765)"
|
||||||
|
id="g44"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path46"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 0,0 H -0.506 C -0.57,0 -0.633,-0.008 -0.698,-0.01 -0.762,-0.008 -0.825,0 -0.89,0 h -7.283 c -3.929,0 -7.359,-2.965 -7.613,-6.885 -0.278,-4.296 3.124,-7.867 7.361,-7.867 0.776,0 1.343,-0.754 1.111,-1.494 -0.658,-2.088 -2.341,-3.751 -4.547,-4.333 -2.074,-0.547 -4.276,-0.821 -6.605,-0.821 -4.007,0 -7.574,0.865 -10.7,2.595 -3.127,1.73 -5.57,4.144 -7.331,7.24 -1.761,3.096 -2.641,6.617 -2.641,10.564 0,4.006 0.88,7.558 2.641,10.654 1.761,3.097 4.219,5.493 7.377,7.195 3.156,1.698 6.768,2.549 10.836,2.549 4.681,0 8.865,-1.269 12.55,-3.807 2.341,-1.612 5.524,-1.588 7.757,0.171 3.48,2.741 3.289,8.045 -0.315,10.452 -1.7,1.136 -3.538,2.112 -5.512,2.928 -4.553,1.881 -9.623,2.823 -15.208,2.823 -6.679,0 -12.69,-1.412 -18.03,-4.235 -5.344,-2.822 -9.517,-6.738 -12.522,-11.747 -3.005,-5.008 -4.508,-10.67 -4.508,-16.983 0,-6.315 1.503,-11.975 4.508,-16.984 3.005,-5.009 7.148,-8.924 12.43,-11.747 5.282,-2.824 11.231,-4.235 17.849,-4.235 4.613,0 9.197,0.699 13.751,2.095 0.045,0.014 0.091,0.028 0.136,0.042 7.104,2.202 11.884,8.86 11.884,16.297 v 9.047 C 6.486,-2.904 3.583,0 0,0" /></g><g
|
||||||
|
transform="matrix(0.55783976,0,0,-0.55783976,85.80763,64.525332)"
|
||||||
|
id="g48"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path50"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||||
|
d="m 0,0 v -49.176 c 0,-4.023 -3.262,-7.285 -7.286,-7.285 h -1.381 c -2.181,0 -4.247,0.977 -5.631,2.662 l -24.229,29.505 c -1.804,2.197 -5.368,0.921 -5.368,-1.922 v -22.96 c 0,-4.023 -3.261,-7.285 -7.285,-7.285 -4.023,0 -7.285,3.262 -7.285,7.285 V 0 c 0,4.024 3.262,7.285 7.285,7.285 h 1.468 c 2.184,0 4.253,-0.979 5.636,-2.669 l 24.135,-29.475 c 1.802,-2.202 5.37,-0.927 5.37,1.918 V 0 c 0,4.024 3.261,7.285 7.285,7.285 C -3.262,7.285 0,4.024 0,0" /></g></g><g
|
||||||
|
aria-label="Z E R O"
|
||||||
|
transform="matrix(0.94681934,0,0,0.94681934,-209.97267,182.03385)"
|
||||||
|
style="font-variant:normal;font-weight:600;font-stretch:normal;font-size:31.76000023px;font-family:'Montserrat SemiBold';-inkscape-font-specification:Montserrat-SemiBold;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.7171717;fill-rule:nonzero;stroke:none"
|
||||||
|
id="text56"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m 243.58117,-73.015206 h 19.46231 v 3.613321 l -12.42176,15.02707 h 12.77844 v 4.512774 h -20.17567 v -3.613321 l 12.42176,-15.02707 h -12.06508 z"
|
||||||
|
id="path2325" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m 278.7684,-73.015206 h 16.11262 v 4.512774 h -10.14211 v 4.311172 h 9.5373 v 4.512773 h -9.5373 v 5.303672 h 10.48328 v 4.512774 H 278.7684 Z"
|
||||||
|
id="path2327" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m 320.00367,-62.749034 q 1.87645,0 2.68285,-0.697851 0.82192,-0.697852 0.82192,-2.295157 0,-1.581796 -0.82192,-2.26414 -0.8064,-0.682344 -2.68285,-0.682344 h -2.51226 v 5.939492 z m -2.51226,4.125078 v 8.761915 h -5.97051 v -23.153165 h 9.11859 q 4.57481,0 6.69938,1.535274 2.14008,1.535273 2.14008,4.853945 0,2.295156 -1.11657,3.768399 -1.10105,1.473242 -3.33418,2.171093 1.22512,0.279141 2.18661,1.271641 0.97699,0.976992 1.96949,2.9775 l 3.24113,6.575313 h -6.3582 l -2.82242,-5.753399 q -0.85293,-1.736875 -1.73688,-2.372695 -0.86844,-0.635821 -2.32617,-0.635821 z"
|
||||||
|
id="path2329" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m 357.57911,-69.107237 q -2.72938,0 -4.23364,2.016016 -1.50425,2.016015 -1.50425,5.675859 0,3.644336 1.50425,5.660352 1.50426,2.016015 4.23364,2.016015 2.74488,0 4.24914,-2.016015 1.50426,-2.016016 1.50426,-5.660352 0,-3.659844 -1.50426,-5.675859 -1.50426,-2.016016 -4.24914,-2.016016 z m 0,-4.32668 q 5.58281,0 8.7464,3.19461 3.1636,3.194609 3.1636,8.823945 0,5.613828 -3.1636,8.808438 -3.16359,3.194609 -8.7464,3.194609 -5.56731,0 -8.74641,-3.194609 -3.16359,-3.19461 -3.16359,-8.808438 0,-5.629336 3.16359,-8.823945 3.1791,-3.19461 8.74641,-3.19461 z"
|
||||||
|
id="path2331" /></g></svg>
|
||||||
|
After Width: | Height: | Size: 7.3 KiB |
39
scripts/integration.sh
Executable file
39
scripts/integration.sh
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap cleanup SIGINT SIGTERM ERR EXIT
|
||||||
|
|
||||||
|
readonly PROJECT_ROOT=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
|
||||||
|
|
||||||
|
source $PROJECT_ROOT/scripts/lib.sh
|
||||||
|
|
||||||
|
is_ci(){
|
||||||
|
if [ -z ${CI+x} ];
|
||||||
|
then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
docker-compose down -v --remove-orphans || true
|
||||||
|
docker-compose up -d
|
||||||
|
cd $(mktemp -d)
|
||||||
|
pwd
|
||||||
|
find
|
||||||
|
git clone https://github.com/mCaptcha/integration .
|
||||||
|
|
||||||
|
if is_ci
|
||||||
|
then
|
||||||
|
yarn install
|
||||||
|
xvfb-run --auto-servernum npm run test.chrome
|
||||||
|
xvfb-run --auto-servernum npm run test.firefox
|
||||||
|
else
|
||||||
|
yarn install
|
||||||
|
npx nightwatch ./test/mCaptcha.ts
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $PROJECT_ROOT
|
||||||
|
docker-compose down -v --remove-orphans || true
|
||||||
@@ -1,18 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
* mCaptcha is a PoW based DoS protection software.
|
||||||
|
* This is the frontend web component of the mCaptcha system
|
||||||
|
* Copyright © 2023 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||||
* License, or (at your option) any later version.
|
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
* mCaptcha is a PoW based DoS protection software.
|
||||||
|
* This is the frontend web component of the mCaptcha system
|
||||||
|
* Copyright © 2023 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||||
* License, or (at your option) any later version.
|
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import '../reset';
|
@import "../reset";
|
||||||
|
|
||||||
.widget__contaienr {
|
.widget__contaienr {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
* mCaptcha is a PoW based DoS protection software.
|
||||||
|
* This is the frontend web component of the mCaptcha system
|
||||||
|
* Copyright © 2023 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||||
* License, or (at your option) any later version.
|
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
*/
|
||||||
import prove from "./prove";
|
|
||||||
import { PoWConfig, ServiceWorkerWork } from "./types";
|
|
||||||
import log from "../logger";
|
import log from "../logger";
|
||||||
|
|
||||||
|
import prove from "./prove";
|
||||||
|
import {PoWConfig, ServiceWorkerWork} from "./types";
|
||||||
|
|
||||||
log.log("worker registered");
|
log.log("worker registered");
|
||||||
onmessage = async (e) => {
|
onmessage = async (e) => {
|
||||||
console.debug("message received at worker");
|
console.debug("message received at worker");
|
||||||
|
|||||||
Reference in New Issue
Block a user