[PR #1476] [MERGED] Feature/use hcaptcha if bot #51132

Closed
opened 2026-05-01 14:44:07 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/bitwarden/android/pull/1476
Author: @MGibson1
Created: 7/23/2021
Status: Merged
Merged: 8/4/2021
Merged by: @MGibson1

Base: masterHead: feature/use-hcaptcha-if-bot


📝 Commits (7)

  • 3047073 Add captcha to login models and methods
  • 152084e Add captcha web auth to login
  • b1cac34 Extract captcha to abstract base class
  • b0c38af Add Captcha to register
  • 2d233d5 Null out captcha token after each successful challenge
  • 45321fd Merge branch 'master' into feature/use-hcaptcha-if-bot
  • bd55131 Cancel > close

📊 Changes

18 files changed (+334 additions, -54 deletions)

View changed files

📝 src/App/Pages/Accounts/LoginPage.xaml (+1 -1)
📝 src/App/Pages/Accounts/LoginPageViewModel.cs (+55 -5)
📝 src/App/Pages/Accounts/RegisterPage.xaml (+1 -1)
📝 src/App/Pages/Accounts/RegisterPageViewModel.cs (+45 -3)
src/App/Pages/CaptchaProtectedViewModel.cs (+88 -0)
📝 src/App/Resources/AppResources.Designer.cs (+24 -12)
📝 src/App/Resources/AppResources.resx (+6 -0)
📝 src/Core/Abstractions/IApiService.cs (+1 -1)
📝 src/Core/Abstractions/IAuthService.cs (+1 -1)
📝 src/Core/Models/Domain/AuthResult.cs (+2 -0)
📝 src/Core/Models/Request/RegisterRequest.cs (+1 -0)
📝 src/Core/Models/Request/TokenRequest.cs (+8 -1)
📝 src/Core/Models/Response/ErrorResponse.cs (+6 -0)
src/Core/Models/Response/IdentityCaptchaResponse.cs (+13 -0)
src/Core/Models/Response/IdentityResponse.cs (+50 -0)
📝 src/Core/Models/Response/IdentityTwoFactorResponse.cs (+3 -0)
📝 src/Core/Services/ApiService.cs (+7 -17)
📝 src/Core/Services/AuthService.cs (+22 -12)

📄 Description

Overview

Adding captcha responses to Login and Registration failures due to suspected bot requests. The basic flow is to attempt the request, fail with a captcha siteKey in the response, use that site key to show a web auth and retrieve a captcha token, and finally reattempt the request with the acquired token.

I couldn't find a good example for DI to a parent ViewModel in the solution already. I chose abstract properties to pass required services to the parent CaptchaProtectedViewModel because I still want to have the dependencies gathered at the highest level and passed down. It didn't make sense to me to grab the dependencies multiple times, but this would be my second favorite approach.

Files Changed

  • loginPage.xaml/registerPage.xaml: On my simulator I was getting long load times for the second request attempt post-captcha that was displaying the login or register page again. I'm disabling the submit buttons until the second attempt is completed.
  • LoginPageViewModel: Inherits from CaptchaProtectedViewModel to get all the captcha handling goodies. Add loading binding to disable submit and handle captcha required by reattempting once the base class set _captchaToken.
  • RegisterPageViewModel: Same as LoginPageViewModel, except the captcha requirement comes in as an ApiException. This is due to the differences in failure modes server-side. Indentity failures are just failed auth requests, whereas API failures are returned as Bad Requests and thrown.
  • CaptchaProtectedViewModel: Initialize a WebAuthenticator when captcha is required and retrieve a token response on success. If we don't get a token, signal failure. The EncodeB64 method matches the... odd... way we're encoding iframe data in the web vault (https://github.com/bitwarden/jslib/blob/master/common/src/misc/iframe_component.ts#L30-L34 && https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings)
  • AppResources: Localize Captcha strings
  • ApiService: Parse out IdentityCaptchaResponse as well as Token and Two Factor. This is primarily handled in the new return class.
  • AuthService: Add Captcha to login. A two factor captcha bypass token is stored for subsequent calls

Screenshots

Login PreCaptcha

image

Login/register captcha

image

Login/register captcha with images (pixel 3a)

image

Login back out of captcha

image

Register precaptcha

image

Register back out of captcha

image

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/bitwarden/android/pull/1476 **Author:** [@MGibson1](https://github.com/MGibson1) **Created:** 7/23/2021 **Status:** ✅ Merged **Merged:** 8/4/2021 **Merged by:** [@MGibson1](https://github.com/MGibson1) **Base:** `master` ← **Head:** `feature/use-hcaptcha-if-bot` --- ### 📝 Commits (7) - [`3047073`](https://github.com/bitwarden/android/commit/30470731a1ea5aa059242a3af8e093fab1b2f7bc) Add captcha to login models and methods - [`152084e`](https://github.com/bitwarden/android/commit/152084eebec0d95b812c2ca5c9b8bc1fee4586d1) Add captcha web auth to login - [`b1cac34`](https://github.com/bitwarden/android/commit/b1cac34e5aacb9a57663b9df4d8f2d18ac356323) Extract captcha to abstract base class - [`b0c38af`](https://github.com/bitwarden/android/commit/b0c38af7108e1c5d96691471bffff87f250b0412) Add Captcha to register - [`2d233d5`](https://github.com/bitwarden/android/commit/2d233d5471660069a43115b06dd11a6fc2bbdb5e) Null out captcha token after each successful challenge - [`45321fd`](https://github.com/bitwarden/android/commit/45321fddc93d3aaf7ea2fb5d4c4806d5d4aee17a) Merge branch 'master' into feature/use-hcaptcha-if-bot - [`bd55131`](https://github.com/bitwarden/android/commit/bd5513195ebbe5e4e8d8a2a8bf89ca92469e4752) Cancel > close ### 📊 Changes **18 files changed** (+334 additions, -54 deletions) <details> <summary>View changed files</summary> 📝 `src/App/Pages/Accounts/LoginPage.xaml` (+1 -1) 📝 `src/App/Pages/Accounts/LoginPageViewModel.cs` (+55 -5) 📝 `src/App/Pages/Accounts/RegisterPage.xaml` (+1 -1) 📝 `src/App/Pages/Accounts/RegisterPageViewModel.cs` (+45 -3) ➕ `src/App/Pages/CaptchaProtectedViewModel.cs` (+88 -0) 📝 `src/App/Resources/AppResources.Designer.cs` (+24 -12) 📝 `src/App/Resources/AppResources.resx` (+6 -0) 📝 `src/Core/Abstractions/IApiService.cs` (+1 -1) 📝 `src/Core/Abstractions/IAuthService.cs` (+1 -1) 📝 `src/Core/Models/Domain/AuthResult.cs` (+2 -0) 📝 `src/Core/Models/Request/RegisterRequest.cs` (+1 -0) 📝 `src/Core/Models/Request/TokenRequest.cs` (+8 -1) 📝 `src/Core/Models/Response/ErrorResponse.cs` (+6 -0) ➕ `src/Core/Models/Response/IdentityCaptchaResponse.cs` (+13 -0) ➕ `src/Core/Models/Response/IdentityResponse.cs` (+50 -0) 📝 `src/Core/Models/Response/IdentityTwoFactorResponse.cs` (+3 -0) 📝 `src/Core/Services/ApiService.cs` (+7 -17) 📝 `src/Core/Services/AuthService.cs` (+22 -12) </details> ### 📄 Description # Overview Adding captcha responses to Login and Registration failures due to suspected bot requests. The basic flow is to attempt the request, fail with a captcha siteKey in the response, use that site key to show a web auth and retrieve a captcha token, and finally reattempt the request with the acquired token. I couldn't find a good example for DI to a parent ViewModel in the solution already. I chose abstract properties to pass required services to the parent `CaptchaProtectedViewModel` because I still want to have the dependencies gathered at the highest level and passed down. It didn't make sense to me to grab the dependencies multiple times, but this would be my second favorite approach. # Files Changed * **loginPage.xaml/registerPage.xaml**: On my simulator I was getting long load times for the second request attempt post-captcha that was displaying the login or register page again. I'm disabling the submit buttons until the second attempt is completed. * **LoginPageViewModel**: Inherits from CaptchaProtectedViewModel to get all the captcha handling goodies. Add loading binding to disable submit and handle captcha required by reattempting once the base class set `_captchaToken`. * **RegisterPageViewModel**: Same as **`LoginPageViewModel`**, except the captcha requirement comes in as an ApiException. This is due to the differences in failure modes server-side. Indentity failures are just failed auth requests, whereas API failures are returned as Bad Requests and thrown. * **CaptchaProtectedViewModel**: Initialize a `WebAuthenticator` when captcha is required and retrieve a token response on success. If we don't get a token, signal failure. The `EncodeB64` method matches the... odd... way we're encoding iframe data in the web vault (https://github.com/bitwarden/jslib/blob/master/common/src/misc/iframe_component.ts#L30-L34 && https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings) * **AppResources**: Localize Captcha strings * **ApiService**: Parse out IdentityCaptchaResponse as well as Token and Two Factor. This is primarily handled in the new return class. * **AuthService**: Add Captcha to login. A two factor captcha bypass token is stored for subsequent calls # Screenshots ## Login PreCaptcha <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824419-14d7f45e-2bf7-4017-a903-037508ca8a99.png"> ## Login/register captcha <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824451-d3d778fc-ceca-433a-8c6a-7e40ae1613a9.png"> ## Login/register captcha with images (pixel 3a) <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824966-5fac18a3-3aae-4778-b5f9-5ce1281269d7.png"> ## Login back out of captcha <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824514-bb811e5a-3e04-4a2c-a7ab-d70ad1d7bf2e.png"> ## Register precaptcha <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824624-e2aea994-5b3a-4b8b-a99b-59e39ac49588.png"> ## Register back out of captcha <img width="326" alt="image" src="https://user-images.githubusercontent.com/18214891/126824670-48c21f6d-5e14-49de-a450-e835ce6519d2.png"> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-01 14:44:07 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/android#51132