mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
Compare commits
24 Commits
aria-label
...
fix-154
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a7e71b499 | ||
|
|
91955501e2 | ||
|
|
cb72b0adfa | ||
|
|
c1fe45d409 | ||
|
|
59e339f287 | ||
|
|
ddcde9cf18 | ||
|
|
65c92ee96e | ||
|
|
40766ff44f | ||
|
|
ddc3008009 | ||
|
|
cba056aba6 | ||
|
|
16c975d2ec | ||
|
|
f67fdf917e | ||
|
|
e1746223c8 | ||
|
|
ae08c09702 | ||
|
|
1c9e242d7e | ||
|
|
3cb0ca38ec | ||
|
|
3cd38511fa | ||
|
|
d765bd7491 | ||
|
|
8e33e75659 | ||
|
|
c00857dd28 | ||
|
|
d010a1cbd4 | ||
|
|
453be36201 | ||
|
|
d4967626ee | ||
|
|
2ee0a0ae5f |
43
.env.docker-compose
Normal file
43
.env.docker-compose
Normal file
@@ -0,0 +1,43 @@
|
||||
MCAPTCHA_debug=false
|
||||
MCAPTCHA_commercial=false
|
||||
MCAPTCHA_source_code=https://github.com/mCaptcha/mCaptcha
|
||||
MCAPTCHA_allow_registration=false
|
||||
MCAPTCHA_allow_demo=false
|
||||
|
||||
# database
|
||||
DATABASE_URL=postgres://postgres:password@mcaptcha_postgres:5432/postgres
|
||||
MCAPTCHA_database_POOL=4
|
||||
|
||||
# redis
|
||||
MCAPTCHA_redis_URL=redis://mcaptcha_redis
|
||||
MCAPTCHA_redis_POOL=4
|
||||
|
||||
# server
|
||||
PORT=7000
|
||||
MCAPTCHA_server_DOMAIN=localhost
|
||||
MCAPTCHA__server_COOKIE_SECRET=pleasereplacethiswithrandomstring # PLEASE SET RANDOM STRING. MIN LENGTH=32
|
||||
MCAPTCHA__server_IP= 0.0.0.0
|
||||
|
||||
|
||||
# captcha
|
||||
MCAPTCHA_captcha_SALT=pleasereplacethiswithrandomstring # PLEASE SET RANDOM STRING. MIN LENGTH=32
|
||||
MCAPTCHA_captcha_GC=30
|
||||
MCAPTCHA_captcha_RUNNERS=4
|
||||
MCAPTCHA_captcha_QUEUE_LENGTH=2000
|
||||
MCAPTCHA_captcha_ENABLE_STATS=true
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_avg_traffic_difficulty=50000 # almost instant solution
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_peak_sustainable_traffic_difficulty=3000000 # greater than 3.5s
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_broke_my_site_traffic_difficulty=5000000 # roughly 1.5s
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_duration=30 # cooldown period in seconds
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_avg_traffic_time=1 # almost instant solution
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_peak_sustainable_traffic_time=3
|
||||
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_broke_my_site_traffic_time=5
|
||||
|
||||
|
||||
# SMTP
|
||||
#MCAPTCHA_smtp_FROM=
|
||||
#MCAPTCHA_smtp_REPLY=
|
||||
#MCAPTCHA_smtp_URL=
|
||||
#MCAPTCHA_smtp_USERNAME=
|
||||
#MCAPTCHA_smtp_PASSWORD=
|
||||
#MCAPTCHA_smtp_PORT=
|
||||
125
.github/workflows/release.yml
vendored
Normal file
125
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
name: Publish release
|
||||
|
||||
on:
|
||||
release:
|
||||
type: [published]
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
name: x86_64-unknown-linux-gnu
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: password
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
mcaptcha-redis:
|
||||
image: mcaptcha/cache
|
||||
ports:
|
||||
- 6379:6379
|
||||
mcaptcha-smtp:
|
||||
image: maildev/maildev
|
||||
env:
|
||||
MAILDEV_WEB_PORT: "1080"
|
||||
MAILDEV_INCOMING_USER: "admin"
|
||||
MAILDEV_INCOMING_PASS: "password"
|
||||
ports:
|
||||
- 1080:1080
|
||||
- 10025:1025
|
||||
|
||||
maria:
|
||||
image: mariadb:10
|
||||
env:
|
||||
MARIADB_USER: "maria"
|
||||
MARIADB_PASSWORD: "password"
|
||||
MARIADB_ROOT_PASSWORD: "password"
|
||||
MARIADB_DATABASE: "maria"
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping"
|
||||
--health-interval=10s
|
||||
--health-timeout=5s
|
||||
--health-retries=10
|
||||
ports:
|
||||
- 3306:3306
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: configure GPG key
|
||||
run: echo -n "$RELEASE_BOT_GPG_SIGNING_KEY" | gpg --batch --import --pinentry-mode loopback
|
||||
env:
|
||||
RELEASE_BOT_GPG_SIGNING_KEY: ${{ secrets.RELEASE_BOT_GPG_SIGNING_KEY }}
|
||||
|
||||
- name: Set release version
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: load env
|
||||
run: |
|
||||
source .env_sample \
|
||||
&& echo "POSTGRES_DATABASE_URL=$POSTGRES_DATABASE_URL" >> $GITHUB_ENV \
|
||||
&& echo "MARIA_DATABASE_URL=$MARIA_DATABASE_URL" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "20.0.0"
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
|
||||
- name: install nightwatch dep
|
||||
run: sudo apt-get install xvfb
|
||||
|
||||
- name: Run migrations
|
||||
run: make migrate
|
||||
env:
|
||||
POSTGRES_DATABASE_URL: "${{ env.POSTGRES_DATABASE_URL }}"
|
||||
MARIA_DATABASE_URL: "${{ env.MARIA_DATABASE_URL }}"
|
||||
|
||||
- name: build
|
||||
run: make
|
||||
env:
|
||||
POSTGRES_DATABASE_URL: "${{ env.POSTGRES_DATABASE_URL }}"
|
||||
MARIA_DATABASE_URL: "${{ env.MARIA_DATABASE_URL }}"
|
||||
|
||||
- name: lint frontend
|
||||
run: yarn lint
|
||||
|
||||
- name: run tests
|
||||
run: make test
|
||||
env:
|
||||
POSTGRES_DATABASE_URL: "${{ env.POSTGRES_DATABASE_URL }}"
|
||||
MARIA_DATABASE_URL: "${{ env.MARIA_DATABASE_URL }}"
|
||||
|
||||
- name: run integration tests
|
||||
run: make test.integration
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: mcaptcha
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: build docker images
|
||||
run: docker build -t mcaptcha/mcaptcha:${RELEASE_VERSION} .
|
||||
|
||||
- name: publish docker images
|
||||
run: docker push mcaptcha/mcaptcha:${RELEASE_VERSION}
|
||||
|
||||
- name: publish bins
|
||||
run: ./scripts/publish.sh publish $RELEASE_VERSION latest $DUMBSERVE_PASSWORD
|
||||
env:
|
||||
DUMBSERVE_PASSWORD: ${{ secrets.DUMBSERVE_PASSWORD }}
|
||||
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}
|
||||
64
.github/workflows/tagged-release.yml
vendored
64
.github/workflows/tagged-release.yml
vendored
@@ -1,32 +1,32 @@
|
||||
name: Create binary for release
|
||||
|
||||
# Only on tags that start with a "v"
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-pc-windows-gnu
|
||||
archive: zip
|
||||
- target: x86_64-unknown-linux-musl
|
||||
archive: tar.gz tar.xz
|
||||
- target: x86_64-apple-darwin
|
||||
archive: zip
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Compile and release
|
||||
uses: rust-build/rust-build.action@v1.3.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
RUSTTARGET: ${{ matrix.target }}
|
||||
ARCHIVE_TYPES: ${{ matrix.archive }}
|
||||
#name: Create binary for release
|
||||
#
|
||||
## Only on tags that start with a "v"
|
||||
#on:
|
||||
# push:
|
||||
# tags:
|
||||
# - "v*"
|
||||
#
|
||||
#jobs:
|
||||
# build:
|
||||
# runs-on: ubuntu-latest
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
# matrix:
|
||||
# include:
|
||||
# - target: x86_64-pc-windows-gnu
|
||||
# archive: zip
|
||||
# - target: x86_64-unknown-linux-musl
|
||||
# archive: tar.gz tar.xz
|
||||
# - target: x86_64-apple-darwin
|
||||
# archive: zip
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v3
|
||||
#
|
||||
# - name: Compile and release
|
||||
# uses: rust-build/rust-build.action@v1.3.2
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# RUSTTARGET: ${{ matrix.target }}
|
||||
# ARCHIVE_TYPES: ${{ matrix.archive }}
|
||||
|
||||
@@ -31,6 +31,10 @@ RUN cargo build --release
|
||||
|
||||
FROM debian:bookworm as mCaptcha
|
||||
LABEL org.opencontainers.image.source https://github.com/mCaptcha/mCaptcha
|
||||
RUN set -ex; \
|
||||
apt-get update; \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get install -y --no-install-recommends curl
|
||||
RUN useradd -ms /bin/bash -u 1001 mcaptcha
|
||||
WORKDIR /home/mcaptcha
|
||||
COPY --from=rust /src/target/release/mcaptcha /usr/local/bin/
|
||||
|
||||
@@ -34,11 +34,11 @@ enable_stats = true
|
||||
|
||||
[captcha.default_difficulty_strategy]
|
||||
avg_traffic_difficulty = 50000 # almost instant solution
|
||||
#avg_traffic_time = 1 # almost instant solution
|
||||
avg_traffic_time = 1 # almost instant solution
|
||||
peak_sustainable_traffic_difficulty = 3000000 # roughly 1.5s
|
||||
#peak_sustainable_traffic_time = 3
|
||||
peak_sustainable_traffic_time = 3
|
||||
broke_my_site_traffic_difficulty = 5000000 # greater than 3.5s
|
||||
#broke_my_site_traffic_time = 5
|
||||
broke_my_site_traffic_time = 5
|
||||
duration = 30 # cooldown period in seconds
|
||||
|
||||
[database]
|
||||
|
||||
@@ -9,11 +9,8 @@ services:
|
||||
image: mcaptcha/mcaptcha:latest
|
||||
ports:
|
||||
- 7000:7000
|
||||
environment:
|
||||
DATABASE_URL: postgres://postgres:password@mcaptcha_postgres:5432/postgres # set password at placeholder
|
||||
MCAPTCHA_redis_URL: "redis://mcaptcha_redis/"
|
||||
RUST_LOG: "debug"
|
||||
PORT: 7000
|
||||
env_file:
|
||||
- .env.docker-compose
|
||||
depends_on:
|
||||
- mcaptcha_postgres
|
||||
- mcaptcha_redis
|
||||
|
||||
@@ -44,6 +44,7 @@ copy() {
|
||||
mkdir $TARGET_DIR/docs
|
||||
cp docs/DEPLOYMENT.md $TARGET_DIR/docs
|
||||
cp docs/CONFIGURATION.md $TARGET_DIR/docs
|
||||
cp config/default.toml $TARGET_DIR/config.toml
|
||||
|
||||
get_bin
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ impl UpdateEasyCaptcha {
|
||||
}
|
||||
|
||||
let mut patterns = data.db.get_all_easy_captchas(limit, offset).await?;
|
||||
if patterns.is_empty() {
|
||||
break;
|
||||
}
|
||||
for pattern in patterns.drain(0..) {
|
||||
if !Self::can_run(rx) {
|
||||
return Ok(());
|
||||
@@ -85,6 +88,7 @@ impl UpdateEasyCaptcha {
|
||||
}
|
||||
page += 1;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn can_run(rx: &mut Receiver<()>) -> bool {
|
||||
|
||||
@@ -21,7 +21,7 @@ SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
<label class="widget__verification-container" for="widget__verification-checkbox">
|
||||
<span id="widget__verification-text"
|
||||
>I'm not a robot</span>
|
||||
<input
|
||||
<input disabled
|
||||
id="widget__verification-checkbox"
|
||||
aria-valuenow="I'm not a robot"
|
||||
aria-checked="false"
|
||||
|
||||
@@ -12,7 +12,17 @@ import * as CONST from "./const";
|
||||
import "./main.scss";
|
||||
|
||||
let LOCK = false;
|
||||
|
||||
const workerPromise = new Promise<Worker>((res) => {
|
||||
const worker = new Worker("/bench.js");
|
||||
worker.onmessage = (event: MessageEvent) => {
|
||||
const message: ServiceWorkerMessage = event.data;
|
||||
if(message.type === "ready") {
|
||||
console.log("worker ready");
|
||||
res(worker);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/** add mcaptcha widget element to DOM */
|
||||
export const registerVerificationEventHandler = (): void => {
|
||||
@@ -20,10 +30,14 @@ export const registerVerificationEventHandler = (): void => {
|
||||
document.querySelector(".widget__verification-container")
|
||||
);
|
||||
verificationContainer.style.display = "flex";
|
||||
CONST.btn().addEventListener("click", (e) => solveCaptchaRunner(e));
|
||||
workerPromise.then((worker: Worker) => {
|
||||
const btn = CONST.btn();
|
||||
btn.disabled = false;
|
||||
btn.addEventListener("click", (e) => solveCaptchaRunner(worker, e));
|
||||
});
|
||||
};
|
||||
|
||||
export const solveCaptchaRunner = async (e: Event): Promise<void> => {
|
||||
export const solveCaptchaRunner = async (worker: Worker, e: Event): Promise<void> => {
|
||||
const PROGRESS_FILL = <HTMLElement>document.querySelector(".progress__fill");
|
||||
|
||||
const setWidth = (width: number) => {
|
||||
@@ -94,7 +108,7 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
|
||||
}
|
||||
if (resp.type === "progress") {
|
||||
if (width < 80) {
|
||||
width = (resp.nonce / max_recorded_nonce) * 100;
|
||||
width = resp.nonce / max_recorded_nonce * 100;
|
||||
setWidth(width);
|
||||
}
|
||||
console.log(`received nonce ${resp.nonce}`);
|
||||
|
||||
@@ -28,6 +28,8 @@ body {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f6f6f6;
|
||||
border: 2px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.widget__noscript-container {
|
||||
@@ -98,6 +100,29 @@ body {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.widget__container {
|
||||
background-color: #1c1c1c;
|
||||
}
|
||||
|
||||
.widget__inner-container {
|
||||
background-color: #1c1c1c;
|
||||
border: 2px solid #656569;
|
||||
}
|
||||
|
||||
.widget__verification-container {
|
||||
color: rgb(232, 230, 227);
|
||||
}
|
||||
|
||||
.widget__mcaptcha-brand-name {
|
||||
color: #7d94f9;
|
||||
}
|
||||
|
||||
.widget__mcaptcha-info-link {
|
||||
color: #7d94f9;
|
||||
}
|
||||
}
|
||||
|
||||
/* progress bar courtesy of https://codepen.io/Bizzy-Coding/pen/poOymVJ?editors=1111 */
|
||||
.progress__bar {
|
||||
position: relative;
|
||||
@@ -113,3 +138,9 @@ body {
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.progress__bar {
|
||||
background: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ const prove = async (
|
||||
config.string,
|
||||
config.difficulty_factor,
|
||||
STEPS,
|
||||
progress
|
||||
(nonce: BigInt | number) => progress(Number(nonce))
|
||||
);
|
||||
const t1 = performance.now();
|
||||
time = t1 - t0;
|
||||
|
||||
@@ -9,6 +9,12 @@ import prove from "./prove";
|
||||
import { PoWConfig, ServiceWorkerMessage, ServiceWorkerWork } from "./types";
|
||||
|
||||
log.log("worker registered");
|
||||
|
||||
const ready: ServiceWorkerMessage = {
|
||||
type: "ready",
|
||||
};
|
||||
postMessage(ready);
|
||||
|
||||
onmessage = async (e) => {
|
||||
console.debug("message received at worker");
|
||||
const config: PoWConfig = e.data;
|
||||
|
||||
@@ -40,5 +40,6 @@ export type Token = {
|
||||
};
|
||||
|
||||
export type ServiceWorkerMessage =
|
||||
| { type: "ready" }
|
||||
| { type: "work"; value: ServiceWorkerWork }
|
||||
| { type: "progress"; nonce: number };
|
||||
|
||||
Reference in New Issue
Block a user