diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 97b43a218d..af81eb7398 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -19,8 +19,8 @@ jobs:
name: Setup
runs-on: ubuntu-20.04
outputs:
- release_version: ${{ steps.version.outputs.package }}
- tag_version: ${{ steps.version.outputs.tag }}
+ release_version: ${{ steps.version.outputs.version }}
+ tag_version: ${{ steps.version.outputs.version }}
branch_name: ${{ steps.branch.outputs.branch_name }}
steps:
- name: Branch check
@@ -38,20 +38,11 @@ jobs:
- name: Check Release Version
id: version
- run: |
- version=$( jq -r ".version" package.json)
- previous_release_tag_version=$(
- curl -sL https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | jq -r ".tag_name"
- )
-
- if [ "v$version" == "$previous_release_tag_version" ] && \
- [ "${{ github.event.inputs.release_type }}" == "Initial Release" ]; then
- echo "[!] Already released v$version. Please bump version to continue"
- exit 1
- fi
-
- echo "::set-output name=package::$version"
- echo "::set-output name=tag::v$version"
+ uses: bitwarden/gh-actions/release-version-check@ea9fab01d76940267b4147cc1c4542431246b9f6
+ with:
+ release-type: ${{ github.event.inputs.release_type }}
+ project-type: ts
+ file: package.json
- name: Get branch name
id: branch
diff --git a/README.md b/README.md
index 1b8dfe7726..609cf5dd57 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
-> **Repository Reorganization in Progress**
+> **Archived**
>
-> We are currently migrating some projects over to a mono repository. For existing PR's we will be providing documentation on how to move/migrate them. To minimize the overhead we are actively reviewing open PRs. If possible please ensure any pending comments are resolved as soon as possible.
->
-> New pull requests created during this transition period may not get addressed —if needed, please create a new PR after the reorganization is complete.
+> This repository is archived, please go to https://github.com/bitwarden/clients for future development.
diff --git a/bitwarden_license/src/app/organizations/organizations-routing.module.ts b/bitwarden_license/src/app/organizations/organizations-routing.module.ts
index c300da148d..691feda30c 100644
--- a/bitwarden_license/src/app/organizations/organizations-routing.module.ts
+++ b/bitwarden_license/src/app/organizations/organizations-routing.module.ts
@@ -22,14 +22,16 @@ const routes: Routes = [
component: ManageComponent,
canActivate: [PermissionsGuard],
data: {
- permissions: NavigationPermissionsService.getPermissions("manage").concat(
- Permissions.ManageSso
- ),
+ permissions: NavigationPermissionsService.getPermissions("manage"),
},
children: [
{
path: "sso",
component: SsoComponent,
+ canActivate: [PermissionsGuard],
+ data: {
+ permissions: [Permissions.ManageSso],
+ },
},
],
},
diff --git a/crowdin.yml b/crowdin.yml
index e99016fc2d..821f35d2c7 100644
--- a/crowdin.yml
+++ b/crowdin.yml
@@ -15,3 +15,4 @@ files:
en-GB: en_GB
en-IN: en_IN
sr-CY: sr_CY
+ sr-CS: sr_CS
diff --git a/package-lock.json b/package-lock.json
index 1106cb2e18..8e68936355 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@bitwarden/web-vault",
- "version": "2.28.1",
+ "version": "2022.05.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@bitwarden/web-vault",
- "version": "2.28.1",
+ "version": "2022.05.0",
"hasInstallScript": true,
"license": "GPL-3.0",
"dependencies": {
diff --git a/package.json b/package.json
index 29da731891..9fe29fcd9c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@bitwarden/web-vault",
- "version": "2.28.1",
+ "version": "2022.05.0",
"license": "GPL-3.0",
"repository": "https://github.com/bitwarden/web",
"scripts": {
diff --git a/src/app/components/organization-switcher.component.html b/src/app/components/organization-switcher.component.html
index 7975fd9e1b..221985a6cf 100644
--- a/src/app/components/organization-switcher.component.html
+++ b/src/app/components/organization-switcher.component.html
@@ -46,7 +46,7 @@
-
+
-
+
{{ "newOrganization" | i18n }}
diff --git a/src/app/components/premium-badge.component.ts b/src/app/components/premium-badge.component.ts
index 86a88d5106..0628621f17 100644
--- a/src/app/components/premium-badge.component.ts
+++ b/src/app/components/premium-badge.component.ts
@@ -5,7 +5,7 @@ import { MessagingService } from "jslib-common/abstractions/messaging.service";
@Component({
selector: "app-premium-badge",
template: `
-
+
{{ "premium" | i18n }}
`,
diff --git a/src/app/layouts/navbar.component.html b/src/app/layouts/navbar.component.html
index 9bbd8d2ece..edc5d34d69 100644
--- a/src/app/layouts/navbar.component.html
+++ b/src/app/layouts/navbar.component.html
@@ -65,24 +65,24 @@
-
+
{{ "accountSettings" | i18n }}
-
+
{{ "getHelp" | i18n }}
-
+
{{ "getApps" | i18n }}
-
+
{{ "lockNow" | i18n }}
-
+
{{ "logOut" | i18n }}
diff --git a/src/app/modules/organizations/users/enroll-master-password-reset.component.html b/src/app/modules/organizations/users/enroll-master-password-reset.component.html
new file mode 100644
index 0000000000..c8d15a3956
--- /dev/null
+++ b/src/app/modules/organizations/users/enroll-master-password-reset.component.html
@@ -0,0 +1,59 @@
+
diff --git a/src/app/modules/organizations/users/enroll-master-password-reset.component.ts b/src/app/modules/organizations/users/enroll-master-password-reset.component.ts
new file mode 100644
index 0000000000..b996493d85
--- /dev/null
+++ b/src/app/modules/organizations/users/enroll-master-password-reset.component.ts
@@ -0,0 +1,97 @@
+import { Component } from "@angular/core";
+
+import { ModalRef } from "jslib-angular/components/modal/modal.ref";
+import { ModalConfig } from "jslib-angular/services/modal.service";
+import { ApiService } from "jslib-common/abstractions/api.service";
+import { CryptoService } from "jslib-common/abstractions/crypto.service";
+import { I18nService } from "jslib-common/abstractions/i18n.service";
+import { LogService } from "jslib-common/abstractions/log.service";
+import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
+import { SyncService } from "jslib-common/abstractions/sync.service";
+import { UserVerificationService } from "jslib-common/abstractions/userVerification.service";
+import { Utils } from "jslib-common/misc/utils";
+import { Organization } from "jslib-common/models/domain/organization";
+import { OrganizationUserResetPasswordEnrollmentRequest } from "jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest";
+import { Verification } from "jslib-common/types/verification";
+
+@Component({
+ selector: "app-enroll-master-password-reset",
+ templateUrl: "enroll-master-password-reset.component.html",
+})
+export class EnrollMasterPasswordReset {
+ organization: Organization;
+
+ verification: Verification;
+ formPromise: Promise;
+
+ constructor(
+ private userVerificationService: UserVerificationService,
+ private apiService: ApiService,
+ private platformUtilsService: PlatformUtilsService,
+ private i18nService: I18nService,
+ private cryptoService: CryptoService,
+ private syncService: SyncService,
+ private logService: LogService,
+ private modalRef: ModalRef,
+ config: ModalConfig
+ ) {
+ this.organization = config.data.organization;
+ }
+
+ async submit() {
+ let toastStringRef = "withdrawPasswordResetSuccess";
+
+ this.formPromise = this.userVerificationService
+ .buildRequest(this.verification, OrganizationUserResetPasswordEnrollmentRequest)
+ .then(async (request) => {
+ // Set variables
+ let keyString: string = null;
+
+ // Enrolling
+ if (!this.organization.resetPasswordEnrolled) {
+ // Retrieve Public Key
+ const orgKeys = await this.apiService.getOrganizationKeys(this.organization.id);
+ if (orgKeys == null) {
+ throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
+ }
+
+ const publicKey = Utils.fromB64ToArray(orgKeys.publicKey);
+
+ // RSA Encrypt user's encKey.key with organization public key
+ const encKey = await this.cryptoService.getEncKey();
+ const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);
+ keyString = encryptedKey.encryptedString;
+ toastStringRef = "enrollPasswordResetSuccess";
+
+ // Create request and execute enrollment
+ request.resetPasswordKey = keyString;
+ await this.apiService.putOrganizationUserResetPasswordEnrollment(
+ this.organization.id,
+ this.organization.userId,
+ request
+ );
+ } else {
+ // Withdrawal
+ request.resetPasswordKey = keyString;
+ await this.apiService.putOrganizationUserResetPasswordEnrollment(
+ this.organization.id,
+ this.organization.userId,
+ request
+ );
+ }
+
+ await this.syncService.fullSync(true);
+ });
+ try {
+ await this.formPromise;
+ this.platformUtilsService.showToast("success", null, this.i18nService.t(toastStringRef));
+ this.modalRef.close();
+ } catch (e) {
+ this.logService.error(e);
+ }
+ }
+
+ get isEnrolled(): boolean {
+ return this.organization.resetPasswordEnrolled;
+ }
+}
diff --git a/src/app/modules/organizations/users/organization-user.module.ts b/src/app/modules/organizations/users/organization-user.module.ts
new file mode 100644
index 0000000000..aed0ac6629
--- /dev/null
+++ b/src/app/modules/organizations/users/organization-user.module.ts
@@ -0,0 +1,14 @@
+import { ScrollingModule } from "@angular/cdk/scrolling";
+import { NgModule } from "@angular/core";
+
+import { LooseComponentsModule } from "../../loose-components.module";
+import { SharedModule } from "../../shared.module";
+
+import { EnrollMasterPasswordReset } from "./enroll-master-password-reset.component";
+
+@NgModule({
+ imports: [SharedModule, ScrollingModule, LooseComponentsModule],
+ declarations: [EnrollMasterPasswordReset],
+ exports: [EnrollMasterPasswordReset],
+})
+export class OrganizationUserModule {}
diff --git a/src/app/modules/vault-filter/components/collection-filter.component.html b/src/app/modules/vault-filter/components/collection-filter.component.html
index 436cda99c7..24463dca19 100644
--- a/src/app/modules/vault-filter/components/collection-filter.component.html
+++ b/src/app/modules/vault-filter/components/collection-filter.component.html
@@ -31,7 +31,7 @@
{
- if (response == null) {
- throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
- }
-
- const publicKey = Utils.fromB64ToArray(response.publicKey);
-
- // RSA Encrypt user's encKey.key with organization public key
- const encKey = await this.cryptoService.getEncKey();
- const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);
- keyString = encryptedKey.encryptedString;
- toastStringRef = "enrollPasswordResetSuccess";
-
- // Create request and execute enrollment
- const request = new OrganizationUserResetPasswordEnrollmentRequest();
- request.resetPasswordKey = keyString;
- return this.apiService.putOrganizationUserResetPasswordEnrollment(
- org.id,
- org.userId,
- request
- );
- })
- .then(() => {
- return this.syncService.fullSync(true);
- });
- } else {
- // Withdrawal
- const request = new OrganizationUserResetPasswordEnrollmentRequest();
- request.resetPasswordKey = keyString;
- this.actionPromise = this.apiService
- .putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request)
- .then(() => {
- return this.syncService.fullSync(true);
- });
- }
-
- try {
- await this.actionPromise;
- this.platformUtilsService.showToast("success", null, this.i18nService.t(toastStringRef));
- await this.load();
- } catch (e) {
- this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), e.message);
- this.logService.error(e);
- }
+ this.modalService.open(EnrollMasterPasswordReset, {
+ allowMultipleModals: true,
+ data: {
+ organization: org,
+ },
+ });
}
}
diff --git a/src/app/modules/vault-filter/vault-filter.component.ts b/src/app/modules/vault-filter/vault-filter.component.ts
index 56b721721b..4442e0abc6 100644
--- a/src/app/modules/vault-filter/vault-filter.component.ts
+++ b/src/app/modules/vault-filter/vault-filter.component.ts
@@ -25,7 +25,7 @@ export class VaultFilterComponent extends BaseVaultFilterComponent {
}
searchTextChanged() {
- this.onSearchTextChanged.emit(this.searchText.normalize("NFD").replace(/[\u0300-\u036f]/g, ""));
+ this.onSearchTextChanged.emit(this.searchText);
}
async initCollections() {
diff --git a/src/app/modules/vault/modules/organization-badge/organization-name-badge.component.html b/src/app/modules/vault/modules/organization-badge/organization-name-badge.component.html
index 1a2f993689..de4711d617 100644
--- a/src/app/modules/vault/modules/organization-badge/organization-name-badge.component.html
+++ b/src/app/modules/vault/modules/organization-badge/organization-name-badge.component.html
@@ -1,5 +1,5 @@
diff --git a/src/app/oss.module.ts b/src/app/oss.module.ts
index 88311f9ded..cd4d3d9d05 100644
--- a/src/app/oss.module.ts
+++ b/src/app/oss.module.ts
@@ -2,6 +2,7 @@ import { NgModule } from "@angular/core";
import { LooseComponentsModule } from "./modules/loose-components.module";
import { OrganizationManageModule } from "./modules/organizations/manage/organization-manage.module";
+import { OrganizationUserModule } from "./modules/organizations/users/organization-user.module";
import { PipesModule } from "./modules/pipes/pipes.module";
import { SharedModule } from "./modules/shared.module";
import { VaultFilterModule } from "./modules/vault-filter/vault-filter.module";
@@ -15,6 +16,7 @@ import { OrganizationBadgeModule } from "./modules/vault/modules/organization-ba
OrganizationBadgeModule,
PipesModule,
OrganizationManageModule,
+ OrganizationUserModule,
],
exports: [LooseComponentsModule, VaultFilterModule, OrganizationBadgeModule, PipesModule],
bootstrap: [],
diff --git a/src/app/reports/breach-report.component.html b/src/app/reports/breach-report.component.html
index b6195bfd59..6d7c0401f0 100644
--- a/src/app/reports/breach-report.component.html
+++ b/src/app/reports/breach-report.component.html
@@ -17,13 +17,7 @@
{{ "breachCheckUsernameEmail" | i18n }}
-
+
{{ "checkBreaches" | i18n }}
diff --git a/src/app/reports/exposed-passwords-report.component.html b/src/app/reports/exposed-passwords-report.component.html
index 496cd108bf..f0a882f793 100644
--- a/src/app/reports/exposed-passwords-report.component.html
+++ b/src/app/reports/exposed-passwords-report.component.html
@@ -3,7 +3,7 @@
{{ "exposedPasswordsReportDesc" | i18n }}
{{ report.description | i18n }}
-
+
{{ "backToReports" | i18n }}
diff --git a/src/app/send/send.component.html b/src/app/send/send.component.html
index db38850c79..eed3cdfa56 100644
--- a/src/app/send/send.component.html
+++ b/src/app/send/send.component.html
@@ -23,7 +23,7 @@
-
+
{{ "allSends" | i18n }}
@@ -38,7 +38,7 @@
-
+
{{ "copySendLink" | i18n }}
-
+
{{ "removePassword" | i18n }}
-
+
{{ "delete" | i18n }}
diff --git a/src/app/settings/account.component.html b/src/app/settings/account.component.html
index 1881498373..c88fc1ece0 100644
--- a/src/app/settings/account.component.html
+++ b/src/app/settings/account.component.html
@@ -14,13 +14,13 @@
{{ "dangerZoneDesc" | i18n }}
-
+
{{ "deauthorizeSessions" | i18n }}
-
+
{{ "purgeVault" | i18n }}
-
+
{{ "deleteAccount" | i18n }}
diff --git a/src/app/settings/billing-sync-key.component.ts b/src/app/settings/billing-sync-key.component.ts
index 929d8aaf69..9b80037c2d 100644
--- a/src/app/settings/billing-sync-key.component.ts
+++ b/src/app/settings/billing-sync-key.component.ts
@@ -3,6 +3,7 @@ import { Component } from "@angular/core";
import { ApiService } from "jslib-common/abstractions/api.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { OrganizationConnectionType } from "jslib-common/enums/organizationConnectionType";
+import { Utils } from "jslib-common/misc/utils";
import { BillingSyncConfigApi } from "jslib-common/models/api/billingSyncConfigApi";
import { BillingSyncConfigRequest } from "jslib-common/models/request/billingSyncConfigRequest";
import { OrganizationConnectionRequest } from "jslib-common/models/request/organizationConnectionRequest";
diff --git a/src/app/settings/change-kdf.component.html b/src/app/settings/change-kdf.component.html
index e389958643..f5eae39be4 100644
--- a/src/app/settings/change-kdf.component.html
+++ b/src/app/settings/change-kdf.component.html
@@ -71,7 +71,7 @@
-
+
{{ "changeKdf" | i18n }}
diff --git a/src/app/settings/change-password.component.html b/src/app/settings/change-password.component.html
index f8a4dd4c58..990d950604 100644
--- a/src/app/settings/change-password.component.html
+++ b/src/app/settings/change-password.component.html
@@ -87,7 +87,7 @@
-
+
{{ "changeMasterPassword" | i18n }}
diff --git a/src/app/settings/payment-method.component.html b/src/app/settings/payment-method.component.html
index aca7b11568..bae22bf4cf 100644
--- a/src/app/settings/payment-method.component.html
+++ b/src/app/settings/payment-method.component.html
@@ -3,7 +3,7 @@
{{ "paymentMethod" | i18n }}
{{ creditOrBalance | currency: "$" }}
{{ "creditAppliedDesc" | i18n }}
-
+
{{ "addCredit" | i18n }}
-
+
{{ (paymentSource ? "changePaymentMethod" : "addPaymentMethod") | i18n }}
{{ "paymentChargedAnnually" | i18n }}
-
+
{{ "submit" | i18n }}
diff --git a/src/app/settings/security-keys.component.html b/src/app/settings/security-keys.component.html
index 9c9b8df5e0..58201014be 100644
--- a/src/app/settings/security-keys.component.html
+++ b/src/app/settings/security-keys.component.html
@@ -8,10 +8,10 @@
{{ "userApiKeyDesc" | i18n }}
-
+
{{ "viewApiKey" | i18n }}
-
+
{{ "rotateApiKey" | i18n }}
diff --git a/src/app/settings/two-factor-setup.component.html b/src/app/settings/two-factor-setup.component.html
index 6d95419c4c..c4960ce56a 100644
--- a/src/app/settings/two-factor-setup.component.html
+++ b/src/app/settings/two-factor-setup.component.html
@@ -5,7 +5,7 @@
{{ "twoStepLoginOrganizationDesc" | i18n }}
{{ "twoStepLoginRecoveryWarning" | i18n }}
-
+
{{ "viewRecoveryCode" | i18n }}
@@ -45,7 +45,7 @@
{{ "subscriptionPendingCanceled" | i18n }}
{{ "status" | i18n }}
{{ (subscription && subscription.status) || "-" }}
- {{
+ {{
"pendingCancellation" | i18n
}}
@@ -96,11 +96,11 @@
-
+
{{ "updateLicense" | i18n }}
-
+
{{ "addStorage" | i18n }}
o.value === "firefoxrelay"),
- 1
- );
+ if (platformUtilsService.isSelfHost()) {
+ // Cannot use Firefox Relay on self hosted web vaults due to CORS issues with Firefox Relay API
+ this.forwardOptions.splice(
+ this.forwardOptions.findIndex((o) => o.value === "firefoxrelay"),
+ 1
+ );
+ }
}
async history() {
diff --git a/src/app/vault/ciphers.component.html b/src/app/vault/ciphers.component.html
index 305fe9240a..096a0833ff 100644
--- a/src/app/vault/ciphers.component.html
+++ b/src/app/vault/ciphers.component.html
@@ -64,12 +64,12 @@
-
+
{{ "copyUsername" | i18n }}
@@ -77,24 +77,24 @@
{{ "copyPassword" | i18n }}
{{ "copyVerificationCode" | i18n }}
-
+
{{ "launch" | i18n }}
-
+
{{ "attachments" | i18n }}
@@ -102,26 +102,26 @@
{{ "clone" | i18n }}
{{ "moveToOrganization" | i18n }}
-
+
{{ "collections" | i18n }}
-
+
{{ "eventLogs" | i18n }}
-
+
{{ "restore" | i18n }}
-
+
{{ (c.isDeleted ? "permanentlyDelete" : "delete") | i18n }}
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index d55d854ae0..bf4952c4ca 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -4163,7 +4163,7 @@
"message": "Password reset success!"
},
"resetPasswordEnrollmentWarning": {
- "message": "Enrollment will allow organization administrators to change your master password. Are you sure you want to enroll?"
+ "message": "Enrollment will allow organization administrators to change your master password"
},
"resetPasswordPolicy": {
"message": "Master Password Reset"
@@ -4674,8 +4674,8 @@
"removeSponsorshipSuccess": {
"message": "Sponsorship Removed"
},
- "ssoKeyConnectorUnavailable": {
- "message": "Unable to reach the Key Connector, try again later."
+ "ssoKeyConnectorError": {
+ "message": "Key Connector error: make sure Key Connector is available and working correctly."
},
"keyConnectorUrl": {
"message": "Key Connector URL"