widget static resources are now built locally
This commit is contained in:
parent
5d55971f19
commit
bfebca6e0e
36 changed files with 2086 additions and 168 deletions
26
.github/workflows/coverage.yml
vendored
26
.github/workflows/coverage.yml
vendored
|
@ -65,15 +65,6 @@ jobs:
|
|||
- name: start smtp server
|
||||
run: docker run -d -p 1080:1080 -p 10025:1025 maildev/maildev --incoming-user admin --incoming-pass password
|
||||
|
||||
- name: Install JavaScript Dependencies
|
||||
run: yarn install
|
||||
|
||||
- name: Build frontend
|
||||
run: yarn build
|
||||
|
||||
- name: Run the tests
|
||||
run: yarn test
|
||||
|
||||
- name: Install ${{ matrix.version }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
|
@ -81,20 +72,15 @@ jobs:
|
|||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Run migrations
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: run
|
||||
args: --bin tests-migrate -- --build
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
- name: Build frontend
|
||||
run: make frontend
|
||||
|
||||
- name: Run the frontend tests
|
||||
run: make frontend-test
|
||||
|
||||
- name: Generate coverage file
|
||||
if: matrix.version == '1.51.0' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||
uses: actions-rs/tarpaulin@v0.1
|
||||
with:
|
||||
version: '0.15.0'
|
||||
args: '-t 1200'
|
||||
run: make xml-test-coverage
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
# GIT_HASH is dummy value. I guess build.rs is skipped in tarpaulin
|
||||
|
|
44
.github/workflows/linux.yml
vendored
44
.github/workflows/linux.yml
vendored
|
@ -38,14 +38,6 @@ jobs:
|
|||
image: mcaptcha/cache
|
||||
ports:
|
||||
- 6379:6379
|
||||
# smtp:
|
||||
# image: maildev/maildev
|
||||
# ports:
|
||||
# - 10025:1025
|
||||
# - 1080:1080
|
||||
# env:
|
||||
# MAILDEV_INCOMING_USER: admin
|
||||
# MAILDEV_INCOMING_PASS: password
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -64,13 +56,7 @@ jobs:
|
|||
node-version: '14.x'
|
||||
|
||||
- name: start smtp server
|
||||
run: docker run -d -p 1080:1080 -p 10025:1025 maildev/maildev --incoming-user admin --incoming-pass password
|
||||
|
||||
- name: Install JavaScript Dependencies
|
||||
run: yarn install
|
||||
|
||||
- name: Build Frontend
|
||||
run: yarn build
|
||||
run: docker run -d -p 1080:1080 -p 10025:1025 maildev/maildev --incoming-user admin --incoming-pass password
|
||||
|
||||
- name: Install ${{ matrix.version }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
|
@ -79,37 +65,27 @@ jobs:
|
|||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
- name: Run migrations
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: run
|
||||
args: --bin tests-migrate
|
||||
run: make migrations
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
|
||||
- name: check build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all --bins --examples --tests
|
||||
- name: build
|
||||
run: make
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
|
||||
- name: tests
|
||||
uses: actions-rs/cargo@v1
|
||||
timeout-minutes: 40
|
||||
with:
|
||||
command: test
|
||||
args: --all --all-features --no-fail-fast
|
||||
- name: run tests
|
||||
run: make test
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
|
||||
- name: generate documentation
|
||||
if: matrix.version == 'stable' && (github.repository == 'mCaptcha/mCaptcha')
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: doc
|
||||
args: --no-deps --workspace --all-features
|
||||
run: make doc
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/postgres
|
||||
GIT_HASH: 8e77345f1597e40c2e266cb4e6dee74888918a61 # dummy value
|
||||
|
|
134
Cargo.lock
generated
134
Cargo.lock
generated
|
@ -221,7 +221,7 @@ dependencies = [
|
|||
"actix-web-codegen 0.5.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ahash",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cookie",
|
||||
"derive_more",
|
||||
"either",
|
||||
|
@ -449,7 +449,7 @@ dependencies = [
|
|||
"actix-service",
|
||||
"base64",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cookie",
|
||||
"derive_more",
|
||||
"futures-core",
|
||||
|
@ -579,7 +579,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cache-buster"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/realaravinth/cache-buster#d970b7031cd90649e30dc297eb5eba74832153e8"
|
||||
source = "git+https://github.com/realaravinth/cache-buster#e75ac689d2155092b90d1421ec05ec84c6917350"
|
||||
dependencies = [
|
||||
"data-encoding",
|
||||
"derive_builder",
|
||||
|
@ -600,6 +600,12 @@ dependencies = [
|
|||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -644,6 +650,16 @@ dependencies = [
|
|||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.8"
|
||||
|
@ -732,7 +748,7 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -741,7 +757,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
|
@ -751,7 +767,7 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
|
@ -761,7 +777,7 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
|
@ -930,7 +946,7 @@ version = "0.8.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -961,7 +977,7 @@ version = "0.2.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"winapi",
|
||||
|
@ -973,7 +989,7 @@ version = "1.0.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
|
@ -1136,7 +1152,7 @@ version = "0.1.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
@ -1147,7 +1163,7 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
]
|
||||
|
@ -1348,7 +1364,7 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1426,7 +1442,7 @@ checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
|||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
@ -1494,7 +1510,7 @@ version = "0.4.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1586,6 +1602,20 @@ dependencies = [
|
|||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mcaptcha-browser"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"pow_sha256",
|
||||
"serde 1.0.126",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.9.1"
|
||||
|
@ -1603,6 +1633,12 @@ version = "2.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
|
@ -1824,7 +1860,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
|
@ -1867,7 +1903,7 @@ version = "0.8.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
|
@ -2408,6 +2444,12 @@ dependencies = [
|
|||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -2543,7 +2585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
|
@ -2562,7 +2604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
|
@ -2854,7 +2896,7 @@ version = "3.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand 0.8.4",
|
||||
"redox_syscall",
|
||||
|
@ -3045,7 +3087,7 @@ version = "0.1.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
@ -3228,7 +3270,7 @@ version = "0.2.74"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
|
@ -3247,6 +3289,18 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
|
@ -3276,6 +3330,30 @@ version = "0.2.74"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cab416a9b970464c2882ed92d55b0c33046b08e0bdc9d59b3b718acd4e1bae8"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4543fc6cf3541ef0d98bf720104cc6bd856d7eba449fd2aa365ef4fed0e782"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
|
@ -3305,6 +3383,18 @@ dependencies = [
|
|||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.1.2"
|
||||
|
|
|
@ -21,6 +21,12 @@ path = "./src/main.rs"
|
|||
name = "tests-migrate"
|
||||
path = "./src/tests-migrate.rs"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
".",
|
||||
"browser",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
#actix-web = "3.3.2"
|
||||
actix-web = "4.0.0-beta.8"
|
||||
|
|
45
Makefile
45
Makefile
|
@ -1,29 +1,45 @@
|
|||
default: frontend
|
||||
cargo build
|
||||
|
||||
run: frontend-dev
|
||||
run: frontend
|
||||
cargo run
|
||||
|
||||
dev-env:
|
||||
cargo fetch
|
||||
yarn install
|
||||
|
||||
docs:
|
||||
doc:
|
||||
#yarn doc
|
||||
cargo doc --no-deps --workspace --all-features
|
||||
|
||||
frontend-dev:
|
||||
yarn build
|
||||
cd browser && cargo doc --no-deps --workspace --all-features
|
||||
|
||||
frontend:
|
||||
cd browser && wasm-pack build --release
|
||||
yarn install
|
||||
yarn build
|
||||
|
||||
test: migrate
|
||||
cargo test
|
||||
test: migrations
|
||||
cd browser && wasm-pack test --release --headless --chrome
|
||||
cd browser && wasm-pack test --release --headless --firefox
|
||||
cargo test --all --all-features --no-fail-fast
|
||||
${MAKE} frontend-test
|
||||
|
||||
xml-test-coverage: migrate
|
||||
frontend-test:
|
||||
cd browser && wasm-pack test --release --headless --chrome
|
||||
cd browser && wasm-pack test --release --headless --firefox
|
||||
yarn test
|
||||
|
||||
a:
|
||||
echo a
|
||||
b:
|
||||
${MAKE} a
|
||||
|
||||
xml-test-coverage: migrations
|
||||
cd browser && cargo tarpaulin -t 1200 --out Xml
|
||||
cargo tarpaulin -t 1200 --out Xml
|
||||
|
||||
coverage: migrate
|
||||
coverage: migrations
|
||||
cd browser && cargo tarpaulin -t 1200 --out Html
|
||||
cargo tarpaulin -t 1200 --out Html
|
||||
|
||||
release: frontend
|
||||
|
@ -35,13 +51,12 @@ clean:
|
|||
|
||||
docker-build:
|
||||
docker build -t mcaptcha/mcaptcha:master -t mcaptcha/mcaptcha:latest .
|
||||
|
||||
docker-publish: docker-build
|
||||
docker push mcaptcha/mcaptcha:master
|
||||
docker push mcaptcha/mcaptcha:latest
|
||||
|
||||
|
||||
|
||||
migrate:
|
||||
migrations:
|
||||
cargo run --bin tests-migrate
|
||||
|
||||
help:
|
||||
|
@ -50,10 +65,10 @@ help:
|
|||
@echo ' dev-env - download dependencies'
|
||||
@echo ' docker-build - build docker image'
|
||||
@echo ' docker-publish - build and publish docker image'
|
||||
@echo ' docs - build documentation'
|
||||
@echo ' frontend-dev - build static assets in dev mode'
|
||||
@echo ' doc - build documentation'
|
||||
@echo ' frontend - build static assets in prod mode'
|
||||
@echo ' migrate - run database migrations'
|
||||
@echo ' frontend-test - run frontend tests'
|
||||
@echo ' migrations - run database migrations'
|
||||
@echo ' run - run developer instance'
|
||||
@echo ' test - run unit and integration tests'
|
||||
@echo ' xml-coverage - build test coverage in XML for upload to codecov'
|
||||
|
|
11
browser/.appveyor.yml
Normal file
11
browser/.appveyor.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
install:
|
||||
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
build: false
|
||||
|
||||
test_script:
|
||||
- cargo test --locked
|
14
browser/.gitignore
vendored
Normal file
14
browser/.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
/target
|
||||
tarpaulin-report.html
|
||||
.env
|
||||
.env
|
||||
cobertura.xml
|
||||
prod/
|
||||
node_modules/
|
||||
/static-assets/bundle
|
||||
./templates/**/*.js
|
||||
/static-assets/bundle/*
|
||||
src/cache_buster_data.json
|
||||
coverage
|
||||
dist/
|
||||
docs
|
69
browser/.travis.yml
Normal file
69
browser/.travis.yml
Normal file
|
@ -0,0 +1,69 @@
|
|||
language: rust
|
||||
sudo: false
|
||||
|
||||
cache: cargo
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
# Builds with wasm-pack.
|
||||
- rust: beta
|
||||
env: RUST_BACKTRACE=1
|
||||
addons:
|
||||
firefox: latest
|
||||
chrome: stable
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
|
||||
# in any of our parent dirs is problematic.
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- wasm-pack build
|
||||
- wasm-pack test --chrome --firefox --headless
|
||||
|
||||
# Builds on nightly.
|
||||
- rust: nightly
|
||||
env: RUST_BACKTRACE=1
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- cargo check
|
||||
- cargo check --target wasm32-unknown-unknown
|
||||
- cargo check --no-default-features
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features
|
||||
- cargo check --no-default-features --features console_error_panic_hook
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
|
||||
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
|
||||
|
||||
# Builds on beta.
|
||||
- rust: beta
|
||||
env: RUST_BACKTRACE=1
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- cargo check
|
||||
- cargo check --target wasm32-unknown-unknown
|
||||
- cargo check --no-default-features
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features
|
||||
- cargo check --no-default-features --features console_error_panic_hook
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
|
||||
# Note: no enabling the `wee_alloc` feature here because it requires
|
||||
# nightly for now.
|
556
browser/Cargo.lock
generated
Normal file
556
browser/Cargo.lock
generated
Normal file
|
@ -0,0 +1,556 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30"
|
||||
dependencies = [
|
||||
"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]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mcaptcha-browser"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"pow_sha256",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "pow_sha256"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/mcaptcha/pow_sha256#807fa7c75284f6d8d488a6f66a3a1b3301f2f412"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"derive_builder",
|
||||
"num",
|
||||
"serde",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cab416a9b970464c2882ed92d55b0c33046b08e0bdc9d59b3b718acd4e1bae8"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4543fc6cf3541ef0d98bf720104cc6bd856d7eba449fd2aa365ef4fed0e782"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
46
browser/Cargo.toml
Normal file
46
browser/Cargo.toml
Normal file
|
@ -0,0 +1,46 @@
|
|||
[package]
|
||||
name = "mcaptcha-browser"
|
||||
version = "0.1.0"
|
||||
authors = ["realaravinth <realaravinth@batsense.net>"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/mCaptcha/browser"
|
||||
description = "mCaptcha client library for the web"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.63"
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||
# code size when deploying.
|
||||
console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||
|
||||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||
# compared to the default allocator's ~10K. It is slower than the default
|
||||
# allocator, however.
|
||||
#
|
||||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||
wee_alloc = { version = "0.4.5", optional = true }
|
||||
|
||||
serde = "1.0.114"
|
||||
serde_derive = "1.0.114"
|
||||
serde_json = "1"
|
||||
|
||||
pow_sha256 = { version = "0.2.1", git = "https://github.com/mcaptcha/pow_sha256" }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.13"
|
||||
|
||||
#[profile.release]
|
||||
## Tell `rustc` to optimize for small code size.
|
||||
#opt-level = "s"
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = false
|
176
browser/LICENSE_APACHE
Normal file
176
browser/LICENSE_APACHE
Normal file
|
@ -0,0 +1,176 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
25
browser/LICENSE_MIT
Normal file
25
browser/LICENSE_MIT
Normal file
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2018 realaravinth <realaravinth@batsense.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
92
browser/README.md
Normal file
92
browser/README.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PoW JavaScript library</h1>
|
||||
|
||||
<strong>JavaScript library to generate PoW for mCaptcha</strong>
|
||||
|
||||
[![0.1.0](https://img.shields.io/badge/Rust_docs-master-dea584)](https://mcaptcha.github.io/browser/rust/mcaptcha_browser/index.html)
|
||||
[![0.1.0](https://img.shields.io/badge/TypeScript_docs-master-2b7489)](https://mcaptcha.github.io/browser/ts/docs/modules.html)
|
||||
![Build)](<https://github.com/mCaptcha/browser/workflows/CI%20(Linux)/badge.svg>)
|
||||
[![dependency status](https://deps.rs/repo/github/mCaptcha/browser/status.svg)](https://deps.rs/repo/github/mCaptcha/browser)
|
||||
<br />
|
||||
[![codecov](https://codecov.io/gh/mCaptcha/browser/branch/master/graph/badge.svg)](https://codecov.io/gh/mCaptcha/browser)
|
||||
|
||||
</div>
|
||||
|
||||
**NOTE:** wasm compilation currently requires `rustc` nightly and
|
||||
wasm optimization of this library will have to be done manually at the
|
||||
moment. Please refer to https://github.com/rustwasm/wasm-pack/issues/886
|
||||
for more information.
|
||||
|
||||
### Optimization:
|
||||
|
||||
```
|
||||
$ /path/to/wasm-opt pkg/pow_bg.wasm -o pkg/pow_bg.wasm -O --enable-mutable-globals
|
||||
```
|
||||
|
||||
My `/path/to/wasm-opt` is `~/.cache/.wasm-pack/wasm-opt-4d7a65327e9363b7/wasm-opt`
|
||||
|
||||
---
|
||||
|
||||
<h2> Default documentation provided by Rust wasm: </h2>
|
||||
|
||||
<h3>
|
||||
<a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html">Tutorial</a>
|
||||
<span> | </span>
|
||||
<a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a>
|
||||
</h3>
|
||||
|
||||
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub>
|
||||
|
||||
</div>
|
||||
|
||||
## About
|
||||
|
||||
[**📚 Read this template tutorial! 📚**][template-docs]
|
||||
|
||||
This template is designed for compiling Rust libraries into WebAssembly and
|
||||
publishing the resulting package to NPM.
|
||||
|
||||
Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other
|
||||
templates and usages of `wasm-pack`.
|
||||
|
||||
[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html
|
||||
[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html
|
||||
|
||||
## 🚴 Usage
|
||||
|
||||
### 🐑 Use `cargo generate` to Clone this Template
|
||||
|
||||
[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate)
|
||||
|
||||
```
|
||||
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
|
||||
cd my-project
|
||||
```
|
||||
|
||||
### 🛠️ Build with `wasm-pack build`
|
||||
|
||||
```
|
||||
wasm-pack build
|
||||
```
|
||||
|
||||
### 🔬 Test in Headless Browsers with `wasm-pack test`
|
||||
|
||||
```
|
||||
wasm-pack test --headless --firefox
|
||||
```
|
||||
|
||||
### 🎁 Publish to NPM with `wasm-pack publish`
|
||||
|
||||
```
|
||||
wasm-pack publish
|
||||
```
|
||||
|
||||
## 🔋 Batteries Included
|
||||
|
||||
- [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating
|
||||
between WebAssembly and JavaScript.
|
||||
- [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook)
|
||||
for logging panic messages to the developer console.
|
||||
- [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized
|
||||
for small code size.
|
154
browser/src/lib.rs
Normal file
154
browser/src/lib.rs
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
//! mCaptcha is a proof of work based Denaial-of-Service attack protection system.
|
||||
//! This is is a WASM library that you can embed in your frontend code to protect your
|
||||
//! service.
|
||||
//!
|
||||
//! A commercial managed solution is in the works but I'd much rather prefer
|
||||
//! folks host their own instances as it will make the more decentralized and free.
|
||||
//!
|
||||
//! ## Workflow:
|
||||
//! mCaptcha workflow in the frontend is simple.
|
||||
//! 1. Call service to get a proof of work(PoW) configuration
|
||||
//! 2. Call into mCaptcha to get PoW
|
||||
//! 3. Send PoW to mCaptcha service
|
||||
//! 4. If proof is valid, the service will return a token to the client
|
||||
//! 5. Submit token to your backend along with your app data(if any)
|
||||
//! 6. In backend, validate client's token with mCaptcha service
|
||||
//!
|
||||
//! ## Example:
|
||||
//!
|
||||
//! generate proof-of-work
|
||||
//! ```rust
|
||||
//! fn main() {
|
||||
//! use mcaptcha_browser::*;
|
||||
//! use pow_sha256::*;
|
||||
//!
|
||||
//!
|
||||
//! // salt using which PoW should be computed
|
||||
//! const SALT: &str = "yrandomsaltisnotlongenoug";
|
||||
//! // one-time phrase over which PoW should be computed
|
||||
//! const PHRASE: &str = "ironmansucks";
|
||||
//! // and the difficulty factor
|
||||
//! const DIFFICULTY: u32 = 1000;
|
||||
//!
|
||||
//! // currently gen_pow() returns a JSON formated string to better communicate
|
||||
//! // with JavaScript. See [PoW<T>][pow_sha256::PoW] for schema
|
||||
//! let serialised_work = gen_pow(SALT.into(), PHRASE.into(), DIFFICULTY);
|
||||
//!
|
||||
//!
|
||||
//! let work: Work = serde_json::from_str(&serialised_work).unwrap();
|
||||
//!
|
||||
//! let work = PoWBuilder::default()
|
||||
//! .result(work.result)
|
||||
//! .nonce(work.nonce)
|
||||
//! .build()
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let config = ConfigBuilder::default().salt(SALT.into()).build().unwrap();
|
||||
//! assert!(config.is_valid_proof(&work, &PHRASE.to_string()));
|
||||
//! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
// allocator.
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
use pow_sha256::{ConfigBuilder, PoW};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Work {
|
||||
pub result: String,
|
||||
pub nonce: u64,
|
||||
}
|
||||
|
||||
impl From<PoW<String>> for Work {
|
||||
fn from(p: PoW<String>) -> Self {
|
||||
Work {
|
||||
result: p.result,
|
||||
nonce: p.nonce,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// generate proof-of-work
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// use mcaptcha_browser::*;
|
||||
/// use pow_sha256::*;
|
||||
///
|
||||
///
|
||||
/// // salt using which PoW should be computed
|
||||
/// const SALT: &str = "yrandomsaltisnotlongenoug";
|
||||
/// // one-time phrase over which PoW should be computed
|
||||
/// const PHRASE: &str = "ironmansucks";
|
||||
/// // and the difficulty factor
|
||||
/// const DIFFICULTY: u32 = 1000;
|
||||
///
|
||||
/// // currently gen_pow() returns a JSON formated string to better communicate
|
||||
/// // with JavaScript. See [PoW<T>][pow_sha256::PoW] for schema
|
||||
/// let serialised_work = gen_pow(SALT.into(), PHRASE.into(), DIFFICULTY);
|
||||
///
|
||||
///
|
||||
/// let work: Work = serde_json::from_str(&serialised_work).unwrap();
|
||||
///
|
||||
/// let work = PoWBuilder::default()
|
||||
/// .result(work.result)
|
||||
/// .nonce(work.nonce)
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let config = ConfigBuilder::default().salt(SALT.into()).build().unwrap();
|
||||
/// assert!(config.is_valid_proof(&work, &PHRASE.to_string()));
|
||||
/// assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||
/// }
|
||||
/// ```
|
||||
#[wasm_bindgen]
|
||||
pub fn gen_pow(salt: String, phrase: String, difficulty_factor: u32) -> String {
|
||||
let config = ConfigBuilder::default().salt(salt).build().unwrap();
|
||||
|
||||
let work = config.prove_work(&phrase, difficulty_factor).unwrap();
|
||||
let work: Work = work.into();
|
||||
|
||||
let payload = serde_json::to_string(&work).unwrap();
|
||||
payload
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pow_sha256::PoWBuilder;
|
||||
|
||||
const SALT: &str = "yrandomsaltisnotlongenoug";
|
||||
const PHRASE: &str = "ironmansucks";
|
||||
const DIFFICULTY: u32 = 1000;
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let serialised_work = gen_pow(SALT.into(), PHRASE.into(), DIFFICULTY);
|
||||
let work: Work = serde_json::from_str(&serialised_work).unwrap();
|
||||
|
||||
let work = PoWBuilder::default()
|
||||
.result(work.result)
|
||||
.nonce(work.nonce)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let config = ConfigBuilder::default().salt(SALT.into()).build().unwrap();
|
||||
assert!(config.is_valid_proof(&work, &PHRASE.to_string()));
|
||||
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||
}
|
||||
}
|
49
browser/static/embeded.html
Normal file
49
browser/static/embeded.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>mcaptcha demo form</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="">
|
||||
<!-- BEGIN: ReCAPTCHA implementation example. -->
|
||||
<div
|
||||
id="recaptcha-demo"
|
||||
class="g-recaptcha"
|
||||
data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
|
||||
data-callback="onSuccess"
|
||||
data-action="action"
|
||||
>
|
||||
<div style="width: 304px; height: 78px;">
|
||||
<div>
|
||||
<iframe
|
||||
title="mCaptcha"
|
||||
src="http://localhost:7000/widget"
|
||||
role="presentation"
|
||||
name="a-i3v5fjryp9h"
|
||||
scrolling="no"
|
||||
sandbox="allow-scripts"
|
||||
width="304"
|
||||
height="78"
|
||||
frameborder="0"
|
||||
></iframe>
|
||||
<!-- sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation allow-modals allow-popups-to-escape-sandbox allow-storage-access-by-user-activation" -->
|
||||
</div>
|
||||
<textarea
|
||||
id="g-recaptcha-response"
|
||||
name="g-recaptcha-response"
|
||||
class="g-recaptcha-response"
|
||||
style="width: 250px; height: 40px; border: 1px solid rgb(193, 193, 193); margin: 10px 25px; padding: 0px; resize: none; display: none; --darkreader-inline-border-top:#48443c; --darkreader-inline-border-right:#48443c; --darkreader-inline-border-bottom:#48443c; --darkreader-inline-border-left:#48443c;"
|
||||
data-darkreader-inline-border-top=""
|
||||
data-darkreader-inline-border-right=""
|
||||
data-darkreader-inline-border-bottom=""
|
||||
data-darkreader-inline-border-left=""
|
||||
></textarea>
|
||||
</div>
|
||||
<iframe style="display: none;"></iframe>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
124
browser/static/index.html
Normal file
124
browser/static/index.html
Normal file
|
@ -0,0 +1,124 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>mCaptcha</title>
|
||||
</head>
|
||||
<body>
|
||||
<form class="contaienr">
|
||||
<noscript class="noscript-container">
|
||||
<span class="warning">
|
||||
Please enable JavaScript to receive mCaptcha challenge
|
||||
</span>
|
||||
<a class="source-code" href="https://github.com/mCaptcha">
|
||||
Read our source code
|
||||
</a>
|
||||
</noscript>
|
||||
<label class="checkbox-label" for="verification">
|
||||
<input id="verification" class="checkbox" type="checkbox" />
|
||||
I'm not a robot
|
||||
</label>
|
||||
<div class="details">
|
||||
<a href="https://mcaptcha.org" class="logo-container">
|
||||
<img
|
||||
class="logo"
|
||||
src="https://mcaptcha.org/icon-trans.png"
|
||||
alt="mCaptcha logo"
|
||||
/>
|
||||
<p class="brand-name">mCaptcha</p>
|
||||
</a>
|
||||
<div class="links-container">
|
||||
<a class="links" href="https://mcaptcha.org/privacy-policy">
|
||||
Privacy
|
||||
</a>
|
||||
<a class="links" href="https://mcaptcha.org/terms">
|
||||
Terms
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
<style type="text/css" media="screen">
|
||||
.contaienr {
|
||||
max-width: 350px;
|
||||
max-height: 90px;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.noscript-container {
|
||||
display: flex;
|
||||
font-size: 0.7rem;
|
||||
line-height: 20px;
|
||||
flex-direction: column;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.warning {
|
||||
display: block;
|
||||
margin: auto;
|
||||
flex: 2;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.source-code {
|
||||
display: block;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
display: none;
|
||||
/*display: flex; */
|
||||
align-items: center;
|
||||
line-height: 30px;
|
||||
flex: 2;
|
||||
margin: auto;
|
||||
font-size: 0.99rem;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.details {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
flex: 2;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
font-size: 0.6rem;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
width: 45px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.links-container {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.links {
|
||||
font-size: 0.5rem;
|
||||
margin: 5px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.querySelector(".checkbox-label").style.display = "flex";
|
||||
</script>
|
||||
</html>
|
42
browser/tests/web.rs
Normal file
42
browser/tests/web.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
//! Test suite for the Web and headless browsers.
|
||||
|
||||
#![cfg(target_arch = "wasm32")]
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn pow_generation_works() {
|
||||
use mcaptcha_browser::*;
|
||||
use pow_sha256::*;
|
||||
|
||||
const SALT: &str = "yrandomsaltisnotlongenoug";
|
||||
const PHRASE: &str = "ironmansucks";
|
||||
const DIFFICULTY: u32 = 1000;
|
||||
let serialised_work = gen_pow(SALT.into(), PHRASE.into(), DIFFICULTY);
|
||||
|
||||
let work: Work = serde_json::from_str(&serialised_work).unwrap();
|
||||
|
||||
let work = PoWBuilder::default()
|
||||
.result(work.result)
|
||||
.nonce(work.nonce)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let config = ConfigBuilder::default().salt(SALT.into()).build().unwrap();
|
||||
assert!(config.is_valid_proof(&work, &PHRASE.to_string()));
|
||||
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||
}
|
22
build.rs
22
build.rs
|
@ -37,20 +37,24 @@ fn main() {
|
|||
}
|
||||
|
||||
fn cache_bust() {
|
||||
let types = vec![
|
||||
mime::IMAGE_PNG,
|
||||
mime::IMAGE_SVG,
|
||||
mime::IMAGE_JPEG,
|
||||
mime::IMAGE_GIF,
|
||||
mime::APPLICATION_JAVASCRIPT,
|
||||
mime::TEXT_CSS,
|
||||
];
|
||||
// until APPLICATION_WASM gets added to mime crate
|
||||
// PR: https://github.com/hyperium/mime/pull/138
|
||||
// let types = vec![
|
||||
// mime::IMAGE_PNG,
|
||||
// mime::IMAGE_SVG,
|
||||
// mime::IMAGE_JPEG,
|
||||
// mime::IMAGE_GIF,
|
||||
// mime::APPLICATION_JAVASCRIPT,
|
||||
// mime::TEXT_CSS,
|
||||
// ];
|
||||
|
||||
let no_hash = vec!["bundle/6b88f6ccf97567b46745.module.wasm"];
|
||||
|
||||
let config = BusterBuilder::default()
|
||||
.source("./static/cache")
|
||||
.result("./assets")
|
||||
.mime_types(types)
|
||||
.copy(true)
|
||||
.no_hash(no_hash)
|
||||
.follow_links(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
|
|
@ -226,6 +226,6 @@ async fn signout(id: Identity) -> impl Responder {
|
|||
id.forget();
|
||||
}
|
||||
HttpResponse::Found()
|
||||
.append_header((header::LOCATION, "/login"))
|
||||
.append_header((header::LOCATION, crate::PAGES.auth.login))
|
||||
.finish()
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ lazy_static! {
|
|||
FILES.get("./static/cache/bundle/bundle.css").unwrap();
|
||||
pub static ref MOBILE_CSS: &'static str =
|
||||
FILES.get("./static/cache/bundle/mobile.css").unwrap();
|
||||
|
||||
pub static ref VERIFICATIN_WIDGET_JS: &'static str =
|
||||
FILES.get("./static/cache/bundle/verificationWidget.js").unwrap();
|
||||
pub static ref VERIFICATIN_WIDGET_CSS: &'static str =
|
||||
|
|
|
@ -14,13 +14,9 @@
|
|||
* 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/>.
|
||||
*/
|
||||
use std::borrow::Cow;
|
||||
|
||||
use actix_web::body::Body;
|
||||
use actix_web::{get, http::header, web, HttpResponse, Responder};
|
||||
//! User facing CAPTCHA widget
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use lazy_static::lazy_static;
|
||||
use mime_guess::from_path;
|
||||
use rust_embed::RustEmbed;
|
||||
use sailfish::TemplateOnce;
|
||||
|
||||
use crate::errors::*;
|
||||
|
@ -30,16 +26,12 @@ pub const WIDGET_ROUTES: routes::Widget = routes::Widget::new();
|
|||
pub mod routes {
|
||||
pub struct Widget {
|
||||
pub verification_widget: &'static str,
|
||||
pub js: &'static str,
|
||||
pub wasm: &'static str,
|
||||
}
|
||||
|
||||
impl Widget {
|
||||
pub const fn new() -> Self {
|
||||
Widget {
|
||||
verification_widget: "/widget",
|
||||
js: "/widget/bundle.js",
|
||||
wasm: "/widget/1476099975f2b060264c.module.wasm",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,37 +61,9 @@ async fn show_widget() -> PageResult<impl Responder> {
|
|||
.body(&*INDEX_PAGE))
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "static/widget/"]
|
||||
struct WidgetAssets;
|
||||
|
||||
fn handle_widget_assets(path: &str) -> HttpResponse {
|
||||
match WidgetAssets::get(path) {
|
||||
Some(content) => {
|
||||
let body: Body = match content {
|
||||
Cow::Borrowed(bytes) => bytes.into(),
|
||||
Cow::Owned(bytes) => bytes.into(),
|
||||
};
|
||||
|
||||
HttpResponse::Ok()
|
||||
.insert_header(header::CacheControl(vec![
|
||||
header::CacheDirective::MaxAge(crate::CACHE_AGE),
|
||||
]))
|
||||
.content_type(from_path(path).first_or_octet_stream().as_ref())
|
||||
.body(body)
|
||||
}
|
||||
None => HttpResponse::NotFound().body("404 Not Found"),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/widget/{_:.*}")]
|
||||
pub async fn widget_assets(path: web::Path<String>) -> impl Responder {
|
||||
handle_widget_assets(&path)
|
||||
}
|
||||
|
||||
/// widget services
|
||||
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(show_widget);
|
||||
cfg.service(widget_assets);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -112,17 +76,6 @@ mod test {
|
|||
#[actix_rt::test]
|
||||
async fn captcha_widget_route_works() {
|
||||
let mut app = get_app!().await;
|
||||
// let list_sitekey_resp = test::call_service(
|
||||
// &mut app,
|
||||
// test::TestRequest::get()
|
||||
// .uri(crate::WIDGET_ROUTES.verification_widget)
|
||||
// .to_request(),
|
||||
// )
|
||||
// .await;
|
||||
// assert_eq!(list_sitekey_resp.status(), StatusCode::OK);
|
||||
|
||||
get_works!(app, crate::WIDGET_ROUTES.verification_widget);
|
||||
get_works!(app, crate::WIDGET_ROUTES.js);
|
||||
get_works!(app, crate::WIDGET_ROUTES.wasm);
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -5,7 +5,5 @@
|
|||
href="<.= &*crate::VERIFICATIN_WIDGET_CSS .>"
|
||||
/>
|
||||
<script src="<.= &*crate::VERIFICATIN_WIDGET_JS .>"></script>
|
||||
<script src="<.= &*crate::WIDGET_ROUTES.js .>"></script>
|
||||
<script src="<.= &*crate::WIDGET_ROUTES.wasm .>"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
152
templates/widget/js/const.ts
Normal file
152
templates/widget/js/const.ts
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
/** mcaptcha checkbox ID **/
|
||||
export const btnId = 'widget__verification-checkbox';
|
||||
|
||||
/** get sitekey */
|
||||
export const sitekey = () => {
|
||||
let sitekey;
|
||||
return (() => {
|
||||
if (sitekey === null || sitekey === undefined) {
|
||||
sitekey = new URL(window.location.href).searchParams.get('sitekey');
|
||||
if (sitekey === null || sitekey === undefined) {
|
||||
throw new Error(`Define sitekey in query parameter`);
|
||||
}
|
||||
}
|
||||
return sitekey;
|
||||
})();
|
||||
};
|
||||
|
||||
/** mCaptcha API routes */
|
||||
export const ROUTES = (() => {
|
||||
const getConfig = '/api/v1/pow/config';
|
||||
const verififyPoW = '/api/v1/pow/verify';
|
||||
|
||||
return {
|
||||
/** get URL to fetch PoW configuration */
|
||||
getConfig,
|
||||
/** get URL to verify PoW*/
|
||||
verififyPoW,
|
||||
};
|
||||
})();
|
||||
|
||||
/** get mCaptcha verifify checkbox button */
|
||||
export const btn = () => {
|
||||
let btn;
|
||||
return (() => {
|
||||
if (btn === null || btn === undefined) {
|
||||
btn = <HTMLInputElement>document.getElementById(btnId);
|
||||
if (btn === null || btn === undefined) {
|
||||
throw new Error(`mCaptcha button not found)`);
|
||||
}
|
||||
}
|
||||
return btn;
|
||||
})();
|
||||
};
|
||||
|
||||
export const messageText = () => {
|
||||
let beforeClass = 'widget__verification-text--before';
|
||||
let duringClass = 'widget__verification-text--during';
|
||||
let errorClass = 'widget__verification-text--error';
|
||||
let afterClass = 'widget__verification-text--after';
|
||||
|
||||
let before: HTMLElement;
|
||||
let after: HTMLElement;
|
||||
let during: HTMLElement;
|
||||
let error: HTMLElement;
|
||||
|
||||
/** runner fn to display HTMLElement **/
|
||||
const showMsg = (e: HTMLElement) => (e.style.display = 'block');
|
||||
/** runner fn to hide HTMLElement **/
|
||||
const hideMsg = (e: HTMLElement) => (e.style.display = 'none');
|
||||
|
||||
/** lazy init and get before elementt **/
|
||||
const getBefore = () => {
|
||||
if (before === null || before === undefined) {
|
||||
before = <HTMLElement>document.querySelector(`.${beforeClass}`);
|
||||
if (before === null || before === undefined) {
|
||||
throw new Error(`before element not found)`);
|
||||
}
|
||||
return before;
|
||||
}
|
||||
};
|
||||
|
||||
/** lazy init and get after elementt **/
|
||||
const getAfter = () => {
|
||||
if (after === null || after === undefined) {
|
||||
after = <HTMLSpanElement>document.querySelector(`.${afterClass}`);
|
||||
if (after === null || after === undefined) {
|
||||
throw new Error(`after element not found)`);
|
||||
}
|
||||
}
|
||||
|
||||
return after;
|
||||
};
|
||||
|
||||
/** lazy init and get error elementt **/
|
||||
const getError = () => {
|
||||
if (error === null || error === undefined) {
|
||||
error = <HTMLSpanElement>document.querySelector(`.${errorClass}`);
|
||||
if (error === null || error === undefined) {
|
||||
throw new Error(`before error not found)`);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
/** lazy init and get during elementt **/
|
||||
const getDuring = () => {
|
||||
if (during === null || during === undefined) {
|
||||
during = <HTMLSpanElement>document.querySelector(`.${duringClass}`);
|
||||
if (during === null || during === undefined) {
|
||||
throw new Error(`before during not found)`);
|
||||
}
|
||||
}
|
||||
|
||||
return during;
|
||||
};
|
||||
return {
|
||||
/** display "before" message **/
|
||||
before: () => {
|
||||
showMsg(getBefore());
|
||||
hideMsg(getAfter());
|
||||
hideMsg(getDuring());
|
||||
hideMsg(getError());
|
||||
},
|
||||
|
||||
/** display "after" message **/
|
||||
after: () => {
|
||||
hideMsg(getBefore());
|
||||
showMsg(getAfter());
|
||||
hideMsg(getDuring());
|
||||
hideMsg(getError());
|
||||
},
|
||||
|
||||
/** display "during" message **/
|
||||
during: () => {
|
||||
hideMsg(getBefore());
|
||||
hideMsg(getAfter());
|
||||
showMsg(getDuring());
|
||||
hideMsg(getError());
|
||||
},
|
||||
|
||||
/** display "error" message **/
|
||||
error: () => {
|
||||
hideMsg(getBefore());
|
||||
hideMsg(getAfter());
|
||||
hideMsg(getDuring());
|
||||
showMsg(getError());
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const inputId = 'mcaptcha-response';
|
48
templates/widget/js/fetchPoWConfig.ts
Normal file
48
templates/widget/js/fetchPoWConfig.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
import genJsonPayload from './utils/genJsonPayload';
|
||||
import * as CONST from './const';
|
||||
|
||||
type GetConfigPayload = {
|
||||
key: string;
|
||||
};
|
||||
|
||||
export type PoWConfig = {
|
||||
string: string;
|
||||
difficulty_factor: number;
|
||||
salt: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* fetch proof-of-work configuration
|
||||
* @returns {PoWConfig} pow config
|
||||
* */
|
||||
export const fetchPoWConfig = async () => {
|
||||
try {
|
||||
const payload: GetConfigPayload = {
|
||||
key: CONST.sitekey(),
|
||||
};
|
||||
|
||||
const res = await fetch(CONST.ROUTES.getConfig, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
const config: PoWConfig = await res.json();
|
||||
return config;
|
||||
} else {
|
||||
const err = await res.json();
|
||||
throw new Error(err);
|
||||
}
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
export default fetchPoWConfig;
|
68
templates/widget/js/index.ts
Normal file
68
templates/widget/js/index.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
import prove from './prove';
|
||||
import fetchPoWConfig from './fetchPoWConfig';
|
||||
import sendWork from './sendWork';
|
||||
import sendToParent from './sendToParent';
|
||||
import * as CONST from './const';
|
||||
|
||||
import '../main.scss';
|
||||
|
||||
let LOCK = false;
|
||||
|
||||
/** add mcaptcha widget element to DOM */
|
||||
export const registerVerificationEventHandler = () => {
|
||||
const verificationContainer = <HTMLElement>(
|
||||
document.querySelector('.widget__verification-container')
|
||||
);
|
||||
verificationContainer.style.display = 'flex';
|
||||
CONST.btn().addEventListener('click', e => solveCaptchaRunner(e));
|
||||
};
|
||||
|
||||
export const solveCaptchaRunner = async (e: Event) => {
|
||||
if (LOCK) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
LOCK = true;
|
||||
if (CONST.btn().checked == false) {
|
||||
CONST.messageText().before();
|
||||
LOCK = false;
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
// steps:
|
||||
|
||||
// 1. show during
|
||||
CONST.messageText().during();
|
||||
// 1. get config
|
||||
const config = await fetchPoWConfig();
|
||||
// 2. prove work
|
||||
const proof = await prove(config);
|
||||
// 3. submit work
|
||||
const token = await sendWork(proof);
|
||||
// 4. send token
|
||||
sendToParent(token);
|
||||
// 5. mark checkbox checked
|
||||
CONST.btn().checked = true;
|
||||
CONST.messageText().after();
|
||||
LOCK = false;
|
||||
} catch (e) {
|
||||
CONST.messageText().error();
|
||||
console.error(e);
|
||||
LOCK = false;
|
||||
}
|
||||
};
|
||||
|
||||
registerVerificationEventHandler();
|
55
templates/widget/js/prove.ts
Normal file
55
templates/widget/js/prove.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
import {gen_pow} from '../../../browser/pkg/index';
|
||||
import {PoWConfig} from './fetchPoWConfig';
|
||||
import * as CONST from './const';
|
||||
|
||||
export type Work = {
|
||||
result: string;
|
||||
nonce: number;
|
||||
string: string;
|
||||
key: string;
|
||||
};
|
||||
|
||||
type WasmWork = {
|
||||
result: string;
|
||||
nonce: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* proove work
|
||||
* @param {PoWConfig} config - the proof-of-work configuration using which
|
||||
* work needs to be computed
|
||||
* */
|
||||
const prove = async (config: PoWConfig) => {
|
||||
try {
|
||||
const proofString = gen_pow(
|
||||
config.salt,
|
||||
config.string,
|
||||
config.difficulty_factor,
|
||||
);
|
||||
const proof: WasmWork = JSON.parse(proofString);
|
||||
|
||||
const res: Work = {
|
||||
key: CONST.sitekey(),
|
||||
string: config.string,
|
||||
nonce: proof.nonce,
|
||||
result: proof.result,
|
||||
};
|
||||
|
||||
return res;
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
export default prove;
|
24
templates/widget/js/sendToParent.ts
Normal file
24
templates/widget/js/sendToParent.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
import {Token} from './sendWork';
|
||||
|
||||
/**
|
||||
* send pow validation token as message to parant of the iframe
|
||||
* @param {Token} token: token received from mCaptcha service
|
||||
* upon successful PoW validation
|
||||
* */
|
||||
export const sendToParent = (token: Token) => {
|
||||
window.parent.postMessage(token, '*');
|
||||
// TODO set origin. Make parent send origin as query parameter
|
||||
// or as a message to iframe
|
||||
};
|
||||
|
||||
export default sendToParent;
|
42
templates/widget/js/sendWork.ts
Normal file
42
templates/widget/js/sendWork.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
import genJsonPayload from './utils/genJsonPayload';
|
||||
import * as CONST from './const';
|
||||
import {Work} from './prove';
|
||||
|
||||
export type Token = {
|
||||
token: string;
|
||||
};
|
||||
|
||||
export const sendWork = async (payload: Work) => {
|
||||
try {
|
||||
const res = await fetch(CONST.ROUTES.verififyPoW, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
console.debug('work verified');
|
||||
const token: Token = await res.json();
|
||||
console.debug(`token ${token.token}`);
|
||||
return token;
|
||||
} else {
|
||||
const err = await res.json();
|
||||
console.error(`error: ${err.error}`);
|
||||
throw new Error(err);
|
||||
}
|
||||
} catch (err) {
|
||||
CONST.messageText().error();
|
||||
console.error(err);
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
window.location.reload();
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
export default sendWork;
|
50
templates/widget/js/tests/const.test.ts
Normal file
50
templates/widget/js/tests/const.test.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
import * as CONST from '../const';
|
||||
|
||||
import {getBaseHtml, sitekey, checkbox} from './setupTests';
|
||||
import * as TESTElements from './setupTests';
|
||||
|
||||
it('const works', () => {
|
||||
const body = document.querySelector('body');
|
||||
const container = getBaseHtml();
|
||||
body.appendChild(container);
|
||||
expect(CONST.sitekey()).toBe(sitekey);
|
||||
expect(CONST.btn()).toBe(checkbox);
|
||||
|
||||
// display after
|
||||
CONST.messageText().after();
|
||||
expect(TESTElements.afterMsg.style.display).toBe('block');
|
||||
expect(TESTElements.beforeMsg.style.display).toBe('none');
|
||||
expect(TESTElements.duringMsg.style.display).toBe('none');
|
||||
expect(TESTElements.errorMsg.style.display).toBe('none');
|
||||
|
||||
// display before
|
||||
CONST.messageText().before();
|
||||
expect(TESTElements.afterMsg.style.display).toBe('none');
|
||||
expect(TESTElements.beforeMsg.style.display).toBe('block');
|
||||
expect(TESTElements.duringMsg.style.display).toBe('none');
|
||||
expect(TESTElements.errorMsg.style.display).toBe('none');
|
||||
|
||||
// display during
|
||||
CONST.messageText().during();
|
||||
expect(TESTElements.afterMsg.style.display).toBe('none');
|
||||
expect(TESTElements.beforeMsg.style.display).toBe('none');
|
||||
expect(TESTElements.duringMsg.style.display).toBe('block');
|
||||
expect(TESTElements.errorMsg.style.display).toBe('none');
|
||||
|
||||
// display error
|
||||
CONST.messageText().error();
|
||||
expect(TESTElements.afterMsg.style.display).toBe('none');
|
||||
expect(TESTElements.beforeMsg.style.display).toBe('none');
|
||||
expect(TESTElements.duringMsg.style.display).toBe('none');
|
||||
expect(TESTElements.errorMsg.style.display).toBe('block');
|
||||
});
|
40
templates/widget/js/tests/setupTests.ts
Normal file
40
templates/widget/js/tests/setupTests.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
import * as CONST from '../const';
|
||||
|
||||
export const sitekey = 'imbatman';
|
||||
|
||||
export const checkbox = <HTMLInputElement>document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.id = CONST.btnId;
|
||||
|
||||
const getMessages = (state: string) => {
|
||||
const msg = <HTMLElement>document.createElement('span');
|
||||
msg.className = `widget__verification-text--${state}`;
|
||||
return msg;
|
||||
};
|
||||
|
||||
export const beforeMsg = getMessages('before');
|
||||
export const afterMsg = getMessages('after');
|
||||
export const duringMsg = getMessages('during');
|
||||
export const errorMsg = getMessages('error');
|
||||
|
||||
/** get base HTML with empty mCaptcha container */
|
||||
export const getBaseHtml = () => {
|
||||
const form = <HTMLFormElement>document.createElement('form');
|
||||
form.appendChild(checkbox);
|
||||
form.appendChild(beforeMsg);
|
||||
form.appendChild(duringMsg);
|
||||
form.appendChild(afterMsg);
|
||||
form.appendChild(errorMsg);
|
||||
|
||||
return form;
|
||||
};
|
30
templates/widget/js/utils/genJsonPayload.test.ts
Normal file
30
templates/widget/js/utils/genJsonPayload.test.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
import genJsonPayload from './genJsonPayload';
|
||||
|
||||
'use strict';
|
||||
|
||||
const payload = {
|
||||
username: 'Jhon',
|
||||
};
|
||||
|
||||
const value = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
};
|
||||
|
||||
it('getFromUrl workds', () => {
|
||||
expect(genJsonPayload(payload)).toEqual(value);
|
||||
});
|
23
templates/widget/js/utils/genJsonPayload.ts
Normal file
23
templates/widget/js/utils/genJsonPayload.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* mCaptcha is a PoW based DoS protection software.
|
||||
* This is the frontend web component of the mCaptcha system
|
||||
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||
*
|
||||
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||
*/
|
||||
|
||||
const genJsonPayload = (payload: any) => {
|
||||
const value = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
};
|
||||
return value;
|
||||
};
|
||||
|
||||
export default genJsonPayload;
|
|
@ -11,7 +11,7 @@ module.exports = {
|
|||
entry: {
|
||||
bundle: './templates/index.ts',
|
||||
mobile: './templates/mobile.ts',
|
||||
verificationWidget: './templates/widget/index.ts',
|
||||
verificationWidget: './templates/widget/js/index.ts',
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
|
@ -45,10 +45,10 @@ module.exports = {
|
|||
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin(),
|
||||
// new WasmPackPlugin({
|
||||
// crateDirectory: __dirname,
|
||||
// outName: "pow.wasm",
|
||||
// }),
|
||||
// new WasmPackPlugin({
|
||||
// crateDirectory: __dirname,
|
||||
// outName: "pow.wasm",
|
||||
// }),
|
||||
],
|
||||
optimization: {
|
||||
minimizer: [
|
||||
|
@ -57,13 +57,13 @@ module.exports = {
|
|||
new CssMinimizerPlugin(),
|
||||
],
|
||||
},
|
||||
// experiments: {
|
||||
// // executeModule: true,
|
||||
// // outputModule: true,
|
||||
// //syncWebAssembly: true,
|
||||
// // topLevelAwait: true,
|
||||
// asyncWebAssembly: true,
|
||||
// // layers: true,
|
||||
// // lazyCompilation: true,
|
||||
// },
|
||||
experiments: {
|
||||
// executeModule: true,
|
||||
// outputModule: true,
|
||||
//syncWebAssembly: true,
|
||||
// topLevelAwait: true,
|
||||
asyncWebAssembly: true,
|
||||
// layers: true,
|
||||
// lazyCompilation: true,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue