Compare commits

..

24 Commits

Author SHA1 Message Date
Aravinth Manivannan
3a7e71b499 fix: exit loop when paginated DB query returns empty array
fixes: https://github.com/mCaptcha/mCaptcha/issues/154
2024-03-24 08:40:52 +05:30
Aravinth Manivannan
91955501e2 feat: enable easy PoW configuration auto-enhance by default 2024-03-24 08:37:26 +05:30
Aravinth Manivannan
cb72b0adfa Merge pull request #152 from mCaptcha/fix-151
fix: difficulty factor for "broke my site" should be greater than peak sustainable traffic"
2024-03-23 13:55:28 +05:30
Aravinth Manivannan
c1fe45d409 fix: difficulty factor for "broke my site" should be greater than "peak sustainable traffic"
fixes: #151
2024-03-23 13:31:49 +05:30
Aravinth Manivannan
59e339f287 Merge pull request #150 from mCaptcha/fix-144
feat: add curl to the final image to aid in healthchecks
2024-03-15 18:01:12 +05:30
Aravinth Manivannan
ddcde9cf18 Merge pull request #146 from 15aura35/master
Update .env.docker-compose to use port 7000 instead of 7001
2024-03-15 18:00:17 +05:30
Aravinth Manivannan
65c92ee96e feat: add curl to the final image to aid in healthchecks
closes: https://github.com/mCaptcha/mCaptcha/issues/144
2024-03-14 20:52:37 +05:30
Aravinth Manivannan
40766ff44f Merge pull request #147 from mitallast/master
Fix: ensuring worker is ready
2024-03-12 19:41:49 +05:30
mitallast
ddc3008009 await worker is ready 2024-03-05 13:42:10 +03:00
mitallast
cba056aba6 fix wasm bigint progress handler 2024-03-05 13:13:47 +03:00
15aura35
16c975d2ec Update .env.docker-compose 2024-03-01 21:53:32 +00:00
Aravinth Manivannan
f67fdf917e Merge pull request #142 from mCaptcha/release-ci
feat: publish tagged docker images and bins
2024-02-23 15:51:56 +05:30
Aravinth Manivannan
e1746223c8 feat: publish tagged docker images and bins 2024-02-23 15:40:45 +05:30
Aravinth Manivannan
ae08c09702 fix: tmp disable bin publication 2024-02-23 15:40:27 +05:30
Aravinth Manivannan
1c9e242d7e Merge pull request #140 from mCaptcha/fix-134
fix: typecast BigInt to number in progress computation
2024-02-22 19:21:03 +05:30
Aravinth Manivannan
3cb0ca38ec fix: typecast BigInt to number in progress computation
closes: https://github.com/mCaptcha/mCaptcha/issues/134
2024-02-22 18:40:38 +05:30
Aravinth Manivannan
3cd38511fa Merge pull request #135 from SebastianGode/widget-dark
Added automatic dark mode to the widget
2024-02-19 20:13:58 +05:30
Sebastian Gode
d765bd7491 Added dark mode to widget 2024-02-13 13:30:14 +00:00
Sebastian Gode
8e33e75659 Added dark mode to widget 2024-02-13 12:59:20 +00:00
Aravinth Manivannan
c00857dd28 Merge pull request #133 from mCaptcha/aria-labels
feat: add aria labels to widget progress bar and checkbox
2024-02-04 01:09:09 +05:30
Aravinth Manivannan
9cf0eb596a feat: add aria labels to widget progress bar and checkbox 2024-02-03 19:33:45 +05:30
Aravinth Manivannan
d010a1cbd4 Merge pull request #131 from mCaptcha/fix-upload-config-file
fix: publish config file in tarball
2024-01-08 00:21:52 +05:30
Aravinth Manivannan
453be36201 fix: publish config file in tarball 2024-01-08 00:14:14 +05:30
Aravinth Manivannan
d4967626ee Merge pull request #130 from mCaptcha/document-configuration-parameters
feat: list all env vars and load in docker-compose
2024-01-07 23:52:49 +05:30
16 changed files with 280 additions and 142 deletions

View File

@@ -13,7 +13,7 @@ MCAPTCHA_redis_URL=redis://mcaptcha_redis
MCAPTCHA_redis_POOL=4 MCAPTCHA_redis_POOL=4
# server # server
PORT=7001 PORT=7000
MCAPTCHA_server_DOMAIN=localhost MCAPTCHA_server_DOMAIN=localhost
MCAPTCHA__server_COOKIE_SECRET=pleasereplacethiswithrandomstring # PLEASE SET RANDOM STRING. MIN LENGTH=32 MCAPTCHA__server_COOKIE_SECRET=pleasereplacethiswithrandomstring # PLEASE SET RANDOM STRING. MIN LENGTH=32
MCAPTCHA__server_IP= 0.0.0.0 MCAPTCHA__server_IP= 0.0.0.0
@@ -26,8 +26,8 @@ MCAPTCHA_captcha_RUNNERS=4
MCAPTCHA_captcha_QUEUE_LENGTH=2000 MCAPTCHA_captcha_QUEUE_LENGTH=2000
MCAPTCHA_captcha_ENABLE_STATS=true MCAPTCHA_captcha_ENABLE_STATS=true
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_avg_traffic_difficulty=50000 # almost instant solution MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_avg_traffic_difficulty=50000 # almost instant solution
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_broke_my_site_traffic_difficulty=3000000 # roughly 1.5s MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_peak_sustainable_traffic_difficulty=3000000 # greater than 3.5s
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_peak_sustainable_traffic_difficulty=5000000 # 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_duration=30 # cooldown period in seconds
MCAPTCHA_captcha_DEFAULT_DIFFICULTY_STRATEGY_avg_traffic_time=1 # almost instant solution 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_peak_sustainable_traffic_time=3

125
.github/workflows/release.yml vendored Normal file
View 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 }}

View File

@@ -1,32 +1,32 @@
name: Create binary for release #name: Create binary for release
#
# Only on tags that start with a "v" ## Only on tags that start with a "v"
on: #on:
push: # push:
tags: # tags:
- "v*" # - "v*"
#
jobs: #jobs:
build: # build:
runs-on: ubuntu-latest # runs-on: ubuntu-latest
strategy: # strategy:
fail-fast: false # fail-fast: false
matrix: # matrix:
include: # include:
- target: x86_64-pc-windows-gnu # - target: x86_64-pc-windows-gnu
archive: zip # archive: zip
- target: x86_64-unknown-linux-musl # - target: x86_64-unknown-linux-musl
archive: tar.gz tar.xz # archive: tar.gz tar.xz
- target: x86_64-apple-darwin # - target: x86_64-apple-darwin
archive: zip # archive: zip
steps: # steps:
- name: Checkout # - name: Checkout
uses: actions/checkout@v3 # uses: actions/checkout@v3
#
- name: Compile and release # - name: Compile and release
uses: rust-build/rust-build.action@v1.3.2 # uses: rust-build/rust-build.action@v1.3.2
env: # env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: # with:
RUSTTARGET: ${{ matrix.target }} # RUSTTARGET: ${{ matrix.target }}
ARCHIVE_TYPES: ${{ matrix.archive }} # ARCHIVE_TYPES: ${{ matrix.archive }}

View File

@@ -31,6 +31,10 @@ RUN cargo build --release
FROM debian:bookworm as mCaptcha FROM debian:bookworm as mCaptcha
LABEL org.opencontainers.image.source https://github.com/mCaptcha/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 RUN useradd -ms /bin/bash -u 1001 mcaptcha
WORKDIR /home/mcaptcha WORKDIR /home/mcaptcha
COPY --from=rust /src/target/release/mcaptcha /usr/local/bin/ COPY --from=rust /src/target/release/mcaptcha /usr/local/bin/

View File

@@ -34,11 +34,11 @@ enable_stats = true
[captcha.default_difficulty_strategy] [captcha.default_difficulty_strategy]
avg_traffic_difficulty = 50000 # almost instant solution 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_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_difficulty = 5000000 # greater than 3.5s
#broke_my_site_traffic_time = 5 broke_my_site_traffic_time = 5
duration = 30 # cooldown period in seconds duration = 30 # cooldown period in seconds
[database] [database]

View File

@@ -44,6 +44,7 @@ copy() {
mkdir $TARGET_DIR/docs mkdir $TARGET_DIR/docs
cp docs/DEPLOYMENT.md $TARGET_DIR/docs cp docs/DEPLOYMENT.md $TARGET_DIR/docs
cp docs/CONFIGURATION.md $TARGET_DIR/docs cp docs/CONFIGURATION.md $TARGET_DIR/docs
cp config/default.toml $TARGET_DIR/config.toml
get_bin get_bin
} }

View File

@@ -55,6 +55,9 @@ impl UpdateEasyCaptcha {
} }
let mut patterns = data.db.get_all_easy_captchas(limit, offset).await?; let mut patterns = data.db.get_all_easy_captchas(limit, offset).await?;
if patterns.is_empty() {
break;
}
for pattern in patterns.drain(0..) { for pattern in patterns.drain(0..) {
if !Self::can_run(rx) { if !Self::can_run(rx) {
return Ok(()); return Ok(());
@@ -85,6 +88,7 @@ impl UpdateEasyCaptcha {
} }
page += 1; page += 1;
} }
Ok(())
} }
fn can_run(rx: &mut Receiver<()>) -> bool { fn can_run(rx: &mut Receiver<()>) -> bool {

View File

@@ -56,53 +56,41 @@ type messageTextReturn = {
error: () => void; error: () => void;
}; };
export const messageText = (): messageTextReturn => { export const BEFORE = "I'm not a robot";
const beforeID = "widget__verification-text--before"; export const DURING = "Processing...";
const duringID = "widget__verification-text--during"; export const AFTER = "Verified!";
const errorID = "widget__verification-text--error"; export const ERROR = "Something went wrong";
const afterID = "widget__verification-text--after";
const before = new LazyElement(beforeID); export const messageText = (): messageTextReturn => {
const after = new LazyElement(afterID); const conatinerID = "widget__verification-text";
const during = new LazyElement(duringID);
const error = new LazyElement(errorID); const container = new LazyElement(conatinerID);
/** runner fn to display HTMLElement **/ /** runner fn to display HTMLElement **/
const showMsg = (e: HTMLElement) => (e.style.display = "block"); const showMsg = (value: string) => {
/** runner fn to hide HTMLElement **/ container.get().innerText = value;
const hideMsg = (e: HTMLElement) => (e.style.display = "none"); btn().ariaValueText = value;
};
return { return {
/** display "before" message **/ /** display "before" message **/
before: () => { before: () => {
showMsg(before.get()); showMsg(BEFORE);
hideMsg(after.get());
hideMsg(during.get());
hideMsg(error.get());
}, },
/** display "after" message **/ /** display "after" message **/
after: () => { after: () => {
hideMsg(before.get()); showMsg(AFTER);
showMsg(after.get());
hideMsg(during.get());
hideMsg(error.get());
}, },
/** display "during" message **/ /** display "during" message **/
during: () => { during: () => {
hideMsg(before.get()); showMsg(DURING);
hideMsg(after.get());
showMsg(during.get());
hideMsg(error.get());
}, },
/** display "error" message **/ /** display "error" message **/
error: () => { error: () => {
hideMsg(before.get()); showMsg(ERROR);
hideMsg(after.get());
hideMsg(during.get());
showMsg(error.get());
}, },
}; };
}; };

View File

@@ -19,14 +19,15 @@ SPDX-License-Identifier: MIT OR Apache-2.0
</div> </div>
</noscript> </noscript>
<label class="widget__verification-container" for="widget__verification-checkbox"> <label class="widget__verification-container" for="widget__verification-checkbox">
<input <span id="widget__verification-text"
>I'm not a robot</span>
<input disabled
id="widget__verification-checkbox" id="widget__verification-checkbox"
aria-valuenow="I'm not a robot"
aria-checked="false"
role="checkbox"
class="widget__verification-checkbox" class="widget__verification-checkbox"
type="checkbox" /> type="checkbox" />
<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--after">Verified!</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 .>"
@@ -54,6 +55,8 @@ SPDX-License-Identifier: MIT OR Apache-2.0
</div> </div>
</div> </div>
</form> </form>
<div class="progress__bar"><div class="progress__fill"></div></div> <div class="progress__bar"><div
aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"
role="progressbar" class="progress__fill"></div></div>
</main> </main>
<.include!("./footer.html"); .> <.include!("./footer.html"); .>

View File

@@ -12,7 +12,17 @@ import * as CONST from "./const";
import "./main.scss"; import "./main.scss";
let LOCK = false; let LOCK = false;
const workerPromise = new Promise<Worker>((res) => {
const worker = new Worker("/bench.js"); 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 */ /** add mcaptcha widget element to DOM */
export const registerVerificationEventHandler = (): void => { export const registerVerificationEventHandler = (): void => {
@@ -20,11 +30,21 @@ export const registerVerificationEventHandler = (): void => {
document.querySelector(".widget__verification-container") document.querySelector(".widget__verification-container")
); );
verificationContainer.style.display = "flex"; 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 PROGRESS_FILL = <HTMLElement>document.querySelector(".progress__fill");
const setWidth = (width: number) => {
PROGRESS_FILL.style.width = `${width}%`;
PROGRESS_FILL.ariaValueNow = <any>parseInt(<any>width);
};
let width = 0; let width = 0;
if (LOCK) { if (LOCK) {
@@ -36,8 +56,9 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
LOCK = true; LOCK = true;
if (CONST.btn().checked == false) { if (CONST.btn().checked == false) {
width = 0; width = 0;
PROGRESS_FILL.style.width = `${width}%`; setWidth(width);
CONST.messageText().before(); CONST.messageText().before();
CONST.btn().ariaChecked = <any>false;
LOCK = false; LOCK = false;
return; return;
} }
@@ -57,7 +78,7 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
if (resp.type === "work") { if (resp.type === "work") {
width = 80; width = 80;
PROGRESS_FILL.style.width = `${width}%`; setWidth(width);
console.log( console.log(
`Proof generated. Difficuly: ${config.difficulty_factor} Duration: ${resp.value.work.time}` `Proof generated. Difficuly: ${config.difficulty_factor} Duration: ${resp.value.work.time}`
); );
@@ -72,22 +93,23 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
}; };
width = 90; width = 90;
PROGRESS_FILL.style.width = `${width}%`; setWidth(width);
// 3. submit work // 3. submit work
const token = await sendWork(proof); const token = await sendWork(proof);
// 4. send token // 4. send token
sendToParent(token); sendToParent(token);
// 5. mark checkbox checked // 5. mark checkbox checked
CONST.btn().checked = true; CONST.btn().checked = true;
CONST.btn().ariaChecked = <any>true;
width = 100; width = 100;
PROGRESS_FILL.style.width = `${width}%`; setWidth(width);
CONST.messageText().after(); CONST.messageText().after();
LOCK = false; LOCK = false;
} }
if (resp.type === "progress") { if (resp.type === "progress") {
if (width < 80) { if (width < 80) {
width = (resp.nonce / max_recorded_nonce) * 100; width = resp.nonce / max_recorded_nonce * 100;
PROGRESS_FILL.style.width = `${width}%`; setWidth(width);
} }
console.log(`received nonce ${resp.nonce}`); console.log(`received nonce ${resp.nonce}`);
} }

View File

@@ -28,6 +28,8 @@ body {
display: flex; display: flex;
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: #f6f6f6;
border: 2px solid #e5e5e5;
} }
.widget__noscript-container { .widget__noscript-container {
@@ -56,7 +58,8 @@ body {
.widget__verification-container { .widget__verification-container {
align-items: center; align-items: center;
display: none; display: flex;
flex-direction: row-reverse;
line-height: 30px; line-height: 30px;
font-size: 1rem; font-size: 1rem;
} }
@@ -67,36 +70,6 @@ body {
margin: 0 10px; margin: 0 10px;
} }
#widget__verification-text--during {
display: none;
}
#widget__verification-text--after {
display: none;
color: green;
}
#widget__verification-text--error {
display: none;
color: red;
}
.widget__verification-checkbox:checked ~ #widget__verification-text--before {
display: none;
}
.widget__verification-checkbox:checked ~ #widget__verification-text--during {
display: none;
}
.widget__verification-checkbox:checked ~ #widget__verification-text--error {
display: none;
}
.widget__verification-checkbox:checked ~ #widget__verification-text--after {
display: block;
}
.widget__mcaptcha-details { .widget__mcaptcha-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -127,6 +100,29 @@ body {
margin: 2px; 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 courtesy of https://codepen.io/Bizzy-Coding/pen/poOymVJ?editors=1111 */
.progress__bar { .progress__bar {
position: relative; position: relative;
@@ -142,3 +138,9 @@ body {
height: 100%; height: 100%;
width: 0%; width: 0%;
} }
@media (prefers-color-scheme: dark) {
.progress__bar {
background: unset;
}
}

View File

@@ -30,7 +30,7 @@ const prove = async (
config.string, config.string,
config.difficulty_factor, config.difficulty_factor,
STEPS, STEPS,
progress (nonce: BigInt | number) => progress(Number(nonce))
); );
const t1 = performance.now(); const t1 = performance.now();
time = t1 - t0; time = t1 - t0;

View File

@@ -9,6 +9,12 @@ import prove from "./prove";
import { PoWConfig, ServiceWorkerMessage, ServiceWorkerWork } from "./types"; import { PoWConfig, ServiceWorkerMessage, ServiceWorkerWork } from "./types";
log.log("worker registered"); log.log("worker registered");
const ready: ServiceWorkerMessage = {
type: "ready",
};
postMessage(ready);
onmessage = async (e) => { onmessage = async (e) => {
console.debug("message received at worker"); console.debug("message received at worker");
const config: PoWConfig = e.data; const config: PoWConfig = e.data;

View File

@@ -17,29 +17,17 @@ it("const works", () => {
// display after // display after
CONST.messageText().after(); CONST.messageText().after();
expect(TESTElements.afterMsg.style.display).toBe("block"); expect(TESTElements.Msg.innerText).toBe(CONST.AFTER);
expect(TESTElements.beforeMsg.style.display).toBe("none");
expect(TESTElements.duringMsg.style.display).toBe("none");
expect(TESTElements.errorMsg.style.display).toBe("none");
// display before // display before
CONST.messageText().before(); CONST.messageText().before();
expect(TESTElements.afterMsg.style.display).toBe("none"); expect(TESTElements.Msg.innerText).toBe(CONST.BEFORE);
expect(TESTElements.beforeMsg.style.display).toBe("block");
expect(TESTElements.duringMsg.style.display).toBe("none");
expect(TESTElements.errorMsg.style.display).toBe("none");
// display during // display during
CONST.messageText().during(); CONST.messageText().during();
expect(TESTElements.afterMsg.style.display).toBe("none"); expect(TESTElements.Msg.innerText).toBe(CONST.DURING);
expect(TESTElements.beforeMsg.style.display).toBe("none");
expect(TESTElements.duringMsg.style.display).toBe("block");
expect(TESTElements.errorMsg.style.display).toBe("none");
// display error // display error
CONST.messageText().error(); CONST.messageText().error();
expect(TESTElements.afterMsg.style.display).toBe("none"); expect(TESTElements.Msg.innerText).toBe(CONST.ERROR);
expect(TESTElements.beforeMsg.style.display).toBe("none");
expect(TESTElements.duringMsg.style.display).toBe("none");
expect(TESTElements.errorMsg.style.display).toBe("block");
}); });

View File

@@ -11,25 +11,19 @@ export const checkbox = <HTMLInputElement>document.createElement("input");
checkbox.type = "checkbox"; checkbox.type = "checkbox";
checkbox.id = CONST.btnId; checkbox.id = CONST.btnId;
const getMessages = (state: string) => { const getMessages = () => {
const msg = <HTMLElement>document.createElement("span"); const msg = <HTMLElement>document.createElement("span");
msg.id = `widget__verification-text--${state}`; msg.id = "widget__verification-text";
msg.innerText = "I'm not a robot";
return msg; return msg;
}; };
export const beforeMsg = getMessages("before"); export const Msg = getMessages();
export const afterMsg = getMessages("after");
export const duringMsg = getMessages("during");
export const errorMsg = getMessages("error");
/** get base HTML with empty mCaptcha container */ /** get base HTML with empty mCaptcha container */
export const getBaseHtml = (): HTMLFormElement => { export const getBaseHtml = (): HTMLFormElement => {
const form = <HTMLFormElement>document.createElement("form"); const form = <HTMLFormElement>document.createElement("form");
form.appendChild(checkbox); form.appendChild(checkbox);
form.appendChild(beforeMsg); form.appendChild(Msg);
form.appendChild(duringMsg);
form.appendChild(afterMsg);
form.appendChild(errorMsg);
return form; return form;
}; };

View File

@@ -40,5 +40,6 @@ export type Token = {
}; };
export type ServiceWorkerMessage = export type ServiceWorkerMessage =
| { type: "ready" }
| { type: "work"; value: ServiceWorkerWork } | { type: "work"; value: ServiceWorkerWork }
| { type: "progress"; nonce: number }; | { type: "progress"; nonce: number };