diff --git a/apps/cli/src/admin-console/.eslintrc.json b/apps/cli/src/admin-console/.eslintrc.json
new file mode 100644
index 0000000000..3846718729
--- /dev/null
+++ b/apps/cli/src/admin-console/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../../../libs/admin-console/.eslintrc.json"
+}
diff --git a/apps/web/src/app/admin-console/.eslintrc.json b/apps/web/src/app/admin-console/.eslintrc.json
new file mode 100644
index 0000000000..d55df3899e
--- /dev/null
+++ b/apps/web/src/app/admin-console/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../../../../libs/admin-console/.eslintrc.json"
+}
diff --git a/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts b/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts
index cf9a7b31dc..653651bf69 100644
--- a/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts
+++ b/apps/web/src/app/admin-console/organizations/guards/is-paid-org.guard.spec.ts
@@ -24,7 +24,7 @@ export class PaidOrganizationOnlyComponent {}
@Component({
template: "
This is the organization upgrade screen!
",
})
-export class OrganizationUpgradeScreen {}
+export class OrganizationUpgradeScreenComponent {}
const orgFactory = (props: Partial = {}) =>
Object.assign(
@@ -62,7 +62,7 @@ describe("Is Paid Org Guard", () => {
},
{
path: "organizations/:organizationId/billing/subscription",
- component: OrganizationUpgradeScreen,
+ component: OrganizationUpgradeScreenComponent,
},
]),
],
diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/nested-checkbox.component.ts b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/nested-checkbox.component.ts
index d823240fe6..69819d6981 100644
--- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/nested-checkbox.component.ts
+++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/nested-checkbox.component.ts
@@ -1,5 +1,5 @@
import { KeyValue } from "@angular/common";
-import { Component, EventEmitter, Input, Output, OnInit, OnDestroy } from "@angular/core";
+import { Component, Input, OnInit, OnDestroy } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { Subject, takeUntil } from "rxjs";
@@ -14,8 +14,6 @@ export class NestedCheckboxComponent implements OnInit, OnDestroy {
@Input() parentId: string;
@Input() checkboxes: FormGroup>>;
- @Output() onSavedUser = new EventEmitter();
- @Output() onDeletedUser = new EventEmitter();
get parentIndeterminate() {
return (
diff --git a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts
index 291b026942..cbda3b2bdf 100644
--- a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts
+++ b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts
@@ -31,7 +31,7 @@ export class ResetPasswordComponent implements OnInit, OnDestroy {
@Input() email: string;
@Input() id: string;
@Input() organizationId: string;
- @Output() onPasswordReset = new EventEmitter();
+ @Output() passwordReset = new EventEmitter();
@ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent;
enforcedPolicyOptions: MasterPasswordPolicyOptions;
@@ -156,7 +156,7 @@ export class ResetPasswordComponent implements OnInit, OnDestroy {
null,
this.i18nService.t("resetPasswordSuccess"),
);
- this.onPasswordReset.emit();
+ this.passwordReset.emit();
} catch (e) {
this.logService.error(e);
}
diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.ts b/apps/web/src/app/admin-console/organizations/members/members.component.ts
index 1376dd5ec0..93827539f8 100644
--- a/apps/web/src/app/admin-console/organizations/members/members.component.ts
+++ b/apps/web/src/app/admin-console/organizations/members/members.component.ts
@@ -635,7 +635,7 @@ export class MembersComponent extends NewBasePeopleComponent {
+ comp.passwordReset.subscribe(() => {
modal.close();
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
diff --git a/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts b/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts
index ff9caf557a..14dd708389 100644
--- a/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts
+++ b/apps/web/src/app/admin-console/organizations/policies/master-password.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ControlsOf } from "@bitwarden/angular/types/controls-of";
@@ -21,7 +21,7 @@ export class MasterPasswordPolicy extends BasePolicy {
selector: "policy-master-password",
templateUrl: "master-password.component.html",
})
-export class MasterPasswordPolicyComponent extends BasePolicyComponent {
+export class MasterPasswordPolicyComponent extends BasePolicyComponent implements OnInit {
MinPasswordLength = Utils.minimumPasswordLength;
data: FormGroup> = this.formBuilder.group({
diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts
index dc3b667511..d84a7dec99 100644
--- a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts
+++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts
@@ -1,5 +1,12 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
-import { ChangeDetectorRef, Component, Inject, ViewChild, ViewContainerRef } from "@angular/core";
+import {
+ AfterViewInit,
+ ChangeDetectorRef,
+ Component,
+ Inject,
+ ViewChild,
+ ViewContainerRef,
+} from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
@@ -28,7 +35,7 @@ export enum PolicyEditDialogResult {
selector: "app-policy-edit",
templateUrl: "policy-edit.component.html",
})
-export class PolicyEditComponent {
+export class PolicyEditComponent implements AfterViewInit {
@ViewChild("policyForm", { read: ViewContainerRef, static: true })
policyFormRef: ViewContainerRef;
diff --git a/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts b/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts
index fbf338ac1f..6307ee13fa 100644
--- a/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts
+++ b/apps/web/src/app/admin-console/organizations/policies/reset-password.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
@@ -22,7 +22,7 @@ export class ResetPasswordPolicy extends BasePolicy {
selector: "policy-reset-password",
templateUrl: "reset-password.component.html",
})
-export class ResetPasswordPolicyComponent extends BasePolicyComponent {
+export class ResetPasswordPolicyComponent extends BasePolicyComponent implements OnInit {
data = this.formBuilder.group({
autoEnrollEnabled: false,
});
diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.ts b/apps/web/src/app/admin-console/organizations/settings/account.component.ts
index 82f9a24993..c53a4991d5 100644
--- a/apps/web/src/app/admin-console/organizations/settings/account.component.ts
+++ b/apps/web/src/app/admin-console/organizations/settings/account.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ViewContainerRef } from "@angular/core";
+import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { combineLatest, from, lastValueFrom, of, Subject, switchMap, takeUntil } from "rxjs";
@@ -27,7 +27,7 @@ import { DeleteOrganizationDialogResult, openDeleteOrganizationDialog } from "./
selector: "app-org-account",
templateUrl: "account.component.html",
})
-export class AccountComponent {
+export class AccountComponent implements OnInit, OnDestroy {
@ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true })
apiKeyModalRef: ViewContainerRef;
@ViewChild("rotateApiKeyTemplate", { read: ViewContainerRef, static: true })
diff --git a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts
index 0e00c31a69..39d29741e7 100644
--- a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts
+++ b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts
@@ -1,5 +1,5 @@
import { DialogRef } from "@angular/cdk/dialog";
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { concatMap, takeUntil, map, lastValueFrom } from "rxjs";
import { first, tap } from "rxjs/operators";
@@ -24,7 +24,7 @@ import { TwoFactorVerifyComponent } from "../../../auth/settings/two-factor-veri
templateUrl: "../../../auth/settings/two-factor-setup.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent {
+export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent implements OnInit {
tabbedHeader = false;
constructor(
dialogService: DialogService,
diff --git a/apps/web/src/app/admin-console/organizations/tools/exposed-passwords-report.component.ts b/apps/web/src/app/admin-console/organizations/tools/exposed-passwords-report.component.ts
index cab6189c45..3ea2a8f43e 100644
--- a/apps/web/src/app/admin-console/organizations/tools/exposed-passwords-report.component.ts
+++ b/apps/web/src/app/admin-console/organizations/tools/exposed-passwords-report.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -19,7 +19,10 @@ import { ExposedPasswordsReportComponent as BaseExposedPasswordsReportComponent
templateUrl: "../../../tools/reports/pages/exposed-passwords-report.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class ExposedPasswordsReportComponent extends BaseExposedPasswordsReportComponent {
+export class ExposedPasswordsReportComponent
+ extends BaseExposedPasswordsReportComponent
+ implements OnInit
+{
manageableCiphers: Cipher[];
constructor(
diff --git a/apps/web/src/app/admin-console/organizations/tools/inactive-two-factor-report.component.ts b/apps/web/src/app/admin-console/organizations/tools/inactive-two-factor-report.component.ts
index abfbd45f38..6eb8889dc2 100644
--- a/apps/web/src/app/admin-console/organizations/tools/inactive-two-factor-report.component.ts
+++ b/apps/web/src/app/admin-console/organizations/tools/inactive-two-factor-report.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -18,7 +18,10 @@ import { InactiveTwoFactorReportComponent as BaseInactiveTwoFactorReportComponen
templateUrl: "../../../tools/reports/pages/inactive-two-factor-report.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class InactiveTwoFactorReportComponent extends BaseInactiveTwoFactorReportComponent {
+export class InactiveTwoFactorReportComponent
+ extends BaseInactiveTwoFactorReportComponent
+ implements OnInit
+{
constructor(
cipherService: CipherService,
modalService: ModalService,
diff --git a/apps/web/src/app/admin-console/organizations/tools/reused-passwords-report.component.ts b/apps/web/src/app/admin-console/organizations/tools/reused-passwords-report.component.ts
index 76d783b666..0fea1f0a58 100644
--- a/apps/web/src/app/admin-console/organizations/tools/reused-passwords-report.component.ts
+++ b/apps/web/src/app/admin-console/organizations/tools/reused-passwords-report.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -18,7 +18,10 @@ import { ReusedPasswordsReportComponent as BaseReusedPasswordsReportComponent }
templateUrl: "../../../tools/reports/pages/reused-passwords-report.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class ReusedPasswordsReportComponent extends BaseReusedPasswordsReportComponent {
+export class ReusedPasswordsReportComponent
+ extends BaseReusedPasswordsReportComponent
+ implements OnInit
+{
manageableCiphers: Cipher[];
constructor(
diff --git a/apps/web/src/app/admin-console/organizations/tools/unsecured-websites-report.component.ts b/apps/web/src/app/admin-console/organizations/tools/unsecured-websites-report.component.ts
index 7f6f08fb96..559d2f417a 100644
--- a/apps/web/src/app/admin-console/organizations/tools/unsecured-websites-report.component.ts
+++ b/apps/web/src/app/admin-console/organizations/tools/unsecured-websites-report.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -17,7 +17,10 @@ import { UnsecuredWebsitesReportComponent as BaseUnsecuredWebsitesReportComponen
templateUrl: "../../../tools/reports/pages/unsecured-websites-report.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class UnsecuredWebsitesReportComponent extends BaseUnsecuredWebsitesReportComponent {
+export class UnsecuredWebsitesReportComponent
+ extends BaseUnsecuredWebsitesReportComponent
+ implements OnInit
+{
constructor(
cipherService: CipherService,
modalService: ModalService,
diff --git a/apps/web/src/app/admin-console/organizations/tools/weak-passwords-report.component.ts b/apps/web/src/app/admin-console/organizations/tools/weak-passwords-report.component.ts
index 0ac2129478..06e6fdf0a7 100644
--- a/apps/web/src/app/admin-console/organizations/tools/weak-passwords-report.component.ts
+++ b/apps/web/src/app/admin-console/organizations/tools/weak-passwords-report.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -19,7 +19,10 @@ import { WeakPasswordsReportComponent as BaseWeakPasswordsReportComponent } from
templateUrl: "../../../tools/reports/pages/weak-passwords-report.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class WeakPasswordsReportComponent extends BaseWeakPasswordsReportComponent {
+export class WeakPasswordsReportComponent
+ extends BaseWeakPasswordsReportComponent
+ implements OnInit
+{
manageableCiphers: Cipher[];
constructor(
diff --git a/bitwarden_license/bit-cli/src/admin-console/.eslintrc.json b/bitwarden_license/bit-cli/src/admin-console/.eslintrc.json
new file mode 100644
index 0000000000..3846718729
--- /dev/null
+++ b/bitwarden_license/bit-cli/src/admin-console/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../../../libs/admin-console/.eslintrc.json"
+}
diff --git a/bitwarden_license/bit-web/src/app/admin-console/.eslintrc.json b/bitwarden_license/bit-web/src/app/admin-console/.eslintrc.json
new file mode 100644
index 0000000000..d55df3899e
--- /dev/null
+++ b/bitwarden_license/bit-web/src/app/admin-console/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../../../../libs/admin-console/.eslintrc.json"
+}
diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts
index 2e422b8136..88f125a65a 100644
--- a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts
+++ b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts
@@ -1,4 +1,4 @@
-import { Component } from "@angular/core";
+import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom, from, map } from "rxjs";
import { switchMap, takeUntil } from "rxjs/operators";
@@ -33,7 +33,7 @@ const DisallowedPlanTypes = [
@Component({
templateUrl: "clients.component.html",
})
-export class ClientsComponent extends BaseClientsComponent {
+export class ClientsComponent extends BaseClientsComponent implements OnInit, OnDestroy {
providerId: string;
addableOrganizations: Organization[];
loading = true;
diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/people.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/people.component.ts
index 97dd4d3e0a..564808d005 100644
--- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/people.component.ts
+++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/people.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ViewContainerRef } from "@angular/core";
+import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { lastValueFrom } from "rxjs";
import { first } from "rxjs/operators";
@@ -34,7 +34,10 @@ import { UserAddEditComponent } from "./user-add-edit.component";
templateUrl: "people.component.html",
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
-export class PeopleComponent extends BasePeopleComponent {
+export class PeopleComponent
+ extends BasePeopleComponent
+ implements OnInit
+{
@ViewChild("addEdit", { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;
@ViewChild("groupsTemplate", { read: ViewContainerRef, static: true })
groupsModalRef: ViewContainerRef;
@@ -154,11 +157,11 @@ export class PeopleComponent extends BasePeopleComponent {
+ comp.savedUser.subscribe(() => {
modal.close();
this.load();
});
- comp.onDeletedUser.subscribe(() => {
+ comp.deletedUser.subscribe(() => {
modal.close();
this.removeUser(user);
});
diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/user-add-edit.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/user-add-edit.component.ts
index b1513a79fc..664e399660 100644
--- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/user-add-edit.component.ts
+++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/user-add-edit.component.ts
@@ -18,8 +18,8 @@ export class UserAddEditComponent implements OnInit {
@Input() name: string;
@Input() providerUserId: string;
@Input() providerId: string;
- @Output() onSavedUser = new EventEmitter();
- @Output() onDeletedUser = new EventEmitter();
+ @Output() savedUser = new EventEmitter();
+ @Output() deletedUser = new EventEmitter();
loading = true;
editMode = false;
@@ -82,7 +82,7 @@ export class UserAddEditComponent implements OnInit {
null,
this.i18nService.t(this.editMode ? "editedUserId" : "invitedUsers", this.name),
);
- this.onSavedUser.emit();
+ this.savedUser.emit();
} catch (e) {
this.logService.error(e);
}
@@ -111,7 +111,7 @@ export class UserAddEditComponent implements OnInit {
null,
this.i18nService.t("removedUserId", this.name),
);
- this.onDeletedUser.emit();
+ this.deletedUser.emit();
} catch (e) {
this.logService.error(e);
}
diff --git a/libs/admin-console/.eslintrc.json b/libs/admin-console/.eslintrc.json
new file mode 100644
index 0000000000..d8aa8f64a8
--- /dev/null
+++ b/libs/admin-console/.eslintrc.json
@@ -0,0 +1,22 @@
+{
+ "overrides": [
+ {
+ "files": ["*.ts"],
+ "extends": ["plugin:@angular-eslint/recommended"],
+ "rules": {
+ "@angular-eslint/component-class-suffix": "error",
+ "@angular-eslint/contextual-lifecycle": "error",
+ "@angular-eslint/directive-class-suffix": "error",
+ "@angular-eslint/no-empty-lifecycle-method": "error",
+ "@angular-eslint/no-input-rename": "error",
+ "@angular-eslint/no-inputs-metadata-property": "error",
+ "@angular-eslint/no-output-native": "error",
+ "@angular-eslint/no-output-on-prefix": "error",
+ "@angular-eslint/no-output-rename": "error",
+ "@angular-eslint/no-outputs-metadata-property": "error",
+ "@angular-eslint/use-lifecycle-interface": "error",
+ "@angular-eslint/use-pipe-transform-interface": "error"
+ }
+ }
+ ]
+}