Compare commits

...

43 Commits

Author SHA1 Message Date
Aravinth Manivannan
6f029d2945 fix: associate challenges with usernames 2023-06-17 16:13:48 +05:30
Aravinth Manivannan
e7b01a5b06 feat: impl auth challenges interfaces for pg 2023-06-13 19:26:21 +05:30
Aravinth Manivannan
0cfffed52e feat: impl auth challenges interfaces for mariadb 2023-06-13 19:24:03 +05:30
Aravinth Manivannan
c53fe2e3ff feat: define internfaces to create,fetch and rm auth challenges 2023-06-13 19:23:23 +05:30
Aravinth Manivannan
78de0b266f Merge pull request #77 from mCaptcha/nighwatch
Integration testing using Nighwatch (firefox + chromium)
2023-05-25 21:23:37 +05:30
Aravinth Manivannan
6ede578ad5 Merge pull request #83 from Benjamin-Loison/master
Correct a typo and add necessary spaces in `README.md`
2023-05-25 21:08:10 +05:30
Aravinth Manivannan
efed5f5f93 Merge pull request #82 from Supernova3339/patch-1
🐛 Typo fix in Documentation
2023-05-25 21:05:08 +05:30
Benjamin Loison
4a6850631a Correct a typo and add necessary spaces in README.md 2023-05-23 15:08:55 +02:00
SuperDev
0adbb0aa2f Update CONFIGURATION.md
FIx typo in documentation
2023-05-18 12:44:39 -05:00
Aravinth Manivannan
8f3faaa279 Merge pull request #75 from WizardTales/licensefix
fix(license): accidential AGPL in MIT licensed files
2023-05-01 16:02:58 +05:30
Aravinth Manivannan
5324969bd2 feat: install selenium drivers 2023-04-30 23:46:58 +05:30
Aravinth Manivannan
43dab030df feat: run nightwatch integration tests on CI 2023-04-30 20:18:47 +05:30
Aravinth Manivannan
9cc667851c feat: run integration tests using nightwatch js 2023-04-30 20:17:51 +05:30
Tobias Gurtzick
9fc7c31083 fix(license): accidential AGPL in MIT licensed files
fixes #69

Signed-off-by: Tobias Gurtzick <magic@wizardtales.com>
2023-04-18 11:20:12 +02:00
Aravinth Manivannan
90e60b0486 Merge pull request #70 from mCaptcha/fix-53
fix: update libmcaptcha to use connection manager
2023-03-31 17:29:58 +05:30
Aravinth Manivannan
58f93cb602 fix: update libmcaptcha to use connection manager
closes: https://github.com/mCaptcha/mCaptcha/issues/53
2023-03-31 16:20:13 +05:30
Aravinth Manivannan
fae50b19f8 Merge pull request #67 from mCaptcha/dependabot/cargo/openssl-0.10.48
chore(deps): bump openssl from 0.10.41 to 0.10.48
2023-03-25 11:43:57 +05:30
dependabot[bot]
e890ba0f57 chore(deps): bump openssl from 0.10.41 to 0.10.48
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.41 to 0.10.48.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.48)

---
updated-dependencies:
- dependency-name: openssl
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-25 05:03:34 +00:00
Aravinth Manivannan
744d94cf8d Merge pull request #66 from mCaptcha/dependabot/npm_and_yarn/docs/openapi/minimist-1.2.8
chore(deps): bump minimist from 1.2.5 to 1.2.8 in /docs/openapi
2023-03-25 10:33:03 +05:30
Aravinth Manivannan
31d12206aa feat: add NLnet funding details 2023-03-08 17:08:39 +05:30
dependabot[bot]
7764eda05d chore(deps): bump minimist from 1.2.5 to 1.2.8 in /docs/openapi
Bumps [minimist](https://github.com/minimistjs/minimist) from 1.2.5 to 1.2.8.
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.8)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 12:38:56 +00:00
Aravinth Manivannan
f78669955c Merge pull request #60 from mCaptcha/fix-59
fix: copy OpenAPI build from build container to final container
2023-01-17 04:26:20 +05:30
Aravinth Manivannan
cadc15a7a1 fix: copy OpenAPI build from build container to final container
fixes: https://github.com/mCaptcha/mCaptcha/issues/59
2023-01-17 03:54:54 +05:30
Aravinth Manivannan
c1f6ce3ae2 Merge pull request #52 from Gusted/close-register-page
Hide register page when registrations are closed
2022-11-07 13:39:34 +05:30
Gusted
864549cb4c Fix copyright 2022-11-06 19:42:22 +01:00
Gusted
5713d4b1ae Hide register page when registrations are closed
- Improve UX for "private" instances.
2022-10-24 22:47:07 +02:00
Aravinth Manivannan
ac502b7c08 Merge pull request #51 from Gusted/fix-compiling
Fix compiling
2022-10-24 21:22:34 +05:30
Gusted
8dc690ca01 Remove redunant format 2022-10-24 16:22:10 +02:00
Gusted
a4f9c92b32 Update cargo 2022-10-22 21:53:18 +02:00
Gusted
8826f6df8f Fix compiling
- I made some mistakes while checking my two previous PRs(Seems like I
don't understand Rust that great after all).
- Do the url encoding only on the password part, not only the whole URL.
- Fix `temporary value dropped while borrowed` compile error.
2022-10-22 21:28:58 +02:00
Aravinth Manivannan
af35fdb48e Merge pull request #46 from Gusted/relax-port-env
Allow `PORT` environment to be not set
2022-10-18 15:51:22 +05:30
Gusted
9fd8ffd666 Add more logging for configuration/env 2022-10-17 19:49:42 +02:00
Aravinth Manivannan
521abd82d6 Merge pull request #47 from Gusted/encode-url-postgres
Encode connection URL to database
2022-10-17 15:42:02 +05:30
Gusted
021f2fe5b4 Encode connection URL to database
- If you have a database password that contains characters like `#` or `*`, sqlx
will error about a InvalidPort, this is due to not encoding the url.
[See issue on sqlx](https://github.com/launchbadge/sqlx/issues/1624).
- Removed useless statements.
2022-10-16 23:37:24 +02:00
Gusted
b3e0ff6769 Allow PORT environment to be not set
- It's quite weird to require the `PORT` environment to be set, when it
already can be set via the config file.
2022-10-16 23:07:10 +02:00
Aravinth Manivannan
97abca2520 Merge pull request #45 from DarianAnjuhal/master
feat: open mail link with target=_blank
2022-10-12 15:28:13 +05:30
Daniel Antlinger
96a6c98c10 feat: open mail link with target=_blank 2022-10-12 11:50:55 +02:00
realaravinth
9d285573d7 fix: typo in widget 2022-09-26 16:40:40 +05:30
Aravinth Manivannan
d506d291c3 Merge pull request #43 from DarianAnjuhal/master
feat: open links from widget in new pages target=_blank
2022-09-07 23:31:56 +05:30
Daniel Antlinger
223e8fb8c2 feat: open links from widget in new pages target=_blank 2022-09-07 14:05:25 +02:00
realaravinth
2abf57d16b fix: set correct upload dir 2022-08-15 18:01:41 +05:30
realaravinth
b3ee57d042 fix: configure gpg key 2022-08-15 17:37:48 +05:30
realaravinth
8c65edd257 fix: upload path 2022-08-15 17:25:22 +05:30
27 changed files with 918 additions and 158 deletions

View File

@@ -82,7 +82,7 @@ jobs:
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: configure GPG key - name: configure GPG key
if: (github.ref == 'refs/heads/master' || github.event_name == 'push') && github.repository == 'realaravinth/dumbserve' if: (github.ref == 'refs/heads/master' || github.event_name == 'push') && github.repository == 'mCaptcha/mCaptcha'
run: echo -n "$RELEASE_BOT_GPG_SIGNING_KEY" | gpg --batch --import --pinentry-mode loopback run: echo -n "$RELEASE_BOT_GPG_SIGNING_KEY" | gpg --batch --import --pinentry-mode loopback
env: env:
RELEASE_BOT_GPG_SIGNING_KEY: ${{ secrets.RELEASE_BOT_GPG_SIGNING_KEY }} RELEASE_BOT_GPG_SIGNING_KEY: ${{ secrets.RELEASE_BOT_GPG_SIGNING_KEY }}
@@ -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

203
Cargo.lock generated
View File

@@ -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]]
@@ -3386,9 +3383,9 @@ dependencies = [
[[package]] [[package]]
name = "urlencoding" name = "urlencoding"
version = "2.1.0" version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821" checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
[[package]] [[package]]
name = "utf-8" name = "utf-8"
@@ -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"

View File

@@ -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]

View File

@@ -38,6 +38,7 @@ COPY --from=cacher /src/target target
#COPY --from=cacher /src/db/db-migrations/target /src/db/db-migrations/target #COPY --from=cacher /src/db/db-migrations/target /src/db/db-migrations/target
#COPY --from=cacher /src/utils/cache-bust/target /src/utils/cache-bust/target #COPY --from=cacher /src/utils/cache-bust/target /src/utils/cache-bust/target
COPY --from=frontend /src/static/cache/bundle/ /src/static/cache/bundle/ COPY --from=frontend /src/static/cache/bundle/ /src/static/cache/bundle/
COPY --from=frontend /src/docs/openapi/dist/ /src/docs/openapi/dist/
RUN cargo --version RUN cargo --version
RUN make cache-bust RUN make cache-bust
RUN cargo build --release RUN cargo build --release

View File

@@ -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

View File

@@ -32,11 +32,11 @@ 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:
@@ -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
@@ -68,7 +68,7 @@ to their request.
- [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.
@@ -95,7 +95,7 @@ monitor console and network activity.
> 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:
@@ -112,7 +112,6 @@ After the containers are up, visit [http://localhost:7000](http://localhost:7000
- 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 :)
See [DEPLOYMENT.md](./docs/DEPLOYMENT.md) detailed alternate deployment See [DEPLOYMENT.md](./docs/DEPLOYMENT.md) detailed alternate deployment
@@ -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.

View File

@@ -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 = []

View File

@@ -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)]

View File

@@ -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())
} }

View File

@@ -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
);

View File

@@ -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": [],

View File

@@ -73,9 +73,6 @@ impl Connect for ConnectionOptions {
if fresh.disable_logging { if fresh.disable_logging {
connect_options.disable_statement_logging(); connect_options.disable_statement_logging();
} }
sqlx::mysql::MySqlConnectOptions::from_str(&fresh.url)
.unwrap()
.disable_statement_logging();
fresh fresh
.pool_options .pool_options
.connect_with(connect_options) .connect_with(connect_options)
@@ -98,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(())
} }
} }
@@ -898,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)]

View File

@@ -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()
);

View File

@@ -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": [

View File

@@ -73,9 +73,6 @@ impl Connect for ConnectionOptions {
if fresh.disable_logging { if fresh.disable_logging {
connect_options.disable_statement_logging(); connect_options.disable_statement_logging();
} }
sqlx::postgres::PgConnectOptions::from_str(&fresh.url)
.unwrap()
.disable_statement_logging();
fresh fresh
.pool_options .pool_options
.connect_with(connect_options) .connect_with(connect_options)
@@ -98,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(())
} }
} }
@@ -904,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)]

View File

@@ -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

View File

@@ -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
View 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
View 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

View File

@@ -97,14 +97,15 @@ delete_dir() {
} }
upload_dist() { upload_dist() {
delete_dir $1 upload_dir="mCaptcha/$1"
delete_dir $upload_dir
pushd $TMP_DIR pushd $TMP_DIR
for file in $TARBALL $TARBALL.asc $TARBALL.sha256 for file in $TARBALL $TARBALL.asc $TARBALL.sha256
do do
curl -v \ curl -v \
-F upload=@$file \ -F upload=@$file \
"$DUMBSERVE_HOST/api/v1/files/upload?path=$1/" "$DUMBSERVE_HOST/api/v1/files/upload?path=$upload_dir"
done done
popd popd
} }

View File

@@ -14,8 +14,8 @@
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
use std::env;
use std::path::Path; use std::path::Path;
use std::{env, fs};
use config::{Config, ConfigError, Environment, File}; use config::{Config, ConfigError, Environment, File};
use derive_more::Display; use derive_more::Display;
@@ -152,25 +152,34 @@ impl Settings {
.expect("unable to set capatcha.enable_stats default config"); .expect("unable to set capatcha.enable_stats default config");
if let Ok(path) = env::var("MCAPTCHA_CONFIG") { if let Ok(path) = env::var("MCAPTCHA_CONFIG") {
s.merge(File::with_name(&path))?; let absolute_path = Path::new(&path).canonicalize().unwrap();
log::info!(
"Loading config file from {}",
absolute_path.to_str().unwrap()
);
s.merge(File::with_name(absolute_path.to_str().unwrap()))?;
} else if Path::new(CURRENT_DIR).exists() { } else if Path::new(CURRENT_DIR).exists() {
let absolute_path = fs::canonicalize(CURRENT_DIR).unwrap();
log::info!(
"Loading config file from {}",
absolute_path.to_str().unwrap()
);
// merging default config from file // merging default config from file
s.merge(File::with_name(CURRENT_DIR))?; s.merge(File::with_name(absolute_path.to_str().unwrap()))?;
} else if Path::new(ETC).exists() { } else if Path::new(ETC).exists() {
log::info!("{}", format!("Loading config file from {}", ETC));
s.merge(File::with_name(ETC))?; s.merge(File::with_name(ETC))?;
} else { } else {
log::warn!("configuration file not found"); log::warn!("Configuration file not found");
} }
s.merge(Environment::with_prefix("MCAPTCHA").separator("_"))?; s.merge(Environment::with_prefix("MCAPTCHA").separator("_"))?;
check_url(&s); check_url(&s);
match env::var("PORT") { if let Ok(val) = env::var("PORT") {
Ok(val) => {
s.set("server.port", val).unwrap(); s.set("server.port", val).unwrap();
} log::info!("Overriding [server].port with environment variable");
Err(e) => warn!("couldn't interpret PORT: {}", e),
} }
match env::var("DATABASE_URL") { match env::var("DATABASE_URL") {
@@ -180,6 +189,7 @@ impl Settings {
let database_type = DBType::from_url(&url).unwrap(); let database_type = DBType::from_url(&url).unwrap();
s.set("database.database_type", database_type.to_string()) s.set("database.database_type", database_type.to_string())
.unwrap(); .unwrap();
log::info!("Overriding [database].url and [database].database_type with environment variable");
} }
Err(e) => { Err(e) => {
set_database_url(&mut s); set_database_url(&mut s);
@@ -215,8 +225,11 @@ fn set_database_url(s: &mut Config) {
r"postgres://{}:{}@{}:{}/{}", r"postgres://{}:{}@{}:{}/{}",
s.get::<String>("database.username") s.get::<String>("database.username")
.expect("Couldn't access database username"), .expect("Couldn't access database username"),
urlencoding::encode(
s.get::<String>("database.password") s.get::<String>("database.password")
.expect("Couldn't access database password"), .expect("Couldn't access database password")
.as_str()
),
s.get::<String>("database.hostname") s.get::<String>("database.hostname")
.expect("Couldn't access database hostname"), .expect("Couldn't access database hostname"),
s.get::<String>("database.port") s.get::<String>("database.port")

View File

@@ -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/>.
*/ */
* { * {

View File

@@ -8,6 +8,16 @@
class="auth__logo" alt="mcaptcha logo" /> class="auth__logo" alt="mcaptcha logo" />
<. if !crate::SETTINGS.allow_registration { .>
<table class="reg-closed__table">
<thead class="reg-closed__table-heading">
<tr><th colspan="4" class="reg-closed__table-title-text">Registration closed</th></tr>
</thead>
<tbody class="reg-closed__body">
<tr><td class="reg-closed__body-text">This mCaptcha instance is closed for registrations.</td></tr>
</tbody>
</table>
<. } else {.>
<form <form
method="POST" method="POST"
action="<.= crate::V1_API_ROUTES.auth.register .>" action="<.= crate::V1_API_ROUTES.auth.register .>"
@@ -73,5 +83,6 @@
<a href="<.= crate::PAGES.auth.login .>" class="auth__secondary-action__link">Log in</a> <a href="<.= crate::PAGES.auth.login .>" class="auth__secondary-action__link">Log in</a>
</p> </p>
<. include!("../demo-user-banner.html"); .> <. include!("../demo-user-banner.html"); .>
<. } .>
</div> </div>
<. include!("../../components/footers.html"); .> <. include!("../../components/footers.html"); .>

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2022 Gusted <postmaster@gusted.xyz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 '../../components/table/main';
.reg-closed__table {
@include table;
margin: auto;
}
.reg-closed__table-title-text {
@include table__title-text;
}
.reg-closed__body-text {
display: block;
margin: 0.5em 0;
}

View File

@@ -19,11 +19,12 @@
<span id="widget__verification-text--before">I'm not a robot</span> <span id="widget__verification-text--before">I'm not a robot</span>
<span id="widget__verification-text--during">Processing...</span> <span id="widget__verification-text--during">Processing...</span>
<span id="widget__verification-text--after">Verified!</span> <span id="widget__verification-text--after">Verified!</span>
<span id="widget__verification-text--error">Something wen't wrong</span> <span id="widget__verification-text--error">Something went wrong</span>
</label> </label>
<div class="widget__mcaptcha-details"> <div class="widget__mcaptcha-details">
<a href="<.= crate::PKG_HOMEPAGE .>" <a href="<.= crate::PKG_HOMEPAGE .>"
class="widget__mcaptcha-logo-container" class="widget__mcaptcha-logo-container"
target="_blank"
> >
<img <img
class="widget__mcaptcha-logo" class="widget__mcaptcha-logo"
@@ -34,10 +35,12 @@
</a> </a>
<div class="widget__mcaptcha-info-container"> <div class="widget__mcaptcha-info-container">
<a class="widget__mcaptcha-info-link" <a class="widget__mcaptcha-info-link"
target="_blank"
href="<.= crate::PKG_HOMEPAGE .><.= crate::PAGES.privacy .>"> href="<.= crate::PKG_HOMEPAGE .><.= crate::PAGES.privacy .>">
Privacy Privacy
</a> </a>
<a class="widget__mcaptcha-info-link" <a class="widget__mcaptcha-info-link"
target="_blank"
href="<.= crate::PKG_HOMEPAGE .><.= crate::PAGES.security .>"> href="<.= crate::PKG_HOMEPAGE .><.= crate::PAGES.security .>">
Terms Terms
</a> </a>

View File

@@ -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;

View File

@@ -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");