mirror of
https://github.com/bitwarden/browser
synced 2026-02-17 18:09:17 +00:00
QR login beep
This commit is contained in:
19
libs/auth/src/angular/debug/debug.component.html
Normal file
19
libs/auth/src/angular/debug/debug.component.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<form [bitSubmit]="submit" [formGroup]="formGroup">
|
||||
<div class="tw-grid tw-gap-3">
|
||||
No QR scanning implemented :(
|
||||
|
||||
<!-- Connect String input -->
|
||||
<bit-form-field>
|
||||
<bit-label>Connect String</bit-label>
|
||||
<input
|
||||
type="text"
|
||||
formControlName="connectString"
|
||||
bitInput
|
||||
placeholder="Enter connect string"
|
||||
/>
|
||||
</bit-form-field>
|
||||
|
||||
<!-- Approve button -->
|
||||
<button type="submit" bitButton block buttonType="primary">Approve</button>
|
||||
</div>
|
||||
</form>
|
||||
117
libs/auth/src/angular/debug/debug.component.ts
Normal file
117
libs/auth/src/angular/debug/debug.component.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { AuthRequestApiServiceAbstraction, AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthRequestType } from "@bitwarden/common/auth/enums/auth-request-type";
|
||||
import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request";
|
||||
import { PasswordlessAuthRequest } from "@bitwarden/common/auth/models/request/passwordless-auth.request";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { AsyncActionsModule, ButtonModule, CalloutModule, DialogModule, DialogService, FormFieldModule, IconButtonModule } from "@bitwarden/components";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
import { ServerRelayInitiator } from "@bitwarden/sdk-internal";
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
|
||||
import {
|
||||
InputPasswordComponent,
|
||||
} from "../input-password/input-password.component";
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: "auth-debug",
|
||||
templateUrl: "debug.component.html",
|
||||
imports: [
|
||||
CommonModule,
|
||||
InputPasswordComponent,
|
||||
JslibModule,
|
||||
ButtonModule,
|
||||
CalloutModule,
|
||||
CommonModule,
|
||||
FormFieldModule,
|
||||
DialogModule,
|
||||
I18nPipe,
|
||||
InputPasswordComponent,
|
||||
DialogModule,
|
||||
CommonModule,
|
||||
JslibModule,
|
||||
ButtonModule,
|
||||
IconButtonModule,
|
||||
ReactiveFormsModule,
|
||||
AsyncActionsModule,
|
||||
FormFieldModule,
|
||||
]
|
||||
})
|
||||
export class DebugComponent implements OnInit {
|
||||
|
||||
protected formGroup = new FormGroup({
|
||||
connectString: this.formBuilder.control(""),
|
||||
});
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private dialogService: DialogService,
|
||||
private keyService: KeyService,
|
||||
private accountService: AccountService,
|
||||
private authRequestApiService: AuthRequestApiServiceAbstraction,
|
||||
private authRequestService: AuthRequestServiceAbstraction,
|
||||
private apiService: ApiService,
|
||||
private appIdService: AppIdService,
|
||||
) { }
|
||||
|
||||
async ngOnInit() {
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
|
||||
const a = await this.dialogService.openSimpleDialog({
|
||||
title: "User verification",
|
||||
acceptButtonText: "Confirm",
|
||||
content: "Please confirm with biometrics.",
|
||||
type: "primary"
|
||||
});
|
||||
|
||||
|
||||
const connectString = this.formGroup.controls.connectString.value;
|
||||
if (a) {
|
||||
const email = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((account) => account.email)),
|
||||
);
|
||||
const request = await this.buildAuthRequest(email, AuthRequestType.AuthenticateAndUnlock);
|
||||
const response = await this.authRequestApiService.postAuthRequest(request);
|
||||
const approveRequest = new PasswordlessAuthRequest(
|
||||
"7.abc",
|
||||
undefined,
|
||||
await this.appIdService.getAppId(),
|
||||
true,
|
||||
);
|
||||
await this.apiService.putAuthRequest(response.id, approveRequest);
|
||||
|
||||
const uuid = connectString.split(",")[0];
|
||||
const psk = Utils.fromB64ToArray(connectString.split(",")[1]);
|
||||
const initiator = await ServerRelayInitiator.connect(
|
||||
uuid, psk
|
||||
);
|
||||
initiator.send_auth_request(
|
||||
(await this.keyService.getUserKey()).toEncoded(),
|
||||
email,
|
||||
response.id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async buildAuthRequest(
|
||||
email: string,
|
||||
authRequestType: AuthRequestType,
|
||||
): Promise<AuthRequest> {
|
||||
const code = "ABCDEFGHIJKLMNOPQRSTUVWXY";
|
||||
return new AuthRequest(email, "00000000-0000-0000-0000-000000000000", "placeholder_public", AuthRequestType.AuthenticateAndUnlock, code);
|
||||
}
|
||||
}
|
||||
0
libs/auth/src/angular/debug/debug.html
Normal file
0
libs/auth/src/angular/debug/debug.html
Normal file
@@ -25,6 +25,7 @@ export * from "./login-decryption-options/default-login-decryption-options.servi
|
||||
|
||||
// login via auth request
|
||||
export * from "./login-via-auth-request/login-via-auth-request.component";
|
||||
export * from "./debug/debug.component";
|
||||
|
||||
// password callout
|
||||
export * from "./password-callout/password-callout.component";
|
||||
|
||||
@@ -12,6 +12,17 @@
|
||||
|
||||
<form [bitSubmit]="submit" [formGroup]="formGroup">
|
||||
<div [ngClass]="{ 'tw-hidden': loginUiState !== LoginUiState.EMAIL_ENTRY }">
|
||||
<!-- Connect String section -->
|
||||
<div class="tw-m-3 tw-flex tw-justify-center">
|
||||
<qrcode
|
||||
[qrdata]="connectString"
|
||||
[errorCorrectionLevel]="'M'"
|
||||
(click)="copyConnectString()"
|
||||
class="tw-cursor-pointer"
|
||||
title="Click to copy connect string"
|
||||
></qrcode>
|
||||
</div>
|
||||
|
||||
<!-- Email Address input -->
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "emailAddress" | i18n }}</bit-label>
|
||||
|
||||
@@ -2,10 +2,12 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router, RouterModule } from "@angular/router";
|
||||
import { QRCodeComponent } from 'angularx-qrcode';
|
||||
import { firstValueFrom, Subject, take, takeUntil } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import {
|
||||
AuthRequestLoginCredentials,
|
||||
LoginEmailServiceAbstraction,
|
||||
LoginStrategyServiceAbstraction,
|
||||
LoginSuccessHandlerService,
|
||||
@@ -25,15 +27,18 @@ import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.ser
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import { UserKey } from "@bitwarden/common/types/key";
|
||||
import {
|
||||
AnonLayoutWrapperDataService,
|
||||
AsyncActionsModule,
|
||||
@@ -44,11 +49,13 @@ import {
|
||||
LinkModule,
|
||||
ToastService,
|
||||
} from "@bitwarden/components";
|
||||
import { PureCrypto, ServerRelayInitiator, ServerRelayResponder, ServerRelayResponderPreHandshake } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { VaultIcon, WaveIcon } from "../icons";
|
||||
|
||||
import { LoginComponentService, PasswordPolicies } from "./login-component.service";
|
||||
|
||||
|
||||
const BroadcasterSubscriptionId = "LoginComponent";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
@@ -71,6 +78,7 @@ export enum LoginUiState {
|
||||
JslibModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule,
|
||||
QRCodeComponent
|
||||
],
|
||||
})
|
||||
export class LoginComponent implements OnInit, OnDestroy {
|
||||
@@ -104,6 +112,8 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
// Desktop properties
|
||||
deferFocus: boolean | null = null;
|
||||
|
||||
connectString: string = "Connecting...";
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
|
||||
@@ -127,6 +137,7 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
private loginSuccessHandlerService: LoginSuccessHandlerService,
|
||||
private masterPasswordService: MasterPasswordServiceAbstraction,
|
||||
private configService: ConfigService,
|
||||
private keyGenerationService: KeyGenerationService,
|
||||
) {
|
||||
this.clientType = this.platformUtilsService.getClientType();
|
||||
}
|
||||
@@ -137,6 +148,28 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
|
||||
await this.defaultOnInit();
|
||||
|
||||
this.logService.info("Connecting");
|
||||
|
||||
(async () => {
|
||||
const responder = await ServerRelayResponderPreHandshake.listen();
|
||||
const psk = (await this.keyGenerationService.createKey(256)).toEncoded();
|
||||
this.connectString = `${await responder.get_id()},${Utils.fromBufferToB64(psk)}`;
|
||||
const a = await responder.wait_for_handshake(psk);
|
||||
const auth_request = await a.wait_for_auth_request();
|
||||
const creds = new AuthRequestLoginCredentials(
|
||||
auth_request.email(),
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXY",
|
||||
auth_request.auth_request_id(),
|
||||
new SymmetricCryptoKey(auth_request.userkey()) as UserKey,
|
||||
null, // no masterKey
|
||||
null, // no masterKeyHash
|
||||
);
|
||||
const resp = await this.loginStrategyService.logIn(creds);
|
||||
console.log("resp", resp)
|
||||
await this.loginSuccessHandlerService.run(resp.userId);
|
||||
await this.router.navigate(["vault"]);
|
||||
})().then(() => { }).catch(() => { });
|
||||
|
||||
if (this.clientType === ClientType.Desktop) {
|
||||
await this.desktopOnInit();
|
||||
}
|
||||
@@ -540,6 +573,19 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
await this.loginComponentService.redirectToSsoLogin(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the connect string to clipboard when QR code is clicked.
|
||||
*/
|
||||
async copyConnectString() {
|
||||
if (this.connectString) {
|
||||
await this.platformUtilsService.copyToClipboard(this.connectString);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: "Connect string copied to clipboard",
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Call to check if the device is known.
|
||||
* Known means that the user has logged in with this device before.
|
||||
|
||||
162
package-lock.json
generated
162
package-lock.json
generated
@@ -35,6 +35,7 @@
|
||||
"@nx/eslint": "21.1.2",
|
||||
"@nx/jest": "21.1.2",
|
||||
"@nx/js": "21.1.2",
|
||||
"angularx-qrcode": "19.0.0",
|
||||
"big-integer": "1.6.52",
|
||||
"bootstrap": "4.6.0",
|
||||
"braintree-web-drop-in": "1.44.0",
|
||||
@@ -14456,6 +14457,19 @@
|
||||
"typescript-eslint": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angularx-qrcode": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-19.0.0.tgz",
|
||||
"integrity": "sha512-uH1gO/X1hgSojZwgO3EmaXP+MvWCgZm5WGh3y1ZL2+VMstEGEMtJGZTyR645fB7ABF2ZIBUMB9h/SKvGJQX/zQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"qrcode": "1.5.4",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||
@@ -18447,6 +18461,12 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dir-compare": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
|
||||
@@ -31936,6 +31956,15 @@
|
||||
"node": ">=10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/polished": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz",
|
||||
@@ -32649,6 +32678,23 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"qrcode": "bin/qrcode"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode-parser": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/qrcode-parser/-/qrcode-parser-2.1.3.tgz",
|
||||
@@ -32658,6 +32704,119 @@
|
||||
"jsqr": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/qrcode/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qrious": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/qrious/-/qrious-4.0.2.tgz",
|
||||
@@ -33282,7 +33441,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/requireindex": {
|
||||
@@ -34233,7 +34391,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
@@ -39450,7 +39607,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
"@nx/eslint": "21.1.2",
|
||||
"@nx/jest": "21.1.2",
|
||||
"@nx/js": "21.1.2",
|
||||
"angularx-qrcode": "19.0.0",
|
||||
"big-integer": "1.6.52",
|
||||
"bootstrap": "4.6.0",
|
||||
"braintree-web-drop-in": "1.44.0",
|
||||
|
||||
Reference in New Issue
Block a user