Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] Migrate to Prosopo Procaptcha #2

Closed
wants to merge 36 commits into from

Conversation

Bullrich
Copy link

@Bullrich Bullrich commented Mar 1, 2024

Fixes paritytech#337

PR to migrate rococo faucet from reCAPTCHA to Prosopo Procaptcha, which runs on the rococo test network.

Overview

When using Procaptcha, the flow of data in the faucet client app is as follows :

Frontend Flow

  1. The user enters the page.
  2. The user selects their network and how many tokens they require.
  3. The user clicks the Procaptcha check box.
  4. A Polkadot user_account is generated using fingerprinting as random entropy
  5. The user_account and the faucet's site_key are passed to the Procaptcha Contract in rococo, and details of a random Captcha Provider are returned.
  6. The rococo network is contacted, querying the Procaptcha Contract, and a Captcha Provider is returned
  7. The website asks the Captcha Provider for a challenge, passing the site_key, user_account, block_number, and other data related to the Captcha Provider.
  8. The Captcha Provider checks it was randomly selected by the Procaptcha Contract, by submitting the same read performed in step 5. using historical block data (e.g. queryAt(block_number))
  9. Assuming step 8. is successful, the Captcha Provider returns a challenge
  10. The user completes the challenge, and passes the solution to the Captcha Provider. If the solution is correct, the checkbox becomes ticked, a challenge payload is added to the form, and the form submission button becomes enabled
  11. The user presses the form submission button and the form data + captcha payload are sent to the faucet backend

Additional Info

Page Reloads

We noticed that the reCAPTCHA implementation would ask the user for a new captcha on every page load. We have recreated this functionality using procaptcha by clearing any local storage on load of the CaptchaV2.svelte component. This prevents a locally stored Captcha Provider from being contacted on page reload, and passing the user_account due to their historical records stored on the Captcha Provider.

Max Verified Time

The maximum amount of time a captcha solution is valid for is 60s. This can be changed using the env variable PROCAPTCHA_MAX_VERIFIED_TIME, which takes a millisecond amount.

Backend Flow

We'll begin the backend flow from where the frontend flow left off.

  1. The backend receives the form data from the frontend.
  2. The backend takes the Procaptcha payload and passes it to a TypeScript package called @prosopo/server.
  3. This package performs the following checks
    a. Check if the provider was actually chosen at block_number
    b. If a provider_url is passed with the payload, the Captcha Provider is contacted to verify the user. Otherwise, read the user_account score from the contract directly after checking the time since the last correct captcha is less than the maxVerifiedTime (60s, mentioned previously)
  4. After 3a. or 3b. the user is either verified via a Captcha Provider or the Procaptcha Contract and will be permitted or denied their funds.

Testing

Client

Our client bundle continues to reach out to the rococo network for a random provider and the provider sends a real captcha. Solving this is clearly out of scope for UI tests so the provider is patched by injecting our mock provider (https://mockprovider.prosopo.io) into local storage. The mock provider always returns { "success": true } for the Alice account and the test site_key=5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM, which is the all zero address.

E2E

As we are using a contract to return a provider, we implemented an additional contracts parachain in the E2E tests. This requires us to do the following:

  1. deploy the Procaptcha Contract
  2. register a Captcha Provider in the contract (We register our mock provider - https://mockprovider.prosopo.io)
  3. store a Captcha Provider dataset in the contract
  4. register an app (site_key) in the contract

Then when a random provider is selected, it is always the mock provider. Again, passing a user_account of Alice's address and the zero address for site_key returns { "success": true }. Obviously, the downside here is the time taken for transactions in 12s parachains in zombienet. We have tried to use the substrate-contracts-node, which has instant seal, alongside the zombienet configuration but didn't succeed.

We would appreciate any feedback on the approach so far!


Copied from paritytech#372

forgetso and others added 5 commits February 22, 2024 12:36
* working frontend temp

* temp

* package json fix

* npm version bump

* Drip request type changing to procaptcha

* Drip request type changing to procaptcha

* swapping all occurrences of recaptcha with procaptcha and adding captcha logic

* Renaming recaptcha files and updating imports

* adding Prosopo outputs to tests

* bugtesting

* Removing bundle and adding back regular tests

* changing frontend to use remote bundle

* Add CAPTCHA_PROVIDER config item

* add feature flag for captcha provider and update tests for procaptcha

* Add react deps

* Add test configs for both captcha providers

* lint:fix and yarn install

* add Paseo testnet config

* remove wococo testnet config

* Adding forgotten paseo deployment

* Address PR comments

* Fix dummy body

* Add debug

* Bump the npm_and_yarn group across 1 directories with 1 update (paritytech#368)

* Create e2e test environment for procaptcha

* remove rogue file

* Update zombienet config in workflow

* yarn.lock

* yarn.lock

* downgrade jest

* try fix for buildcheck

* Pin polkadot versions

* yarn.lock with 1.22.21

* try new yarn.lock

* Update faucet lockfile

* Procaptcha dev (#2)

* dev setup wip

* update docker setup for procaptcha

* Remove extra unecessary stuff

* Undo formatting

* Update mock provider URL to use prosopo subdomain

* bump prosopo versions

* add missing dep

* Update to working package versions

* Upgrade prosopo deps

* Add missing body parameter

---------

Co-authored-by: Hugh <hughglynparry@gmail.com>
Co-authored-by: hugh <hugh@prosopo.io>
Co-authored-by: Pierre Besson <pierre.besson@parity.io>
Co-authored-by: Yuri Volkov <0@mcornholio.ru>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@Bullrich Bullrich changed the title Migrate to Prosopo Procaptcha [TEST] Migrate to Prosopo Procaptcha Mar 1, 2024
@paritytech-stg paritytech-stg deleted a comment from cla-bot-2021-stg bot Mar 1, 2024
mutantcornholio and others added 16 commits March 5, 2024 20:07
Fixes paritytech#223

+ Adding prom-client dependency, because it was removed from
@eng-automation/js (rightfully so)
@josepot has reported an error with `@zombienet/cli@1.3.43`, while the
latest version worked
* Currently, e2e types are generated on postinstall and prebuild steps,
which requires metadata to be available in Docker image, even though
it's not technically used in the application code. I think separating
things would make things more complicated, but it's possible.
* Couldn't undestand the reason for having two different COPY
instructions
in Dockerfile, but that doesn't live well with generating types in
postinstall, so merging those two
* .scale metadata files from Zombienet hosts saved in the codebase,
in order to be able to compile the code separately from running
Zombienet
This removes the base url, making the website work on the root of the
domain.

Also, by doing this change, and having set up the dns, this resolves
paritytech#348
It generates a JSON object inside the header following the instructions
from:
https://developers.google.com/search/docs/appearance/structured-data/faqpage

It parses the information of the markdown text to generate this json
object.

This resolves paritytech#277
We currently don't have an artifact retention period, so it defaults to
90 days.

While the artifact for the site is not too big, having one build per
push and PR can quickly accumulate the amount and make us hit our hard
limit.

By adding a limit to the retention day of 5 days we ensure that we get
rid of the old artifacts faster than waiting for two whole months.

I also updated all the actions version to latest release
* lockfile update

* Upgrade deps

* Package-lock.json

* Updating e2e tests readme (paritytech#375)

* Fixing e2e readme link

* Adding runtimeRestarter (paritytech#376)

Fixes paritytech#223

+ Adding prom-client dependency, because it was removed from
@eng-automation/js (rightfully so)

* Updating zombinenet verion in e2e docs (paritytech#378)

@josepot has reported an error with `@zombienet/cli@1.3.43`, while the
latest version worked

* Using PAPI for e2e tests (paritytech#379)

* Currently, e2e types are generated on postinstall and prebuild steps,
which requires metadata to be available in Docker image, even though
it's not technically used in the application code. I think separating
things would make things more complicated, but it's possible.
* Couldn't undestand the reason for having two different COPY
instructions
in Dockerfile, but that doesn't live well with generating types in
postinstall, so merging those two
* .scale metadata files from Zombienet hosts saved in the codebase,
in order to be able to compile the code separately from running
Zombienet

* Update dependencies

* yarn.lock

* Bump the npm_and_yarn group across 2 directories with 2 updates (paritytech#381)

* removed base url (paritytech#382)

This removes the base url, making the website work on the root of the
domain.

Also, by doing this change, and having set up the dns, this resolves
paritytech#348

* Update deps

* Update API calls

* Silence polkadot API type errors

* Update captcha type to image and set width of captcha container

* remove grid class

* switch back to PJS. change port number

* remove prettier deps

* update port

* set procaptcha details

* fix dropdown z-index

* Fix z-indexes

* Change mock provider version

* remove console.errors

---------

Co-authored-by: Yuri Volkov <0@mcornholio.ru>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Javier Bullrich <javier@bullrich.dev>
As the Frequency Faucet now also supports Frequency Paseo testnet in
addition to the Rococo one, the url is being set to a generic one
instead of specific for the network.

https://faucet.testnet.frequency.xyz/
It fails when an external contributors make a PR.

This will fix that issue.
* Updating e2e tests readme (paritytech#375)

* Fixing e2e readme link

* Adding runtimeRestarter (paritytech#376)

Fixes paritytech#223

+ Adding prom-client dependency, because it was removed from
@eng-automation/js (rightfully so)

* Updating zombinenet verion in e2e docs (paritytech#378)

@josepot has reported an error with `@zombienet/cli@1.3.43`, while the
latest version worked

* Using PAPI for e2e tests (paritytech#379)

* Currently, e2e types are generated on postinstall and prebuild steps,
which requires metadata to be available in Docker image, even though
it's not technically used in the application code. I think separating
things would make things more complicated, but it's possible.
* Couldn't undestand the reason for having two different COPY
instructions
in Dockerfile, but that doesn't live well with generating types in
postinstall, so merging those two
* .scale metadata files from Zombienet hosts saved in the codebase,
in order to be able to compile the code separately from running
Zombienet

* Bump the npm_and_yarn group across 2 directories with 2 updates (paritytech#381)

* removed base url (paritytech#382)

This removes the base url, making the website work on the root of the
domain.

Also, by doing this change, and having set up the dns, this resolves
paritytech#348

* Added markup code generation (paritytech#383)

It generates a JSON object inside the header following the instructions
from:
https://developers.google.com/search/docs/appearance/structured-data/faqpage

It parses the information of the markdown text to generate this json
object.

This resolves paritytech#277

* Updated actions to latest and added retention period (paritytech#384)

We currently don't have an artifact retention period, so it defaults to
90 days.

While the artifact for the site is not too big, having one build per
push and PR can quickly accumulate the amount and make us hit our hard
limit.

By adding a limit to the retention day of 5 days we ensure that we get
rid of the old artifacts faster than waiting for two whole months.

I also updated all the actions version to latest release

* Bump the npm_and_yarn group across 1 directory with 1 update (paritytech#385)

* Bump the npm_and_yarn group across 1 directory with 1 update (paritytech#387)

* Update Frequency Faucet URL (paritytech#393)

As the Frequency Faucet now also supports Frequency Paseo testnet in
addition to the Rococo one, the url is being set to a generic one
instead of specific for the network.

https://faucet.testnet.frequency.xyz/

* moved tag-client to work in pull_request_target (paritytech#394)

It fails when an external contributors make a PR.

This will fix that issue.

* Merge latest upstream and use a transaction queue to send txs to nodes

* Add MIT LICENSE (paritytech#395)

* bump to polkadot 10.13.1

* lockfile

* yarn.lock

* yarn.lock

* yarn.lock

* yarn.lock

* yarn.lock client

* Fix test mock

* Add @polkadot/util to dev dependencies

* Address comments from @mutantcornholio

---------

Co-authored-by: Yuri Volkov <0@mcornholio.ru>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Javier Bullrich <javier@bullrich.dev>
Co-authored-by: Wil Wade <wil@wilwade.com>
Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com>
@cla-bot-2021-stg
Copy link

User @wilwade, please sign the CLA here.

forgetso and others added 9 commits April 29, 2024 16:39
* Update paseo RPC wss://sys.dotters.network/paseo (paritytech#398)

* Prettier write

* Make properties public. Remove try catches. Lint

* remove console.log

* Increase test timeout

* try installing playwright with yarn

---------

Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com>
* Update paseo RPC wss://sys.dotters.network/paseo (paritytech#398)

* Prettier write

* Make properties public. Remove try catches. Lint

* remove console.log

* Increase test timeout

* try installing playwright with yarn

* Moved GitLab checks to GitHub's action (paritytech#402)

Resolves paritytech#401

* Bump yaml from 2.4.1 to 2.4.2 in /client in the npm_and_yarn group across 1 directory (paritytech#403)

* remove empty spaces

* Address more PR comments

* Address comments

* Add type check function to test file

* Fix import so that it works from tests dir2

* Update eng-automation

* fix import

* try after linting

* Suppress ESLint to get CICD to run

* yarn:fix

* pass block number to mock provider

* fix tests

* yarn format:fix

---------

Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com>
Co-authored-by: Javier Bullrich <javier@bullrich.dev>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@Bullrich Bullrich closed this May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PoC: Migrate to Prosopo
5 participants