diff --git a/apps/browser/package.json b/apps/browser/package.json index 50f71797a69..a337378e9df 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2022.10.2", + "version": "2022.12.0", "scripts": { "build": "webpack", "build:mv3": "cross-env MANIFEST_VERSION=3 webpack", diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 3730ac6c56f..84d6d09bc6f 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2022.10.2", + "version": "2022.12.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index bbba272c19b..5f1aadd2566 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2022.10.2", + "version": "2022.12.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 63478418d31..cb578725210 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -19,7 +19,7 @@ "**/node_modules/@bitwarden/desktop-native/index.js", "**/node_modules/@bitwarden/desktop-native/desktop_native.${platform}-${arch}*.node" ], - "electronVersion": "19.0.8", + "electronVersion": "21.3.1", "generateUpdatesFilesForAllChannels": true, "publish": { "provider": "generic", diff --git a/apps/desktop/package.json b/apps/desktop/package.json index e66967ece2e..52584f57f94 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2022.11.1", + "version": "2022.12.1", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 1f571fc4d23..5d4d7f9c7a3 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2022.11.1", + "version": "2022.12.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2022.11.1", + "version": "2022.12.1", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-native": "file:../desktop_native" diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index a9be27dc243..e893f4ce025 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2022.11.1", + "version": "2022.12.1", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/web/package.json b/apps/web/package.json index 7e39254626e..21e19565c2e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2022.11.2", + "version": "2022.12.0", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/apps/web/src/app/core/web-platform-utils.service.ts b/apps/web/src/app/core/web-platform-utils.service.ts index bb8bf7707e6..2d682a35aaa 100644 --- a/apps/web/src/app/core/web-platform-utils.service.ts +++ b/apps/web/src/app/core/web-platform-utils.service.ts @@ -140,7 +140,8 @@ export class WebPlatformUtilsService implements PlatformUtilsService { confirmText?: string, cancelText?: string, type?: string, - bodyIsHtml = false + bodyIsHtml = false, + target?: string ) { let iconClasses: string = null; if (type != null) { @@ -182,6 +183,7 @@ export class WebPlatformUtilsService implements PlatformUtilsService { cancelButtonText: cancelText, showConfirmButton: true, confirmButtonText: confirmText == null ? this.i18nService.t("ok") : confirmText, + target: target != null ? target : "body", }); if (bootstrapModal != null) { diff --git a/apps/web/src/app/organizations/manage/group-add-edit.component.ts b/apps/web/src/app/organizations/manage/group-add-edit.component.ts index 2fdad269796..2a7270492fe 100644 --- a/apps/web/src/app/organizations/manage/group-add-edit.component.ts +++ b/apps/web/src/app/organizations/manage/group-add-edit.component.ts @@ -267,7 +267,9 @@ export class GroupAddEditComponent implements OnInit, OnDestroy { this.group.name, this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + "app-group-add-edit .modal-content" ); if (!confirmed) { return false; diff --git a/apps/web/src/app/organizations/manage/member-dialog/member-dialog.component.ts b/apps/web/src/app/organizations/manage/member-dialog/member-dialog.component.ts index 88530b6999a..24eaaa53173 100644 --- a/apps/web/src/app/organizations/manage/member-dialog/member-dialog.component.ts +++ b/apps/web/src/app/organizations/manage/member-dialog/member-dialog.component.ts @@ -237,7 +237,9 @@ export class MemberDialogComponent implements OnInit { this.i18nService.t("removeUserIdAccess", this.params.name), this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + "app-user-add-edit .modal-content" ); if (!confirmed) { return false; @@ -270,7 +272,9 @@ export class MemberDialogComponent implements OnInit { this.i18nService.t("revokeUserId", this.params.name), this.i18nService.t("revokeAccess"), this.i18nService.t("cancel"), - "warning" + "warning", + false, + "app-user-add-edit .modal-content" ); if (!confirmed) { return false; diff --git a/apps/web/src/app/organizations/vault/add-edit.component.ts b/apps/web/src/app/organizations/vault/add-edit.component.ts index dbbbf42dd02..6a03696c2ef 100644 --- a/apps/web/src/app/organizations/vault/add-edit.component.ts +++ b/apps/web/src/app/organizations/vault/add-edit.component.ts @@ -29,6 +29,7 @@ import { AddEditComponent as BaseAddEditComponent } from "../../vault/add-edit.c }) export class AddEditComponent extends BaseAddEditComponent { originalCipher: Cipher = null; + protected override componentName = "app-org-vault-add-edit"; constructor( cipherService: CipherService, diff --git a/apps/web/src/app/send/add-edit.component.ts b/apps/web/src/app/send/add-edit.component.ts index 9091a60dd8d..d8f8aa491fc 100644 --- a/apps/web/src/app/send/add-edit.component.ts +++ b/apps/web/src/app/send/add-edit.component.ts @@ -16,6 +16,8 @@ import { StateService } from "@bitwarden/common/abstractions/state.service"; templateUrl: "add-edit.component.html", }) export class AddEditComponent extends BaseAddEditComponent { + override componentName = "app-send-add-edit"; + constructor( i18nService: I18nService, platformUtilsService: PlatformUtilsService, diff --git a/apps/web/src/app/settings/emergency-add-edit.component.ts b/apps/web/src/app/settings/emergency-add-edit.component.ts index c709f4a9291..3e97067d6f9 100644 --- a/apps/web/src/app/settings/emergency-add-edit.component.ts +++ b/apps/web/src/app/settings/emergency-add-edit.component.ts @@ -26,6 +26,7 @@ import { AddEditComponent as BaseAddEditComponent } from "../vault/add-edit.comp export class EmergencyAddEditComponent extends BaseAddEditComponent { originalCipher: Cipher = null; viewOnly = true; + protected override componentName = "app-org-vault-add-edit"; constructor( cipherService: CipherService, diff --git a/apps/web/src/app/vault/add-edit.component.ts b/apps/web/src/app/vault/add-edit.component.ts index 1847be254eb..a8372871f9d 100644 --- a/apps/web/src/app/vault/add-edit.component.ts +++ b/apps/web/src/app/vault/add-edit.component.ts @@ -37,6 +37,7 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On viewOnly = false; protected totpInterval: number; + protected override componentName = "app-vault-add-edit"; constructor( cipherService: CipherService, diff --git a/apps/web/src/app/vault/attachments.component.ts b/apps/web/src/app/vault/attachments.component.ts index a2f361dd016..63e1f8bf39f 100644 --- a/apps/web/src/app/vault/attachments.component.ts +++ b/apps/web/src/app/vault/attachments.component.ts @@ -17,6 +17,7 @@ import { AttachmentView } from "@bitwarden/common/models/view/attachment.view"; }) export class AttachmentsComponent extends BaseAttachmentsComponent { viewOnly = false; + protected override componentName = "app-vault-attachments"; constructor( cipherService: CipherService, diff --git a/apps/web/src/app/vault/folder-add-edit.component.ts b/apps/web/src/app/vault/folder-add-edit.component.ts index a014389577d..9c1910b32ca 100644 --- a/apps/web/src/app/vault/folder-add-edit.component.ts +++ b/apps/web/src/app/vault/folder-add-edit.component.ts @@ -12,6 +12,7 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti templateUrl: "folder-add-edit.component.html", }) export class FolderAddEditComponent extends BaseFolderAddEditComponent { + protected override componentName = "app-folder-add-edit"; constructor( folderService: FolderService, folderApiService: FolderApiServiceAbstraction, diff --git a/libs/angular/src/components/add-edit.component.ts b/libs/angular/src/components/add-edit.component.ts index 2d59ac475f1..c7b73bbcce0 100644 --- a/libs/angular/src/components/add-edit.component.ts +++ b/libs/angular/src/components/add-edit.component.ts @@ -77,6 +77,7 @@ export class AddEditComponent implements OnInit, OnDestroy { canUseReprompt = true; organization: Organization; + protected componentName = ""; protected destroy$ = new Subject(); protected writeableCollections: CollectionView[]; private personalOwnershipPolicyAppliesToActiveUser: boolean; @@ -397,7 +398,9 @@ export class AddEditComponent implements OnInit, OnDestroy { this.i18nService.t("deleteItem"), this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + this.componentName != "" ? this.componentName + " .modal-content" : null ); if (!confirmed) { return false; diff --git a/libs/angular/src/components/attachments.component.ts b/libs/angular/src/components/attachments.component.ts index a484661be31..8a8db676185 100644 --- a/libs/angular/src/components/attachments.component.ts +++ b/libs/angular/src/components/attachments.component.ts @@ -29,6 +29,7 @@ export class AttachmentsComponent implements OnInit { deletePromises: { [id: string]: Promise } = {}; reuploadPromises: { [id: string]: Promise } = {}; emergencyAccessId?: string = null; + protected componentName = ""; constructor( protected cipherService: CipherService, @@ -104,7 +105,9 @@ export class AttachmentsComponent implements OnInit { this.i18nService.t("deleteAttachment"), this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + this.componentName != "" ? this.componentName + " .modal-content" : null ); if (!confirmed) { return; diff --git a/libs/angular/src/components/folder-add-edit.component.ts b/libs/angular/src/components/folder-add-edit.component.ts index c389d72dcd8..02b8922b509 100644 --- a/libs/angular/src/components/folder-add-edit.component.ts +++ b/libs/angular/src/components/folder-add-edit.component.ts @@ -18,6 +18,7 @@ export class FolderAddEditComponent implements OnInit { title: string; formPromise: Promise; deletePromise: Promise; + protected componentName = ""; constructor( protected folderService: FolderService, @@ -65,7 +66,9 @@ export class FolderAddEditComponent implements OnInit { this.i18nService.t("deleteFolder"), this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + this.componentName != "" ? this.componentName + " .modal-content" : null ); if (!confirmed) { return false; diff --git a/libs/angular/src/components/send/add-edit.component.ts b/libs/angular/src/components/send/add-edit.component.ts index dfa03e1942d..51c8f120488 100644 --- a/libs/angular/src/components/send/add-edit.component.ts +++ b/libs/angular/src/components/send/add-edit.component.ts @@ -45,6 +45,7 @@ export class AddEditComponent implements OnInit, OnDestroy { alertShown = false; showOptions = false; + protected componentName = ""; private sendLinkBaseUrl: string; private destroy$ = new Subject(); @@ -242,7 +243,9 @@ export class AddEditComponent implements OnInit, OnDestroy { this.i18nService.t("deleteSend"), this.i18nService.t("yes"), this.i18nService.t("no"), - "warning" + "warning", + false, + this.componentName != "" ? this.componentName + " .modal-content" : null ); if (!confirmed) { return false; diff --git a/libs/common/spec/services/export.service.spec.ts b/libs/common/spec/services/export.service.spec.ts index 19177bc171e..92dbd16883e 100644 --- a/libs/common/spec/services/export.service.spec.ts +++ b/libs/common/spec/services/export.service.spec.ts @@ -1,6 +1,5 @@ // eslint-disable-next-line no-restricted-imports import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; -import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; @@ -12,9 +11,11 @@ import { KdfType } from "@bitwarden/common/enums/kdfType"; import { Utils } from "@bitwarden/common/misc/utils"; import { Cipher } from "@bitwarden/common/models/domain/cipher"; import { EncString } from "@bitwarden/common/models/domain/enc-string"; +import { Folder } from "@bitwarden/common/models/domain/folder"; import { Login } from "@bitwarden/common/models/domain/login"; import { CipherWithIdExport as CipherExport } from "@bitwarden/common/models/export/cipher-with-ids.export"; import { CipherView } from "@bitwarden/common/models/view/cipher.view"; +import { FolderView } from "@bitwarden/common/models/view/folder.view"; import { LoginView } from "@bitwarden/common/models/view/login.view"; import { ExportService } from "@bitwarden/common/services/export.service"; @@ -32,6 +33,10 @@ const UserCipherDomains = [ generateCipherDomain(true), ]; +const UserFolderViews = [generateFolderView(), generateFolderView()]; + +const UserFolders = [generateFolder(), generateFolder()]; + function generateCipherView(deleted: boolean) { return BuildTestObject( { @@ -72,6 +77,26 @@ function generateCipherDomain(deleted: boolean) { ); } +function generateFolderView() { + return BuildTestObject( + { + id: GetUniqueString("id"), + name: GetUniqueString("name"), + revisionDate: new Date(), + }, + FolderView + ); +} + +function generateFolder() { + const actual = Folder.fromJSON({ + revisionDate: new Date("2022-08-04T01:06:40.441Z").toISOString(), + name: "name", + id: "id", + }); + return actual; +} + function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string) { const actual = JSON.stringify(JSON.parse(jsonResult).items); const items: CipherExport[] = []; @@ -84,6 +109,34 @@ function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string expect(actual).toEqual(JSON.stringify(items)); } +function expectEqualFolderViews(folderviews: FolderView[] | Folder[], jsonResult: string) { + const actual = JSON.stringify(JSON.parse(jsonResult).folders); + const folders: FolderResponse[] = []; + folderviews.forEach((c) => { + const folder = new FolderResponse(); + folder.id = c.id; + folder.name = c.name.toString(); + folders.push(folder); + }); + + expect(actual.length).toBeGreaterThan(0); + expect(actual).toEqual(JSON.stringify(folders)); +} + +function expectEqualFolders(folders: Folder[], jsonResult: string) { + const actual = JSON.stringify(JSON.parse(jsonResult).folders); + const items: Folder[] = []; + folders.forEach((c) => { + const item = new Folder(); + item.id = c.id; + item.name = c.name; + items.push(item); + }); + + expect(actual.length).toBeGreaterThan(0); + expect(actual).toEqual(JSON.stringify(items)); +} + describe("ExportService", () => { let exportService: ExportService; let apiService: SubstituteOf; @@ -99,8 +152,8 @@ describe("ExportService", () => { folderService = Substitute.for(); cryptoService = Substitute.for(); - folderService.folderViews$.returns(new BehaviorSubject([])); - folderService.folders$.returns(new BehaviorSubject([])); + folderService.getAllDecryptedFromState().resolves(UserFolderViews); + folderService.getAllFromState().resolves(UserFolders); exportService = new ExportService( folderService, @@ -208,4 +261,25 @@ describe("ExportService", () => { }); }); }); + + it("exported unencrypted object contains folders", async () => { + cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); + await folderService.getAllDecryptedFromState(); + const actual = await exportService.getExport("json"); + + expectEqualFolderViews(UserFolderViews, actual); + }); + + it("exported encrypted json contains folders", async () => { + cipherService.getAll().resolves(UserCipherDomains.slice(0, 1)); + await folderService.getAllFromState(); + const actual = await exportService.getExport("encrypted_json"); + + expectEqualFolders(UserFolders, actual); + }); }); + +export class FolderResponse { + id: string = null; + name: string = null; +} diff --git a/libs/common/src/abstractions/folder/folder.service.abstraction.ts b/libs/common/src/abstractions/folder/folder.service.abstraction.ts index 44db4a985b4..90b6fc23323 100644 --- a/libs/common/src/abstractions/folder/folder.service.abstraction.ts +++ b/libs/common/src/abstractions/folder/folder.service.abstraction.ts @@ -12,6 +12,7 @@ export abstract class FolderService { clearCache: () => Promise; encrypt: (model: FolderView, key?: SymmetricCryptoKey) => Promise; get: (id: string) => Promise; + getAllFromState: () => Promise; /** * @deprecated Only use in CLI! */ diff --git a/libs/common/src/abstractions/platformUtils.service.ts b/libs/common/src/abstractions/platformUtils.service.ts index 8f2f5461273..296b8a2404c 100644 --- a/libs/common/src/abstractions/platformUtils.service.ts +++ b/libs/common/src/abstractions/platformUtils.service.ts @@ -34,7 +34,8 @@ export abstract class PlatformUtilsService { confirmText?: string, cancelText?: string, type?: string, - bodyIsHtml?: boolean + bodyIsHtml?: boolean, + target?: string ) => Promise; isDev: () => boolean; isSelfHost: () => boolean; diff --git a/libs/common/src/services/export.service.ts b/libs/common/src/services/export.service.ts index 4c2f51026af..690701b83ea 100644 --- a/libs/common/src/services/export.service.ts +++ b/libs/common/src/services/export.service.ts @@ -1,5 +1,4 @@ import * as papa from "papaparse"; -import { firstValueFrom } from "rxjs"; import { ApiService } from "../abstractions/api.service"; import { CipherService } from "../abstractions/cipher.service"; @@ -116,7 +115,7 @@ export class ExportService implements ExportServiceAbstraction { const promises = []; promises.push( - firstValueFrom(this.folderService.folderViews$).then((folders) => { + this.folderService.getAllDecryptedFromState().then((folders) => { decFolders = folders; }) ); @@ -192,7 +191,7 @@ export class ExportService implements ExportServiceAbstraction { const promises = []; promises.push( - firstValueFrom(this.folderService.folders$).then((f) => { + this.folderService.getAllFromState().then((f) => { folders = f; }) ); diff --git a/libs/common/src/services/folder/folder.service.ts b/libs/common/src/services/folder/folder.service.ts index 096d89cea9f..85ef564fd5a 100644 --- a/libs/common/src/services/folder/folder.service.ts +++ b/libs/common/src/services/folder/folder.service.ts @@ -64,6 +64,18 @@ export class FolderService implements InternalFolderServiceAbstraction { return folders.find((folder) => folder.id === id); } + async getAllFromState(): Promise { + const folders = await this.stateService.getEncryptedFolders(); + const response: Folder[] = []; + for (const id in folders) { + // eslint-disable-next-line + if (folders.hasOwnProperty(id)) { + response.push(new Folder(folders[id])); + } + } + return response; + } + /** * @deprecated For the CLI only * @param id id of the folder diff --git a/libs/components/src/async-actions/bit-action.directive.ts b/libs/components/src/async-actions/bit-action.directive.ts index 0ea479f190b..640063971b5 100644 --- a/libs/components/src/async-actions/bit-action.directive.ts +++ b/libs/components/src/async-actions/bit-action.directive.ts @@ -18,6 +18,8 @@ export class BitActionDirective implements OnDestroy { private destroy$ = new Subject(); private _loading$ = new BehaviorSubject(false); + disabled = false; + @Input("bitAction") protected handler: FunctionReturningAwaitable; readonly loading$ = this._loading$.asObservable(); @@ -39,7 +41,7 @@ export class BitActionDirective implements OnDestroy { @HostListener("click") protected async onClick() { - if (!this.handler) { + if (!this.handler || this.loading || this.disabled || this.buttonComponent.disabled) { return; } diff --git a/libs/components/src/async-actions/form-button.directive.ts b/libs/components/src/async-actions/form-button.directive.ts index e44244ca3e6..c41b24da4e2 100644 --- a/libs/components/src/async-actions/form-button.directive.ts +++ b/libs/components/src/async-actions/form-button.directive.ts @@ -13,8 +13,10 @@ import { BitSubmitDirective } from "./bit-submit.directive"; * - Activates the button loading effect while the form is processing an async submit action. * - Disables the button while a `bitAction` directive on another button is being processed. * - * When attached to a standalone button with `bitAction` directive: - * - Disables the form while the `bitAction` directive is processing an async submit action. + * When attached to a button with `bitAction` directive inside of a form: + * - Disables the button while the `bitSubmit` directive is processing an async submit action. + * - Disables the button while a `bitAction` directive on another button is being processed. + * - Disables form submission while the `bitAction` directive is processing an async action. */ @Directive({ selector: "button[bitFormButton]", @@ -47,6 +49,10 @@ export class BitFormButtonDirective implements OnDestroy { actionDirective.loading$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => { submitDirective.disabled = disabled; }); + + submitDirective.disabled$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => { + actionDirective.disabled = disabled; + }); } } diff --git a/libs/components/src/async-actions/in-forms.stories.mdx b/libs/components/src/async-actions/in-forms.stories.mdx index 75bedda8ebc..6a07fcda6ee 100644 --- a/libs/components/src/async-actions/in-forms.stories.mdx +++ b/libs/components/src/async-actions/in-forms.stories.mdx @@ -16,14 +16,16 @@ Adding async actions to submit buttons requires the following 3 steps ### 1. Add a handler to your `Component` A handler is a function that returns a promise or an observable. Functions that return `void` are also supported which is -useful for aborting an action. +useful because `return;` can be used to abort an action. -**NOTE:** +**NOTE:** Defining the handlers as arrow-functions assigned to variables is mandatory if the handler needs access to the parent +component using the variable `this`. -- Defining the handlers as arrow-functions assigned to variables is mandatory if the handler needs access to the parent - component using the variable `this`. -- `formGroup.invalid` will always return `true` after the first `await` operation, event if the form is not actually - invalid. This is due to the form getting disabled by the `bitSubmit` directive while waiting for the async action to complete. +**NOTE:** `formGroup.invalid` will always return `true` after the first `await` operation, event if the form is not actually +invalid. This is due to the form getting disabled by the `bitSubmit` directive while waiting for the async action to complete. + +**NOTE:** Handlers do not need to check if any previous requests have finished because the directives have built in protection against +users attempting to trigger new actions before the previous ones have finished. ```ts @Component({...}) @@ -52,6 +54,8 @@ Add the `bitSubmit` directive and supply the handler defined in step 1. **NOTE:** The `directive` is defined using the input syntax: `[input]="handler"`. This is different from how submit handlers are usually defined with the output syntax `(ngSubmit)="handler()"`. +**NOTE:** `[bitSubmit]` is used instead of `(ngSubmit)`. Using both is not supported. + ```html
...
``` @@ -60,6 +64,8 @@ This is different from how submit handlers are usually defined with the output s Add both `bitButton` and `bitFormButton` directives to the button. +**NOTE:** A summary of what each directive does can be found inside the source code. + ```html ``` @@ -76,21 +82,22 @@ useful for aborting an action. **NOTE:** Defining the handlers as arrow-functions assigned to variables is mandatory if the handler needs access to the parent component using the variable `this`. +**NOTE:** Handlers do not need to check if any previous requests have finished because the directives have built in protection against +users attempting to trigger new actions before the previous ones have finished. + ```ts @Component({...}) class Component { formGroup = this.formBuilder.group({...}); submit = async () => { - // not relevant for this example + // contents of this handler are not relevant for this example + // as this handler will not be trigger by standalone buttons using + // `bitAction` } // action can also return Observable instead of Promise handler = async () => { - if (/* perform guard check */) { - return; - } - await this.apiService.post(/* ... */); }; } @@ -98,7 +105,7 @@ class Component { ### 2. Add directive to the `form` element -The `bitSubmit` directive is required beacuse of its coordinating role. +The `bitSubmit` directive is required beacuse of its coordinating role inside of a form. ```html
...
@@ -108,6 +115,8 @@ The `bitSubmit` directive is required beacuse of its coordinating role. Add `bitButton`, `bitFormButton`, `bitAction` directives to the button. Make sure to supply a handler. +**NOTE:** A summary of what each directive does can be found inside the source code. + ```html diff --git a/libs/components/src/async-actions/standalone.stories.mdx b/libs/components/src/async-actions/standalone.stories.mdx index 7ed5c46ffde..9ff5753388d 100644 --- a/libs/components/src/async-actions/standalone.stories.mdx +++ b/libs/components/src/async-actions/standalone.stories.mdx @@ -14,21 +14,20 @@ Adding async actions to standalone buttons requires the following 2 steps ### 1. Add a handler to your `Component` A handler is a function that returns a promise or an observable. Functions that return `void` are also supported which is -useful for aborting an action. +useful because `return;` can be used to abort an action. **NOTE:** Defining the handlers as arrow-functions assigned to variables is mandatory if the handler needs access to the parent component using the variable `this`. +**NOTE:** Handlers do not need to check if any previous requests have finished because the directives have built in protection against +users attempting to trigger new actions before the previous ones have finished. + #### Example using promises ```ts @Component({...}) class PromiseExampleComponent { handler = async () => { - if (/* perform guard check */) { - return; - } - await this.apiService.post(/* ... */); }; } @@ -40,10 +39,6 @@ class PromiseExampleComponent { @Component({...}) class Component { handler = () => { - if (/* perform guard check */) { - return; - } - return this.apiService.post$(/* ... */); }; } @@ -56,6 +51,8 @@ Add the `bitAction` directive and supply the handler defined in step 1. **NOTE:** The `directive` is defined using the input syntax: `[input]="handler"`. This is different from how click handlers are usually defined with the output syntax `(click)="handler()"`. +**NOTE:** `[bitAction]` is used instead of `(click)`. Using both is not supported. + ```html diff --git a/package-lock.json b/package-lock.json index becef74c530..73699277f2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -114,14 +114,14 @@ "cross-env": "^7.0.3", "css-loader": "^6.5.1", "del": "^6.0.0", - "electron": "19.0.8", + "electron": "21.3.1", "electron-builder": "22.11.10", "electron-log": "^4.4.8", - "electron-notarize": "^1.2.1", - "electron-rebuild": "^3.2.7", + "electron-notarize": "^1.2.2", + "electron-rebuild": "^3.2.9", "electron-reload": "^2.0.0-alpha.1", - "electron-store": "^8.0.2", - "electron-updater": "^5.0.5", + "electron-store": "^8.1.0", + "electron-updater": "^5.3.0", "eslint": "^8.14.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^2.7.1", @@ -177,7 +177,7 @@ }, "apps/browser": { "name": "@bitwarden/browser", - "version": "2022.10.2" + "version": "2022.12.0" }, "apps/cli": { "name": "@bitwarden/cli", @@ -216,7 +216,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2022.11.1", + "version": "2022.12.1", "hasInstallScript": true, "license": "GPL-3.0" }, @@ -230,7 +230,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2022.11.2" + "version": "2022.12.0" }, "libs/angular": { "name": "@bitwarden/angular", @@ -13330,6 +13330,16 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/zxcvbn": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.1.tgz", @@ -17819,9 +17829,9 @@ } }, "node_modules/conf": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.1.2.tgz", - "integrity": "sha512-o9Fv1Mv+6A0JpoayQ8JleNp3hhkbOJP/Re/Q+QqxMPHPkABVsRjQGWZn9A5GcqLiTNC6d89p2PB5ZhHVDSMwyg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", "dev": true, "dependencies": { "ajv": "^8.6.3", @@ -20158,21 +20168,21 @@ } }, "node_modules/electron": { - "version": "19.0.8", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.0.8.tgz", - "integrity": "sha512-OWK3P/NbDFfBUv+wbYv1/OV4jehY5DQPT7n1maQJfN9hsnrWTMktXS/bmS05eSUAjNAzHmKPKfiKH2c1Yr7nGw==", + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-21.3.1.tgz", + "integrity": "sha512-Ik/I9oFHA1h32JRtRm6GMgYdUctFpF/tPnHyATg4r3LXBTUT6habGh3GxSdmmTa5JgtA7uJUEm8EjjZItk7T3g==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^1.14.1", "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" }, "engines": { - "node": ">= 8.6" + "node": ">= 10.17.0" } }, "node_modules/electron-builder": { @@ -20209,9 +20219,10 @@ "dev": true }, "node_modules/electron-notarize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", - "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.2.tgz", + "integrity": "sha512-ZStVWYcWI7g87/PgjPJSIIhwQXOaw4/XeXU+pWqMMktSLHaGMLHdyPPN7Cmao7+Cr7fYufA16npdtMndYciHNw==", + "deprecated": "Please use @electron/notarize moving forward. There is no API change, just a package name change", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -20300,9 +20311,10 @@ } }, "node_modules/electron-rebuild": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.8.tgz", - "integrity": "sha512-+U/G5ZH9RNfvPQsEHevC3yDlgSB+wliNXnG6haqUeZBEq061pEgSTWK9ZBEfqMEq+PKxvniMNxfou/h6079s3A==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz", + "integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==", + "deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change", "dev": true, "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", @@ -20535,13 +20547,13 @@ } }, "node_modules/electron-store": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.0.2.tgz", - "integrity": "sha512-9GwUMv51w8ydbkaG7X0HrPlElXLApg63zYy1/VZ/a08ndl0gfm4iCoD3f0E1JvP3V16a+7KxqriCI0c122stiA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", + "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", "dev": true, "dependencies": { - "conf": "^10.1.2", - "type-fest": "^2.12.2" + "conf": "^10.2.0", + "type-fest": "^2.17.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -20554,13 +20566,13 @@ "dev": true }, "node_modules/electron-updater": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.5.tgz", - "integrity": "sha512-YcKEI9zpU+c0sNXTpjw3UpzP8Pfuuwo70T42oLYm0hHc0dy41ih51oENlhxgooa2+uzzpXhoCOyrpG+w6CB0Pw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.3.0.tgz", + "integrity": "sha512-iKEr7yQBcvnQUPnSDYGSWC9t0eF2YbZWeYYYZzYxdl+HiRejXFENjYMnYjoOm2zxyD6Cr2JTHZhp9pqxiXuCOw==", "dev": true, "dependencies": { "@types/semver": "^7.3.6", - "builder-util-runtime": "9.0.2", + "builder-util-runtime": "9.1.1", "fs-extra": "^10.0.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", @@ -20577,9 +20589,9 @@ "dev": true }, "node_modules/electron-updater/node_modules/builder-util-runtime": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.2.tgz", - "integrity": "sha512-xF55W/8mgfT6+sMbX0TeiJkTusA5GMOzckM4rajN4KirFcUIuLTH8oEaTYmM86YwVCZaTwa/7GyFhauXaEICwA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -22712,46 +22724,39 @@ } }, "node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" - } - }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/extsprintf": { "version": "1.4.1", @@ -53265,6 +53270,16 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@types/zxcvbn": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.1.tgz", @@ -56752,9 +56767,9 @@ } }, "conf": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.1.2.tgz", - "integrity": "sha512-o9Fv1Mv+6A0JpoayQ8JleNp3hhkbOJP/Re/Q+QqxMPHPkABVsRjQGWZn9A5GcqLiTNC6d89p2PB5ZhHVDSMwyg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", "dev": true, "requires": { "ajv": "^8.6.3", @@ -58593,14 +58608,14 @@ } }, "electron": { - "version": "19.0.8", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.0.8.tgz", - "integrity": "sha512-OWK3P/NbDFfBUv+wbYv1/OV4jehY5DQPT7n1maQJfN9hsnrWTMktXS/bmS05eSUAjNAzHmKPKfiKH2c1Yr7nGw==", + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-21.3.1.tgz", + "integrity": "sha512-Ik/I9oFHA1h32JRtRm6GMgYdUctFpF/tPnHyATg4r3LXBTUT6habGh3GxSdmmTa5JgtA7uJUEm8EjjZItk7T3g==", "dev": true, "requires": { "@electron/get": "^1.14.1", "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "extract-zip": "^2.0.1" } }, "electron-builder": { @@ -58630,9 +58645,9 @@ "dev": true }, "electron-notarize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", - "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.2.tgz", + "integrity": "sha512-ZStVWYcWI7g87/PgjPJSIIhwQXOaw4/XeXU+pWqMMktSLHaGMLHdyPPN7Cmao7+Cr7fYufA16npdtMndYciHNw==", "dev": true, "requires": { "debug": "^4.1.1", @@ -58709,9 +58724,9 @@ } }, "electron-rebuild": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.8.tgz", - "integrity": "sha512-+U/G5ZH9RNfvPQsEHevC3yDlgSB+wliNXnG6haqUeZBEq061pEgSTWK9ZBEfqMEq+PKxvniMNxfou/h6079s3A==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz", + "integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==", "dev": true, "requires": { "@malept/cross-spawn-promise": "^2.0.0", @@ -58873,13 +58888,13 @@ } }, "electron-store": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.0.2.tgz", - "integrity": "sha512-9GwUMv51w8ydbkaG7X0HrPlElXLApg63zYy1/VZ/a08ndl0gfm4iCoD3f0E1JvP3V16a+7KxqriCI0c122stiA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", + "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", "dev": true, "requires": { - "conf": "^10.1.2", - "type-fest": "^2.12.2" + "conf": "^10.2.0", + "type-fest": "^2.17.0" } }, "electron-to-chromium": { @@ -58889,13 +58904,13 @@ "dev": true }, "electron-updater": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.5.tgz", - "integrity": "sha512-YcKEI9zpU+c0sNXTpjw3UpzP8Pfuuwo70T42oLYm0hHc0dy41ih51oENlhxgooa2+uzzpXhoCOyrpG+w6CB0Pw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.3.0.tgz", + "integrity": "sha512-iKEr7yQBcvnQUPnSDYGSWC9t0eF2YbZWeYYYZzYxdl+HiRejXFENjYMnYjoOm2zxyD6Cr2JTHZhp9pqxiXuCOw==", "dev": true, "requires": { "@types/semver": "^7.3.6", - "builder-util-runtime": "9.0.2", + "builder-util-runtime": "9.1.1", "fs-extra": "^10.0.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", @@ -58912,9 +58927,9 @@ "dev": true }, "builder-util-runtime": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.2.tgz", - "integrity": "sha512-xF55W/8mgfT6+sMbX0TeiJkTusA5GMOzckM4rajN4KirFcUIuLTH8oEaTYmM86YwVCZaTwa/7GyFhauXaEICwA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", "dev": true, "requires": { "debug": "^4.3.4", @@ -60513,40 +60528,25 @@ } }, "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { - "ms": "2.0.0" + "pump": "^3.0.0" } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true } } }, diff --git a/package.json b/package.json index dfaa1925479..9a8d1b8953e 100644 --- a/package.json +++ b/package.json @@ -79,14 +79,14 @@ "cross-env": "^7.0.3", "css-loader": "^6.5.1", "del": "^6.0.0", - "electron": "19.0.8", + "electron": "21.3.1", "electron-builder": "22.11.10", "electron-log": "^4.4.8", - "electron-notarize": "^1.2.1", - "electron-rebuild": "^3.2.7", + "electron-notarize": "^1.2.2", + "electron-rebuild": "^3.2.9", "electron-reload": "^2.0.0-alpha.1", - "electron-store": "^8.0.2", - "electron-updater": "^5.0.5", + "electron-store": "^8.1.0", + "electron-updater": "^5.3.0", "eslint": "^8.14.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^2.7.1",