mirror of
https://github.com/bitwarden/browser
synced 2025-12-21 02:33:46 +00:00
Merge branch 'master' into feature/org-admin-refresh
This commit is contained in:
@@ -6,3 +6,7 @@ export abstract class AbstractStorageService {
|
||||
abstract save<T>(key: string, obj: T, options?: StorageOptions): Promise<void>;
|
||||
abstract remove(key: string, options?: StorageOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class AbstractCachedStorageService extends AbstractStorageService {
|
||||
abstract getBypassCache<T>(key: string, options?: StorageOptions): Promise<T>;
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
export enum Permissions {
|
||||
AccessEventLogs,
|
||||
AccessImportExport,
|
||||
AccessReports,
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and
|
||||
* `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
ManageAllCollections,
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and
|
||||
* `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
ManageAssignedCollections,
|
||||
ManageGroups,
|
||||
ManageOrganization,
|
||||
ManagePolicies,
|
||||
ManageProvider,
|
||||
ManageUsers,
|
||||
ManageUsersPassword,
|
||||
CreateNewCollections,
|
||||
EditAnyCollection,
|
||||
DeleteAnyCollection,
|
||||
EditAssignedCollections,
|
||||
DeleteAssignedCollections,
|
||||
ManageSso,
|
||||
ManageBilling,
|
||||
ManageScim,
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { IEncrypted } from "@bitwarden/common/interfaces/IEncrypted";
|
||||
|
||||
import { CryptoService } from "../../abstractions/crypto.service";
|
||||
@@ -21,80 +23,9 @@ export class EncString implements IEncrypted {
|
||||
mac?: string
|
||||
) {
|
||||
if (data != null) {
|
||||
// data and header
|
||||
const encType = encryptedStringOrType as EncryptionType;
|
||||
|
||||
if (iv != null) {
|
||||
this.encryptedString = encType + "." + iv + "|" + data;
|
||||
} else {
|
||||
this.encryptedString = encType + "." + data;
|
||||
}
|
||||
|
||||
// mac
|
||||
if (mac != null) {
|
||||
this.encryptedString += "|" + mac;
|
||||
}
|
||||
|
||||
this.encryptionType = encType;
|
||||
this.data = data;
|
||||
this.iv = iv;
|
||||
this.mac = mac;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.encryptedString = encryptedStringOrType as string;
|
||||
if (!this.encryptedString) {
|
||||
return;
|
||||
}
|
||||
|
||||
const headerPieces = this.encryptedString.split(".");
|
||||
let encPieces: string[] = null;
|
||||
|
||||
if (headerPieces.length === 2) {
|
||||
try {
|
||||
this.encryptionType = parseInt(headerPieces[0], null);
|
||||
encPieces = headerPieces[1].split("|");
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
this.initFromData(encryptedStringOrType as EncryptionType, data, iv, mac);
|
||||
} else {
|
||||
encPieces = this.encryptedString.split("|");
|
||||
this.encryptionType =
|
||||
encPieces.length === 3
|
||||
? EncryptionType.AesCbc128_HmacSha256_B64
|
||||
: EncryptionType.AesCbc256_B64;
|
||||
}
|
||||
|
||||
switch (this.encryptionType) {
|
||||
case EncryptionType.AesCbc128_HmacSha256_B64:
|
||||
case EncryptionType.AesCbc256_HmacSha256_B64:
|
||||
if (encPieces.length !== 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
this.mac = encPieces[2];
|
||||
break;
|
||||
case EncryptionType.AesCbc256_B64:
|
||||
if (encPieces.length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
break;
|
||||
case EncryptionType.Rsa2048_OaepSha256_B64:
|
||||
case EncryptionType.Rsa2048_OaepSha1_B64:
|
||||
if (encPieces.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data = encPieces[0];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
this.initFromEncryptedString(encryptedStringOrType as string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,4 +64,100 @@ export class EncString implements IEncrypted {
|
||||
get dataBytes(): ArrayBuffer {
|
||||
return this.data == null ? null : Utils.fromB64ToArray(this.data).buffer;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.encryptedString;
|
||||
}
|
||||
|
||||
static fromJSON(obj: Jsonify<EncString>): EncString {
|
||||
return new EncString(obj);
|
||||
}
|
||||
|
||||
private initFromData(encType: EncryptionType, data: string, iv: string, mac: string) {
|
||||
if (iv != null) {
|
||||
this.encryptedString = encType + "." + iv + "|" + data;
|
||||
} else {
|
||||
this.encryptedString = encType + "." + data;
|
||||
}
|
||||
|
||||
// mac
|
||||
if (mac != null) {
|
||||
this.encryptedString += "|" + mac;
|
||||
}
|
||||
|
||||
this.encryptionType = encType;
|
||||
this.data = data;
|
||||
this.iv = iv;
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
private initFromEncryptedString(encryptedString: string) {
|
||||
this.encryptedString = encryptedString as string;
|
||||
if (!this.encryptedString) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { encType, encPieces } = this.parseEncryptedString(this.encryptedString);
|
||||
this.encryptionType = encType;
|
||||
|
||||
switch (encType) {
|
||||
case EncryptionType.AesCbc128_HmacSha256_B64:
|
||||
case EncryptionType.AesCbc256_HmacSha256_B64:
|
||||
if (encPieces.length !== 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
this.mac = encPieces[2];
|
||||
break;
|
||||
case EncryptionType.AesCbc256_B64:
|
||||
if (encPieces.length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
break;
|
||||
case EncryptionType.Rsa2048_OaepSha256_B64:
|
||||
case EncryptionType.Rsa2048_OaepSha1_B64:
|
||||
if (encPieces.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data = encPieces[0];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private parseEncryptedString(encryptedString: string): {
|
||||
encType: EncryptionType;
|
||||
encPieces: string[];
|
||||
} {
|
||||
const headerPieces = encryptedString.split(".");
|
||||
let encType: EncryptionType;
|
||||
let encPieces: string[] = null;
|
||||
|
||||
if (headerPieces.length === 2) {
|
||||
try {
|
||||
encType = parseInt(headerPieces[0], null);
|
||||
encPieces = headerPieces[1].split("|");
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
encPieces = encryptedString.split("|");
|
||||
encType =
|
||||
encPieces.length === 3
|
||||
? EncryptionType.AesCbc128_HmacSha256_B64
|
||||
: EncryptionType.AesCbc256_B64;
|
||||
}
|
||||
|
||||
return {
|
||||
encType,
|
||||
encPieces,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { FolderData } from "../data/folderData";
|
||||
import { FolderView } from "../view/folderView";
|
||||
|
||||
@@ -37,4 +39,9 @@ export class Folder extends Domain {
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
static fromJSON(obj: Jsonify<Folder>) {
|
||||
const revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
|
||||
return Object.assign(new Folder(), obj, { name: EncString.fromJSON(obj.name), revisionDate });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { Permissions } from "../../enums/permissions";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
import { OrganizationData } from "../data/organizationData";
|
||||
@@ -114,7 +113,7 @@ export class Organization {
|
||||
}
|
||||
|
||||
get canAccessEventLogs() {
|
||||
return this.isAdmin || this.permissions.accessEventLogs;
|
||||
return (this.isAdmin || this.permissions.accessEventLogs) && this.useEvents;
|
||||
}
|
||||
|
||||
get canAccessImportExport() {
|
||||
@@ -168,11 +167,11 @@ export class Organization {
|
||||
}
|
||||
|
||||
get canManageGroups() {
|
||||
return this.isAdmin || this.permissions.manageGroups;
|
||||
return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
|
||||
}
|
||||
|
||||
get canManageSso() {
|
||||
return this.isAdmin || this.permissions.manageSso;
|
||||
return (this.isAdmin || this.permissions.manageSso) && this.useSso;
|
||||
}
|
||||
|
||||
get canManageScim() {
|
||||
@@ -180,7 +179,7 @@ export class Organization {
|
||||
}
|
||||
|
||||
get canManagePolicies() {
|
||||
return this.isAdmin || this.permissions.managePolicies;
|
||||
return (this.isAdmin || this.permissions.managePolicies) && this.usePolicies;
|
||||
}
|
||||
|
||||
get canManageUsers() {
|
||||
@@ -195,30 +194,6 @@ export class Organization {
|
||||
return this.canManagePolicies;
|
||||
}
|
||||
|
||||
hasAnyPermission(permissions: Permissions[]) {
|
||||
const specifiedPermissions =
|
||||
(permissions.includes(Permissions.AccessEventLogs) && this.canAccessEventLogs) ||
|
||||
(permissions.includes(Permissions.AccessImportExport) && this.canAccessImportExport) ||
|
||||
(permissions.includes(Permissions.AccessReports) && this.canAccessReports) ||
|
||||
(permissions.includes(Permissions.CreateNewCollections) && this.canCreateNewCollections) ||
|
||||
(permissions.includes(Permissions.EditAnyCollection) && this.canEditAnyCollection) ||
|
||||
(permissions.includes(Permissions.DeleteAnyCollection) && this.canDeleteAnyCollection) ||
|
||||
(permissions.includes(Permissions.EditAssignedCollections) &&
|
||||
this.canEditAssignedCollections) ||
|
||||
(permissions.includes(Permissions.DeleteAssignedCollections) &&
|
||||
this.canDeleteAssignedCollections) ||
|
||||
(permissions.includes(Permissions.ManageGroups) && this.canManageGroups) ||
|
||||
(permissions.includes(Permissions.ManageOrganization) && this.isOwner) ||
|
||||
(permissions.includes(Permissions.ManagePolicies) && this.canManagePolicies) ||
|
||||
(permissions.includes(Permissions.ManageUsers) && this.canManageUsers) ||
|
||||
(permissions.includes(Permissions.ManageUsersPassword) && this.canManageUsersPassword) ||
|
||||
(permissions.includes(Permissions.ManageSso) && this.canManageSso) ||
|
||||
(permissions.includes(Permissions.ManageScim) && this.canManageScim) ||
|
||||
(permissions.includes(Permissions.ManageBilling) && this.canManageBilling);
|
||||
|
||||
return specifiedPermissions && (this.enabled || this.isOwner);
|
||||
}
|
||||
|
||||
get canManageBilling() {
|
||||
return this.isOwner && (this.isProviderUser || !this.hasProvider);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { Folder } from "../domain/folder";
|
||||
import { ITreeNodeObject } from "../domain/treeNode";
|
||||
|
||||
@@ -16,4 +18,9 @@ export class FolderView implements View, ITreeNodeObject {
|
||||
this.id = f.id;
|
||||
this.revisionDate = f.revisionDate;
|
||||
}
|
||||
|
||||
static fromJSON(obj: Jsonify<FolderView>) {
|
||||
const revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
|
||||
return Object.assign(new FolderView(), obj, { revisionDate });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import { SymmetricCryptoKey } from "../../models/domain/symmetricCryptoKey";
|
||||
import { FolderView } from "../../models/view/folderView";
|
||||
|
||||
export class FolderService implements InternalFolderServiceAbstraction {
|
||||
private _folders: BehaviorSubject<Folder[]> = new BehaviorSubject([]);
|
||||
private _folderViews: BehaviorSubject<FolderView[]> = new BehaviorSubject([]);
|
||||
protected _folders: BehaviorSubject<Folder[]> = new BehaviorSubject([]);
|
||||
protected _folderViews: BehaviorSubject<FolderView[]> = new BehaviorSubject([]);
|
||||
|
||||
folders$ = this._folders.asObservable();
|
||||
folderViews$ = this._folderViews.asObservable();
|
||||
|
||||
@@ -196,7 +196,7 @@ export class SearchService implements SearchServiceAbstraction {
|
||||
if (
|
||||
c.login &&
|
||||
c.login.hasUris &&
|
||||
c.login.uris.some((loginUri) => loginUri.uri.toLowerCase().indexOf(query) > -1)
|
||||
c.login.uris.some((loginUri) => loginUri?.uri?.toLowerCase().indexOf(query) > -1)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user