mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
chore(captcha): [PM-15162] Remove handling of captcha enforcement and bypass token
* Removed captcha references. * Removed connectors from webpack * Fixed extra parameter. * Resolve merge conflicts. * Fixed extra argument. * Fixed failing tests. * Fixed failing test. * Accessibility cookie cleanup * Cleaned up accessibility component. * Deleted old registration endpoint * Remove unused register request object. * Fixed merge error that changed font family. * Fixed formatting from merge. * Linting
This commit is contained in:
@@ -47,10 +47,9 @@ export abstract class AccountApiService {
|
||||
* @param request - The request object containing the user's email verification token,
|
||||
* the email, hashed MP, newly created user key, and new asymmetric user key pair along
|
||||
* with the KDF information used during the process.
|
||||
* @returns A promise that resolves to a string captcha bypass token when the
|
||||
* registration process is successfully completed.
|
||||
* @returns A promise that resolves when the registration process is successfully completed.
|
||||
*/
|
||||
abstract registerFinish(request: RegisterFinishRequest): Promise<string>;
|
||||
abstract registerFinish(request: RegisterFinishRequest): Promise<void>;
|
||||
|
||||
/**
|
||||
* Sets the [dbo].[User].[VerifyDevices] flag to true or false.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { I18nService } from "../platform/abstractions/i18n.service";
|
||||
|
||||
import { IFrameComponent } from "./iframe-component";
|
||||
|
||||
// TODO: PM-15162 - captcha is deprecated as part of UI refresh work
|
||||
export class CaptchaIFrame extends IFrameComponent {
|
||||
constructor(
|
||||
win: Window,
|
||||
webVaultUrl: string,
|
||||
private i18nService: I18nService,
|
||||
successCallback: (message: string) => any,
|
||||
errorCallback: (message: string) => any,
|
||||
infoCallback: (message: string) => any,
|
||||
) {
|
||||
super(
|
||||
win,
|
||||
webVaultUrl,
|
||||
"captcha-connector.html",
|
||||
"hcaptcha_iframe",
|
||||
successCallback,
|
||||
errorCallback,
|
||||
(message: string) => {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
if (typeof parsedMessage !== "string") {
|
||||
this.iframe.height = parsedMessage.height.toString();
|
||||
this.iframe.width = parsedMessage.width.toString();
|
||||
} else {
|
||||
infoCallback(parsedMessage);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
init(siteKey: string): void {
|
||||
super.initComponent(
|
||||
this.createParams({ siteKey: siteKey, locale: this.i18nService.translationLocale }, 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
export abstract class IFrameComponent {
|
||||
iframe: HTMLIFrameElement;
|
||||
private connectorLink: HTMLAnchorElement;
|
||||
private parseFunction = this.parseMessage.bind(this);
|
||||
|
||||
constructor(
|
||||
private win: Window,
|
||||
protected webVaultUrl: string,
|
||||
private path: string,
|
||||
private iframeId: string,
|
||||
public successCallback?: (message: string) => any,
|
||||
public errorCallback?: (message: string) => any,
|
||||
public infoCallback?: (message: string) => any,
|
||||
) {
|
||||
this.connectorLink = win.document.createElement("a");
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.sendMessage("stop");
|
||||
}
|
||||
|
||||
start() {
|
||||
this.sendMessage("start");
|
||||
}
|
||||
|
||||
sendMessage(message: any) {
|
||||
if (!this.iframe || !this.iframe.src || !this.iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iframe.contentWindow.postMessage(message, this.iframe.src);
|
||||
}
|
||||
|
||||
base64Encode(str: string): string {
|
||||
return btoa(
|
||||
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => {
|
||||
return String.fromCharCode(("0x" + p1) as any);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
this.win.removeEventListener("message", this.parseFunction, false);
|
||||
}
|
||||
|
||||
protected createParams(data: any, version: number) {
|
||||
return new URLSearchParams({
|
||||
data: this.base64Encode(JSON.stringify(data)),
|
||||
parent: encodeURIComponent(this.win.document.location.href),
|
||||
v: version.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
protected initComponent(params: URLSearchParams): void {
|
||||
this.connectorLink.href = `${this.webVaultUrl}/${this.path}?${params}`;
|
||||
this.iframe = this.win.document.getElementById(this.iframeId) as HTMLIFrameElement;
|
||||
this.iframe.src = this.connectorLink.href;
|
||||
|
||||
this.win.addEventListener("message", this.parseFunction, false);
|
||||
}
|
||||
|
||||
private parseMessage(event: MessageEvent) {
|
||||
if (!this.validMessage(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parts: string[] = event.data.split("|");
|
||||
if (parts[0] === "success" && this.successCallback) {
|
||||
this.successCallback(parts[1]);
|
||||
} else if (parts[0] === "error" && this.errorCallback) {
|
||||
this.errorCallback(parts[1]);
|
||||
} else if (parts[0] === "info" && this.infoCallback) {
|
||||
this.infoCallback(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private validMessage(event: MessageEvent) {
|
||||
if (
|
||||
event.origin == null ||
|
||||
event.origin === "" ||
|
||||
event.origin !== (this.connectorLink as any).origin ||
|
||||
event.data == null ||
|
||||
typeof event.data !== "string"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
event.data.indexOf("success|") === 0 ||
|
||||
event.data.indexOf("error|") === 0 ||
|
||||
event.data.indexOf("info|") === 0
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Utils } from "../../../platform/misc/utils";
|
||||
import { UserId } from "../../../types/guid";
|
||||
import { TwoFactorProviderType } from "../../enums/two-factor-provider-type";
|
||||
|
||||
export class AuthResult {
|
||||
userId: UserId;
|
||||
captchaSiteKey = "";
|
||||
// TODO: PM-3287 - Remove this after 3 releases of backwards compatibility. - Target release 2023.12 for removal
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -21,10 +19,6 @@ export class AuthResult {
|
||||
requiresEncryptionKeyMigration: boolean;
|
||||
requiresDeviceVerification: boolean;
|
||||
|
||||
get requiresCaptcha() {
|
||||
return !Utils.isNullOrWhitespace(this.captchaSiteKey);
|
||||
}
|
||||
|
||||
get requiresTwoFactor() {
|
||||
return this.twoFactorProviders != null;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
export abstract class CaptchaProtectedRequest {
|
||||
captchaResponse: string = null;
|
||||
}
|
||||
@@ -1,16 +1,14 @@
|
||||
import { ClientType } from "../../../../enums";
|
||||
import { Utils } from "../../../../platform/misc/utils";
|
||||
import { CaptchaProtectedRequest } from "../captcha-protected.request";
|
||||
|
||||
import { DeviceRequest } from "./device.request";
|
||||
import { TokenTwoFactorRequest } from "./token-two-factor.request";
|
||||
import { TokenRequest } from "./token.request";
|
||||
|
||||
export class PasswordTokenRequest extends TokenRequest implements CaptchaProtectedRequest {
|
||||
export class PasswordTokenRequest extends TokenRequest {
|
||||
constructor(
|
||||
public email: string,
|
||||
public masterPasswordHash: string,
|
||||
public captchaResponse: string,
|
||||
protected twoFactor: TokenTwoFactorRequest,
|
||||
device?: DeviceRequest,
|
||||
public newDeviceOtp?: string,
|
||||
@@ -25,10 +23,6 @@ export class PasswordTokenRequest extends TokenRequest implements CaptchaProtect
|
||||
obj.username = this.email;
|
||||
obj.password = this.masterPasswordHash;
|
||||
|
||||
if (this.captchaResponse != null) {
|
||||
obj.captchaResponse = this.captchaResponse;
|
||||
}
|
||||
|
||||
if (this.newDeviceOtp) {
|
||||
obj.newDeviceOtp = this.newDeviceOtp;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export interface ICaptchaProtectedResponse {
|
||||
captchaBypassToken: string;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { BaseResponse } from "../../../models/response/base.response";
|
||||
|
||||
export class IdentityCaptchaResponse extends BaseResponse {
|
||||
siteKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.siteKey = this.getResponseProperty("HCaptcha_SiteKey");
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,9 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response";
|
||||
|
||||
export class IdentityDeviceVerificationResponse extends BaseResponse {
|
||||
deviceVerified: boolean;
|
||||
captchaToken: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.deviceVerified = this.getResponseProperty("DeviceVerified") ?? false;
|
||||
|
||||
this.captchaToken = this.getResponseProperty("CaptchaBypassToken");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,12 @@ export class IdentityTwoFactorResponse extends BaseResponse {
|
||||
twoFactorProviders: TwoFactorProviderType[];
|
||||
// a map of two-factor providers to necessary data for completion
|
||||
twoFactorProviders2: Record<TwoFactorProviderType, Record<string, string>>;
|
||||
captchaToken: string;
|
||||
ssoEmail2faSessionToken: string;
|
||||
email?: string;
|
||||
masterPasswordPolicy?: MasterPasswordPolicyResponse;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.captchaToken = this.getResponseProperty("CaptchaBypassToken");
|
||||
this.twoFactorProviders = this.getResponseProperty("TwoFactorProviders");
|
||||
this.twoFactorProviders2 = this.getResponseProperty("TwoFactorProviders2");
|
||||
this.masterPasswordPolicy = new MasterPasswordPolicyResponse(
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { BaseResponse } from "../../../models/response/base.response";
|
||||
|
||||
import { ICaptchaProtectedResponse } from "./captcha-protected.response";
|
||||
|
||||
export class RegisterResponse extends BaseResponse implements ICaptchaProtectedResponse {
|
||||
captchaBypassToken: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.captchaBypassToken = this.getResponseProperty("CaptchaBypassToken");
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export class AccountApiServiceImplementation implements AccountApiService {
|
||||
}
|
||||
}
|
||||
|
||||
async registerFinish(request: RegisterFinishRequest): Promise<string> {
|
||||
async registerFinish(request: RegisterFinishRequest): Promise<void> {
|
||||
const env = await firstValueFrom(this.environmentService.environment$);
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user