@bitwarden/cli 2023.9.0 → 2023.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bw.js +471 -98
- package/build/bw.js.map +1 -1
- package/package.json +1 -1
package/build/bw.js
CHANGED
|
@@ -20,7 +20,7 @@ module.exports = require("url");
|
|
|
20
20
|
/***/ 147:
|
|
21
21
|
/***/ ((module) => {
|
|
22
22
|
|
|
23
|
-
module.exports = JSON.parse('{"name":"@bitwarden/cli","description":"A secure and free password manager for all of your devices.","version":"2023.9.
|
|
23
|
+
module.exports = JSON.parse('{"name":"@bitwarden/cli","description":"A secure and free password manager for all of your devices.","version":"2023.9.1","keywords":["bitwarden","password","vault","password manager","cli"],"author":"Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)","homepage":"https://bitwarden.com","repository":{"type":"git","url":"https://github.com/bitwarden/clients"},"license":"GPL-3.0-only","scripts":{"clean":"rimraf dist","build":"webpack","build:debug":"npm run build && node --inspect ./build/bw.js","build:watch":"webpack --watch","build:prod":"cross-env NODE_ENV=production webpack","build:prod:watch":"cross-env NODE_ENV=production webpack --watch","package":"npm run package:win && npm run package:mac && npm run package:lin","package:win":"pkg . --targets win-x64 --output ./dist/windows/bw.exe","package:mac":"pkg . --targets macos-x64 --output ./dist/macos/bw","package:lin":"pkg . --targets linux-x64 --output ./dist/linux/bw","debug":"node --inspect ./build/bw.js","dist":"npm run build:prod && npm run clean && npm run package","dist:win":"npm run build:prod && npm run clean && npm run package:win","dist:mac":"npm run build:prod && npm run clean && npm run package:mac","dist:lin":"npm run build:prod && npm run clean && npm run package:lin","publish:npm":"npm run build:prod && npm publish --access public","test":"jest","test:watch":"jest --watch","test:watch:all":"jest --watchAll"},"bin":{"bw":"build/bw.js"},"pkg":{"assets":["./build/**/*","../../node_modules/argon2/**/*"]},"dependencies":{"@koa/multer":"3.0.2","@koa/router":"12.0.0","argon2":"0.31.0","big-integer":"1.6.51","browser-hrtime":"1.1.8","chalk":"4.1.2","commander":"7.2.0","form-data":"4.0.0","https-proxy-agent":"5.0.1","inquirer":"8.2.6","jsdom":"22.1.0","jszip":"3.10.1","koa":"2.14.2","koa-bodyparser":"4.4.1","koa-json":"2.0.2","lowdb":"1.0.0","lunr":"2.3.9","multer":"1.4.5-lts.1","node-fetch":"2.6.12","node-forge":"1.3.1","open":"8.4.2","papaparse":"5.4.1","proper-lockfile":"4.1.2","rxjs":"7.8.1","tldts":"6.0.14","zxcvbn":"4.4.2"}}');
|
|
24
24
|
|
|
25
25
|
/***/ })
|
|
26
26
|
|
|
@@ -6090,6 +6090,73 @@ class BroadcasterService {
|
|
|
6090
6090
|
}
|
|
6091
6091
|
}
|
|
6092
6092
|
|
|
6093
|
+
;// CONCATENATED MODULE: ../../libs/common/src/platform/models/response/server-config.response.ts
|
|
6094
|
+
|
|
6095
|
+
class ServerConfigResponse extends BaseResponse {
|
|
6096
|
+
constructor(response) {
|
|
6097
|
+
super(response);
|
|
6098
|
+
this.featureStates = {};
|
|
6099
|
+
if (response == null) {
|
|
6100
|
+
return;
|
|
6101
|
+
}
|
|
6102
|
+
this.version = this.getResponseProperty("Version");
|
|
6103
|
+
this.gitHash = this.getResponseProperty("GitHash");
|
|
6104
|
+
this.server = new ThirdPartyServerConfigResponse(this.getResponseProperty("Server"));
|
|
6105
|
+
this.environment = new EnvironmentServerConfigResponse(this.getResponseProperty("Environment"));
|
|
6106
|
+
this.featureStates = this.getResponseProperty("FeatureStates");
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
class EnvironmentServerConfigResponse extends BaseResponse {
|
|
6110
|
+
constructor(data = null) {
|
|
6111
|
+
super(data);
|
|
6112
|
+
if (data == null) {
|
|
6113
|
+
return;
|
|
6114
|
+
}
|
|
6115
|
+
this.cloudRegion = this.getResponseProperty("CloudRegion");
|
|
6116
|
+
this.vault = this.getResponseProperty("Vault");
|
|
6117
|
+
this.api = this.getResponseProperty("Api");
|
|
6118
|
+
this.identity = this.getResponseProperty("Identity");
|
|
6119
|
+
this.notifications = this.getResponseProperty("Notifications");
|
|
6120
|
+
this.sso = this.getResponseProperty("Sso");
|
|
6121
|
+
}
|
|
6122
|
+
}
|
|
6123
|
+
class ThirdPartyServerConfigResponse extends BaseResponse {
|
|
6124
|
+
constructor(data = null) {
|
|
6125
|
+
super(data);
|
|
6126
|
+
if (data == null) {
|
|
6127
|
+
return;
|
|
6128
|
+
}
|
|
6129
|
+
this.name = this.getResponseProperty("Name");
|
|
6130
|
+
this.url = this.getResponseProperty("Url");
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
|
|
6134
|
+
;// CONCATENATED MODULE: ../../libs/common/src/platform/services/config/config-api.service.ts
|
|
6135
|
+
var config_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6136
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6137
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6138
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6139
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6140
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
6141
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
6142
|
+
});
|
|
6143
|
+
};
|
|
6144
|
+
|
|
6145
|
+
|
|
6146
|
+
class ConfigApiService {
|
|
6147
|
+
constructor(apiService, authService) {
|
|
6148
|
+
this.apiService = apiService;
|
|
6149
|
+
this.authService = authService;
|
|
6150
|
+
}
|
|
6151
|
+
get() {
|
|
6152
|
+
return config_api_service_awaiter(this, void 0, void 0, function* () {
|
|
6153
|
+
const authed = (yield this.authService.getAuthStatus()) !== AuthenticationStatus.LoggedOut;
|
|
6154
|
+
const r = yield this.apiService.send("GET", "/config", null, authed, true);
|
|
6155
|
+
return new ServerConfigResponse(r);
|
|
6156
|
+
});
|
|
6157
|
+
}
|
|
6158
|
+
}
|
|
6159
|
+
|
|
6093
6160
|
;// CONCATENATED MODULE: ../../libs/common/src/platform/services/container.service.ts
|
|
6094
6161
|
class ContainerService {
|
|
6095
6162
|
constructor(cryptoService, encryptService) {
|
|
@@ -14545,6 +14612,12 @@ class CryptoService {
|
|
|
14545
14612
|
return new SymmetricCryptoKey(sendKey);
|
|
14546
14613
|
});
|
|
14547
14614
|
}
|
|
14615
|
+
makeCipherKey() {
|
|
14616
|
+
return crypto_service_awaiter(this, void 0, void 0, function* () {
|
|
14617
|
+
const randomBytes = yield this.cryptoFunctionService.aesGenerateKey(512);
|
|
14618
|
+
return new SymmetricCryptoKey(randomBytes);
|
|
14619
|
+
});
|
|
14620
|
+
}
|
|
14548
14621
|
clearKeys(userId) {
|
|
14549
14622
|
return crypto_service_awaiter(this, void 0, void 0, function* () {
|
|
14550
14623
|
yield this.clearUserKey(true, userId);
|
|
@@ -17355,6 +17428,7 @@ class CipherData {
|
|
|
17355
17428
|
this.creationDate = response.creationDate;
|
|
17356
17429
|
this.deletedDate = response.deletedDate;
|
|
17357
17430
|
this.reprompt = response.reprompt;
|
|
17431
|
+
this.key = response.key;
|
|
17358
17432
|
switch (this.type) {
|
|
17359
17433
|
case CipherType.Login:
|
|
17360
17434
|
this.login = new LoginData(response.login);
|
|
@@ -23100,6 +23174,57 @@ class SendService {
|
|
|
23100
23174
|
}
|
|
23101
23175
|
}
|
|
23102
23176
|
|
|
23177
|
+
;// CONCATENATED MODULE: external "semver"
|
|
23178
|
+
const external_semver_namespaceObject = require("semver");
|
|
23179
|
+
;// CONCATENATED MODULE: ../../libs/common/src/platform/misc/flags.ts
|
|
23180
|
+
function getFlags(envFlags) {
|
|
23181
|
+
if (typeof envFlags === "string") {
|
|
23182
|
+
return JSON.parse(envFlags);
|
|
23183
|
+
}
|
|
23184
|
+
else {
|
|
23185
|
+
return envFlags;
|
|
23186
|
+
}
|
|
23187
|
+
}
|
|
23188
|
+
/**
|
|
23189
|
+
* Gets the value of a feature flag from environment.
|
|
23190
|
+
* All flags default to "on" (true).
|
|
23191
|
+
* Only use for shared code in `libs`, otherwise use the client-specific function.
|
|
23192
|
+
* @param flag The name of the feature flag to check
|
|
23193
|
+
* @returns The value of the flag
|
|
23194
|
+
*/
|
|
23195
|
+
function flagEnabled(flag) {
|
|
23196
|
+
const flags = getFlags({"enableCipherKeyEncryption":false});
|
|
23197
|
+
return flags[flag] == null || !!flags[flag];
|
|
23198
|
+
}
|
|
23199
|
+
/**
|
|
23200
|
+
* Gets the value of a dev flag from environment.
|
|
23201
|
+
* Will always return false unless in development.
|
|
23202
|
+
* Only use for shared code in `libs`, otherwise use the client-specific function.
|
|
23203
|
+
* @param flag The name of the dev flag to check
|
|
23204
|
+
* @returns The value of the flag
|
|
23205
|
+
*/
|
|
23206
|
+
function devFlagEnabled(flag) {
|
|
23207
|
+
if (process.env.ENV !== "development") {
|
|
23208
|
+
return false;
|
|
23209
|
+
}
|
|
23210
|
+
const devFlags = getFlags(process.env.DEV_FLAGS);
|
|
23211
|
+
return devFlags[flag] == null || !!devFlags[flag];
|
|
23212
|
+
}
|
|
23213
|
+
/**
|
|
23214
|
+
* Gets the value of a dev flag from environment.
|
|
23215
|
+
* Will always return false unless in development.
|
|
23216
|
+
* @param flag The name of the dev flag to check
|
|
23217
|
+
* @returns The value of the flag
|
|
23218
|
+
* @throws Error if the flag is not enabled
|
|
23219
|
+
*/
|
|
23220
|
+
function devFlagValue(flag) {
|
|
23221
|
+
if (!devFlagEnabled(flag)) {
|
|
23222
|
+
throw new Error(`This method should not be called, it is protected by a disabled dev flag.`);
|
|
23223
|
+
}
|
|
23224
|
+
const devFlags = getFlags(process.env.DEV_FLAGS);
|
|
23225
|
+
return devFlags[flag];
|
|
23226
|
+
}
|
|
23227
|
+
|
|
23103
23228
|
;// CONCATENATED MODULE: ../../libs/common/src/vault/models/domain/attachment.ts
|
|
23104
23229
|
var attachment_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
23105
23230
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -23647,6 +23772,8 @@ var cipher_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _a
|
|
|
23647
23772
|
|
|
23648
23773
|
|
|
23649
23774
|
|
|
23775
|
+
|
|
23776
|
+
|
|
23650
23777
|
class Cipher extends Domain {
|
|
23651
23778
|
constructor(obj, localData = null) {
|
|
23652
23779
|
super();
|
|
@@ -23660,6 +23787,7 @@ class Cipher extends Domain {
|
|
|
23660
23787
|
folderId: null,
|
|
23661
23788
|
name: null,
|
|
23662
23789
|
notes: null,
|
|
23790
|
+
key: null,
|
|
23663
23791
|
}, ["id", "organizationId", "folderId"]);
|
|
23664
23792
|
this.type = obj.type;
|
|
23665
23793
|
this.favorite = obj.favorite;
|
|
@@ -23712,9 +23840,16 @@ class Cipher extends Domain {
|
|
|
23712
23840
|
this.passwordHistory = null;
|
|
23713
23841
|
}
|
|
23714
23842
|
}
|
|
23843
|
+
// We are passing the organizationId into the EncString.decrypt() method here, but because the encKey will always be
|
|
23844
|
+
// present and so the organizationId will not be used.
|
|
23845
|
+
// We will refactor the EncString.decrypt() in https://bitwarden.atlassian.net/browse/PM-3762 to remove the dependency on the organizationId.
|
|
23715
23846
|
decrypt(encKey) {
|
|
23716
23847
|
return cipher_awaiter(this, void 0, void 0, function* () {
|
|
23717
23848
|
const model = new CipherView(this);
|
|
23849
|
+
if (this.key != null) {
|
|
23850
|
+
const encryptService = utils_Utils.getContainerService().getEncryptService();
|
|
23851
|
+
encKey = new SymmetricCryptoKey(yield encryptService.decryptToBytes(this.key, encKey));
|
|
23852
|
+
}
|
|
23718
23853
|
yield this.decryptObj(model, {
|
|
23719
23854
|
name: null,
|
|
23720
23855
|
notes: null,
|
|
@@ -23735,13 +23870,12 @@ class Cipher extends Domain {
|
|
|
23735
23870
|
default:
|
|
23736
23871
|
break;
|
|
23737
23872
|
}
|
|
23738
|
-
const orgId = this.organizationId;
|
|
23739
23873
|
if (this.attachments != null && this.attachments.length > 0) {
|
|
23740
23874
|
const attachments = [];
|
|
23741
23875
|
yield this.attachments.reduce((promise, attachment) => {
|
|
23742
23876
|
return promise
|
|
23743
23877
|
.then(() => {
|
|
23744
|
-
return attachment.decrypt(
|
|
23878
|
+
return attachment.decrypt(this.organizationId, encKey);
|
|
23745
23879
|
})
|
|
23746
23880
|
.then((decAttachment) => {
|
|
23747
23881
|
attachments.push(decAttachment);
|
|
@@ -23754,7 +23888,7 @@ class Cipher extends Domain {
|
|
|
23754
23888
|
yield this.fields.reduce((promise, field) => {
|
|
23755
23889
|
return promise
|
|
23756
23890
|
.then(() => {
|
|
23757
|
-
return field.decrypt(
|
|
23891
|
+
return field.decrypt(this.organizationId, encKey);
|
|
23758
23892
|
})
|
|
23759
23893
|
.then((decField) => {
|
|
23760
23894
|
fields.push(decField);
|
|
@@ -23767,7 +23901,7 @@ class Cipher extends Domain {
|
|
|
23767
23901
|
yield this.passwordHistory.reduce((promise, ph) => {
|
|
23768
23902
|
return promise
|
|
23769
23903
|
.then(() => {
|
|
23770
|
-
return ph.decrypt(
|
|
23904
|
+
return ph.decrypt(this.organizationId, encKey);
|
|
23771
23905
|
})
|
|
23772
23906
|
.then((decPh) => {
|
|
23773
23907
|
passwordHistory.push(decPh);
|
|
@@ -23779,6 +23913,7 @@ class Cipher extends Domain {
|
|
|
23779
23913
|
});
|
|
23780
23914
|
}
|
|
23781
23915
|
toCipherData() {
|
|
23916
|
+
var _a;
|
|
23782
23917
|
const c = new CipherData();
|
|
23783
23918
|
c.id = this.id;
|
|
23784
23919
|
c.organizationId = this.organizationId;
|
|
@@ -23793,6 +23928,7 @@ class Cipher extends Domain {
|
|
|
23793
23928
|
c.creationDate = this.creationDate != null ? this.creationDate.toISOString() : null;
|
|
23794
23929
|
c.deletedDate = this.deletedDate != null ? this.deletedDate.toISOString() : null;
|
|
23795
23930
|
c.reprompt = this.reprompt;
|
|
23931
|
+
c.key = (_a = this.key) === null || _a === void 0 ? void 0 : _a.encryptedString;
|
|
23796
23932
|
this.buildDataModel(this, c, {
|
|
23797
23933
|
name: null,
|
|
23798
23934
|
notes: null,
|
|
@@ -23837,6 +23973,7 @@ class Cipher extends Domain {
|
|
|
23837
23973
|
const attachments = (_a = obj.attachments) === null || _a === void 0 ? void 0 : _a.map((a) => Attachment.fromJSON(a));
|
|
23838
23974
|
const fields = (_b = obj.fields) === null || _b === void 0 ? void 0 : _b.map((f) => Field.fromJSON(f));
|
|
23839
23975
|
const passwordHistory = (_c = obj.passwordHistory) === null || _c === void 0 ? void 0 : _c.map((ph) => Password.fromJSON(ph));
|
|
23976
|
+
const key = EncString.fromJSON(obj.key);
|
|
23840
23977
|
Object.assign(domain, obj, {
|
|
23841
23978
|
name,
|
|
23842
23979
|
notes,
|
|
@@ -23845,6 +23982,7 @@ class Cipher extends Domain {
|
|
|
23845
23982
|
attachments,
|
|
23846
23983
|
fields,
|
|
23847
23984
|
passwordHistory,
|
|
23985
|
+
key,
|
|
23848
23986
|
});
|
|
23849
23987
|
switch (obj.type) {
|
|
23850
23988
|
case CipherType.Card:
|
|
@@ -24083,6 +24221,7 @@ class AttachmentRequest {
|
|
|
24083
24221
|
|
|
24084
24222
|
class CipherRequest {
|
|
24085
24223
|
constructor(cipher) {
|
|
24224
|
+
var _a;
|
|
24086
24225
|
this.type = cipher.type;
|
|
24087
24226
|
this.folderId = cipher.folderId;
|
|
24088
24227
|
this.organizationId = cipher.organizationId;
|
|
@@ -24091,6 +24230,7 @@ class CipherRequest {
|
|
|
24091
24230
|
this.favorite = cipher.favorite;
|
|
24092
24231
|
this.lastKnownRevisionDate = cipher.revisionDate;
|
|
24093
24232
|
this.reprompt = cipher.reprompt;
|
|
24233
|
+
this.key = (_a = cipher.key) === null || _a === void 0 ? void 0 : _a.encryptedString;
|
|
24094
24234
|
switch (this.type) {
|
|
24095
24235
|
case CipherType.Login:
|
|
24096
24236
|
this.login = new LoginApi();
|
|
@@ -24311,8 +24451,13 @@ var cipher_service_awaiter = (undefined && undefined.__awaiter) || function (thi
|
|
|
24311
24451
|
|
|
24312
24452
|
|
|
24313
24453
|
|
|
24454
|
+
|
|
24455
|
+
|
|
24456
|
+
|
|
24457
|
+
|
|
24458
|
+
const CIPHER_KEY_ENC_MIN_SERVER_VER = new external_semver_namespaceObject.SemVer("2023.9.1");
|
|
24314
24459
|
class CipherService {
|
|
24315
|
-
constructor(cryptoService, settingsService, apiService, i18nService, searchService, stateService, encryptService, cipherFileUploadService) {
|
|
24460
|
+
constructor(cryptoService, settingsService, apiService, i18nService, searchService, stateService, encryptService, cipherFileUploadService, configService) {
|
|
24316
24461
|
this.cryptoService = cryptoService;
|
|
24317
24462
|
this.settingsService = settingsService;
|
|
24318
24463
|
this.apiService = apiService;
|
|
@@ -24321,6 +24466,7 @@ class CipherService {
|
|
|
24321
24466
|
this.stateService = stateService;
|
|
24322
24467
|
this.encryptService = encryptService;
|
|
24323
24468
|
this.cipherFileUploadService = cipherFileUploadService;
|
|
24469
|
+
this.configService = configService;
|
|
24324
24470
|
this.sortedCiphersCache = new SortedCiphersCache(this.sortCiphersByLastUsed);
|
|
24325
24471
|
}
|
|
24326
24472
|
getDecryptedCipherCache() {
|
|
@@ -24347,56 +24493,17 @@ class CipherService {
|
|
|
24347
24493
|
yield this.clearDecryptedCiphersState(userId);
|
|
24348
24494
|
});
|
|
24349
24495
|
}
|
|
24350
|
-
encrypt(model,
|
|
24496
|
+
encrypt(model, keyForEncryption, keyForCipherKeyDecryption, originalCipher = null) {
|
|
24497
|
+
var _a;
|
|
24351
24498
|
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
24352
|
-
// Adjust password history
|
|
24353
24499
|
if (model.id != null) {
|
|
24354
24500
|
if (originalCipher == null) {
|
|
24355
24501
|
originalCipher = yield this.get(model.id);
|
|
24356
24502
|
}
|
|
24357
24503
|
if (originalCipher != null) {
|
|
24358
|
-
|
|
24359
|
-
model.passwordHistory = existingCipher.passwordHistory || [];
|
|
24360
|
-
if (model.type === CipherType.Login && existingCipher.type === CipherType.Login) {
|
|
24361
|
-
if (existingCipher.login.password != null &&
|
|
24362
|
-
existingCipher.login.password !== "" &&
|
|
24363
|
-
existingCipher.login.password !== model.login.password) {
|
|
24364
|
-
const ph = new PasswordHistoryView();
|
|
24365
|
-
ph.password = existingCipher.login.password;
|
|
24366
|
-
ph.lastUsedDate = model.login.passwordRevisionDate = new Date();
|
|
24367
|
-
model.passwordHistory.splice(0, 0, ph);
|
|
24368
|
-
}
|
|
24369
|
-
else {
|
|
24370
|
-
model.login.passwordRevisionDate = existingCipher.login.passwordRevisionDate;
|
|
24371
|
-
}
|
|
24372
|
-
}
|
|
24373
|
-
if (existingCipher.hasFields) {
|
|
24374
|
-
const existingHiddenFields = existingCipher.fields.filter((f) => f.type === FieldType.Hidden &&
|
|
24375
|
-
f.name != null &&
|
|
24376
|
-
f.name !== "" &&
|
|
24377
|
-
f.value != null &&
|
|
24378
|
-
f.value !== "");
|
|
24379
|
-
const hiddenFields = model.fields == null
|
|
24380
|
-
? []
|
|
24381
|
-
: model.fields.filter((f) => f.type === FieldType.Hidden && f.name != null && f.name !== "");
|
|
24382
|
-
existingHiddenFields.forEach((ef) => {
|
|
24383
|
-
const matchedField = hiddenFields.find((f) => f.name === ef.name);
|
|
24384
|
-
if (matchedField == null || matchedField.value !== ef.value) {
|
|
24385
|
-
const ph = new PasswordHistoryView();
|
|
24386
|
-
ph.password = ef.name + ": " + ef.value;
|
|
24387
|
-
ph.lastUsedDate = new Date();
|
|
24388
|
-
model.passwordHistory.splice(0, 0, ph);
|
|
24389
|
-
}
|
|
24390
|
-
});
|
|
24391
|
-
}
|
|
24392
|
-
}
|
|
24393
|
-
if (model.passwordHistory != null && model.passwordHistory.length === 0) {
|
|
24394
|
-
model.passwordHistory = null;
|
|
24395
|
-
}
|
|
24396
|
-
else if (model.passwordHistory != null && model.passwordHistory.length > 5) {
|
|
24397
|
-
// only save last 5 history
|
|
24398
|
-
model.passwordHistory = model.passwordHistory.slice(0, 5);
|
|
24504
|
+
yield this.updateModelfromExistingCipher(model, originalCipher);
|
|
24399
24505
|
}
|
|
24506
|
+
this.adjustPasswordHistoryLength(model);
|
|
24400
24507
|
}
|
|
24401
24508
|
const cipher = new Cipher();
|
|
24402
24509
|
cipher.id = model.id;
|
|
@@ -24408,29 +24515,28 @@ class CipherService {
|
|
|
24408
24515
|
cipher.revisionDate = model.revisionDate;
|
|
24409
24516
|
cipher.reprompt = model.reprompt;
|
|
24410
24517
|
cipher.edit = model.edit;
|
|
24411
|
-
if (
|
|
24412
|
-
key =
|
|
24413
|
-
|
|
24414
|
-
|
|
24518
|
+
if (yield this.getCipherKeyEncryptionEnabled()) {
|
|
24519
|
+
cipher.key = (_a = originalCipher === null || originalCipher === void 0 ? void 0 : originalCipher.key) !== null && _a !== void 0 ? _a : null;
|
|
24520
|
+
const userOrOrgKey = yield this.getKeyForCipherKeyDecryption(cipher);
|
|
24521
|
+
// The keyForEncryption is only used for encrypting the cipher key, not the cipher itself, since cipher key encryption is enabled.
|
|
24522
|
+
// If the caller has provided a key for cipher key encryption, use it. Otherwise, use the user or org key.
|
|
24523
|
+
keyForEncryption || (keyForEncryption = userOrOrgKey);
|
|
24524
|
+
// If the caller has provided a key for cipher key decryption, use it. Otherwise, use the user or org key.
|
|
24525
|
+
keyForCipherKeyDecryption || (keyForCipherKeyDecryption = userOrOrgKey);
|
|
24526
|
+
return this.encryptCipherWithCipherKey(model, cipher, keyForEncryption, keyForCipherKeyDecryption);
|
|
24527
|
+
}
|
|
24528
|
+
else {
|
|
24529
|
+
if (keyForEncryption == null && cipher.organizationId != null) {
|
|
24530
|
+
keyForEncryption = yield this.cryptoService.getOrgKey(cipher.organizationId);
|
|
24531
|
+
if (keyForEncryption == null) {
|
|
24532
|
+
throw new Error("Cannot encrypt cipher for organization. No key.");
|
|
24533
|
+
}
|
|
24415
24534
|
}
|
|
24535
|
+
// We want to ensure that the cipher key is null if cipher key encryption is disabled
|
|
24536
|
+
// so that decryption uses the proper key.
|
|
24537
|
+
cipher.key = null;
|
|
24538
|
+
return this.encryptCipher(model, cipher, keyForEncryption);
|
|
24416
24539
|
}
|
|
24417
|
-
yield Promise.all([
|
|
24418
|
-
this.encryptObjProperty(model, cipher, {
|
|
24419
|
-
name: null,
|
|
24420
|
-
notes: null,
|
|
24421
|
-
}, key),
|
|
24422
|
-
this.encryptCipherData(cipher, model, key),
|
|
24423
|
-
this.encryptFields(model.fields, key).then((fields) => {
|
|
24424
|
-
cipher.fields = fields;
|
|
24425
|
-
}),
|
|
24426
|
-
this.encryptPasswordHistories(model.passwordHistory, key).then((ph) => {
|
|
24427
|
-
cipher.passwordHistory = ph;
|
|
24428
|
-
}),
|
|
24429
|
-
this.encryptAttachments(model.attachments, key).then((attachments) => {
|
|
24430
|
-
cipher.attachments = attachments;
|
|
24431
|
-
}),
|
|
24432
|
-
]);
|
|
24433
|
-
return cipher;
|
|
24434
24540
|
});
|
|
24435
24541
|
}
|
|
24436
24542
|
encryptAttachments(attachmentsModel, key) {
|
|
@@ -24774,7 +24880,7 @@ class CipherService {
|
|
|
24774
24880
|
yield Promise.all(attachmentPromises);
|
|
24775
24881
|
cipher.organizationId = organizationId;
|
|
24776
24882
|
cipher.collectionIds = collectionIds;
|
|
24777
|
-
const encCipher = yield this.
|
|
24883
|
+
const encCipher = yield this.encryptSharedCipher(cipher);
|
|
24778
24884
|
const request = new CipherShareRequest(encCipher);
|
|
24779
24885
|
const response = yield this.apiService.putShareCipher(cipher.id, request);
|
|
24780
24886
|
const data = new CipherData(response, collectionIds);
|
|
@@ -24788,7 +24894,7 @@ class CipherService {
|
|
|
24788
24894
|
for (const cipher of ciphers) {
|
|
24789
24895
|
cipher.organizationId = organizationId;
|
|
24790
24896
|
cipher.collectionIds = collectionIds;
|
|
24791
|
-
promises.push(this.
|
|
24897
|
+
promises.push(this.encryptSharedCipher(cipher).then((c) => {
|
|
24792
24898
|
encCiphers.push(c);
|
|
24793
24899
|
}));
|
|
24794
24900
|
}
|
|
@@ -24827,12 +24933,22 @@ class CipherService {
|
|
|
24827
24933
|
}
|
|
24828
24934
|
saveAttachmentRawWithServer(cipher, filename, data, admin = false) {
|
|
24829
24935
|
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
24830
|
-
|
|
24831
|
-
|
|
24832
|
-
|
|
24833
|
-
|
|
24834
|
-
|
|
24835
|
-
|
|
24936
|
+
const encKey = yield this.getKeyForCipherKeyDecryption(cipher);
|
|
24937
|
+
const cipherKeyEncryptionEnabled = yield this.getCipherKeyEncryptionEnabled();
|
|
24938
|
+
const cipherEncKey = cipherKeyEncryptionEnabled && cipher.key != null
|
|
24939
|
+
? new SymmetricCryptoKey(yield this.encryptService.decryptToBytes(cipher.key, encKey))
|
|
24940
|
+
: encKey;
|
|
24941
|
+
//if cipher key encryption is disabled but the item has an individual key,
|
|
24942
|
+
//then we rollback to using the user key as the main key of encryption of the item
|
|
24943
|
+
//in order to keep item and it's attachments with the same encryption level
|
|
24944
|
+
if (cipher.key != null && !cipherKeyEncryptionEnabled) {
|
|
24945
|
+
const model = yield cipher.decrypt(yield this.getKeyForCipherKeyDecryption(cipher));
|
|
24946
|
+
cipher = yield this.encrypt(model);
|
|
24947
|
+
yield this.updateWithServer(cipher);
|
|
24948
|
+
}
|
|
24949
|
+
const encFileName = yield this.encryptService.encrypt(filename, cipherEncKey);
|
|
24950
|
+
const dataEncKey = yield this.cryptoService.makeDataEncKey(cipherEncKey);
|
|
24951
|
+
const encData = yield this.encryptService.encryptToBytes(new Uint8Array(data), dataEncKey[0]);
|
|
24836
24952
|
const response = yield this.cipherFileUploadService.upload(cipher, encFileName, encData, admin, dataEncKey);
|
|
24837
24953
|
const cData = new CipherData(response, cipher.collectionIds);
|
|
24838
24954
|
if (!admin) {
|
|
@@ -25120,7 +25236,68 @@ class CipherService {
|
|
|
25120
25236
|
yield this.restore(restores);
|
|
25121
25237
|
});
|
|
25122
25238
|
}
|
|
25239
|
+
getKeyForCipherKeyDecryption(cipher) {
|
|
25240
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25241
|
+
return ((yield this.cryptoService.getOrgKey(cipher.organizationId)) ||
|
|
25242
|
+
(yield this.cryptoService.getUserKeyWithLegacySupport()));
|
|
25243
|
+
});
|
|
25244
|
+
}
|
|
25123
25245
|
// Helpers
|
|
25246
|
+
// In the case of a cipher that is being shared with an organization, we want to decrypt the
|
|
25247
|
+
// cipher key with the user's key and then re-encrypt it with the organization's key.
|
|
25248
|
+
encryptSharedCipher(model) {
|
|
25249
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25250
|
+
const keyForCipherKeyDecryption = yield this.cryptoService.getUserKeyWithLegacySupport();
|
|
25251
|
+
return yield this.encrypt(model, null, keyForCipherKeyDecryption);
|
|
25252
|
+
});
|
|
25253
|
+
}
|
|
25254
|
+
updateModelfromExistingCipher(model, originalCipher) {
|
|
25255
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25256
|
+
const existingCipher = yield originalCipher.decrypt(yield this.getKeyForCipherKeyDecryption(originalCipher));
|
|
25257
|
+
model.passwordHistory = existingCipher.passwordHistory || [];
|
|
25258
|
+
if (model.type === CipherType.Login && existingCipher.type === CipherType.Login) {
|
|
25259
|
+
if (existingCipher.login.password != null &&
|
|
25260
|
+
existingCipher.login.password !== "" &&
|
|
25261
|
+
existingCipher.login.password !== model.login.password) {
|
|
25262
|
+
const ph = new PasswordHistoryView();
|
|
25263
|
+
ph.password = existingCipher.login.password;
|
|
25264
|
+
ph.lastUsedDate = model.login.passwordRevisionDate = new Date();
|
|
25265
|
+
model.passwordHistory.splice(0, 0, ph);
|
|
25266
|
+
}
|
|
25267
|
+
else {
|
|
25268
|
+
model.login.passwordRevisionDate = existingCipher.login.passwordRevisionDate;
|
|
25269
|
+
}
|
|
25270
|
+
}
|
|
25271
|
+
if (existingCipher.hasFields) {
|
|
25272
|
+
const existingHiddenFields = existingCipher.fields.filter((f) => f.type === FieldType.Hidden &&
|
|
25273
|
+
f.name != null &&
|
|
25274
|
+
f.name !== "" &&
|
|
25275
|
+
f.value != null &&
|
|
25276
|
+
f.value !== "");
|
|
25277
|
+
const hiddenFields = model.fields == null
|
|
25278
|
+
? []
|
|
25279
|
+
: model.fields.filter((f) => f.type === FieldType.Hidden && f.name != null && f.name !== "");
|
|
25280
|
+
existingHiddenFields.forEach((ef) => {
|
|
25281
|
+
const matchedField = hiddenFields.find((f) => f.name === ef.name);
|
|
25282
|
+
if (matchedField == null || matchedField.value !== ef.value) {
|
|
25283
|
+
const ph = new PasswordHistoryView();
|
|
25284
|
+
ph.password = ef.name + ": " + ef.value;
|
|
25285
|
+
ph.lastUsedDate = new Date();
|
|
25286
|
+
model.passwordHistory.splice(0, 0, ph);
|
|
25287
|
+
}
|
|
25288
|
+
});
|
|
25289
|
+
}
|
|
25290
|
+
});
|
|
25291
|
+
}
|
|
25292
|
+
adjustPasswordHistoryLength(model) {
|
|
25293
|
+
if (model.passwordHistory != null && model.passwordHistory.length === 0) {
|
|
25294
|
+
model.passwordHistory = null;
|
|
25295
|
+
}
|
|
25296
|
+
else if (model.passwordHistory != null && model.passwordHistory.length > 5) {
|
|
25297
|
+
// only save last 5 history
|
|
25298
|
+
model.passwordHistory = model.passwordHistory.slice(0, 5);
|
|
25299
|
+
}
|
|
25300
|
+
}
|
|
25124
25301
|
shareAttachmentWithServer(attachmentView, cipherId, organizationId) {
|
|
25125
25302
|
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25126
25303
|
const attachmentResponse = yield this.apiService.nativeFetch(new Request(attachmentView.url, { cache: "no-store" }));
|
|
@@ -25298,6 +25475,49 @@ class CipherService {
|
|
|
25298
25475
|
clearSortedCiphers() {
|
|
25299
25476
|
this.sortedCiphersCache.clear();
|
|
25300
25477
|
}
|
|
25478
|
+
encryptCipher(model, cipher, key) {
|
|
25479
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25480
|
+
yield Promise.all([
|
|
25481
|
+
this.encryptObjProperty(model, cipher, {
|
|
25482
|
+
name: null,
|
|
25483
|
+
notes: null,
|
|
25484
|
+
}, key),
|
|
25485
|
+
this.encryptCipherData(cipher, model, key),
|
|
25486
|
+
this.encryptFields(model.fields, key).then((fields) => {
|
|
25487
|
+
cipher.fields = fields;
|
|
25488
|
+
}),
|
|
25489
|
+
this.encryptPasswordHistories(model.passwordHistory, key).then((ph) => {
|
|
25490
|
+
cipher.passwordHistory = ph;
|
|
25491
|
+
}),
|
|
25492
|
+
this.encryptAttachments(model.attachments, key).then((attachments) => {
|
|
25493
|
+
cipher.attachments = attachments;
|
|
25494
|
+
}),
|
|
25495
|
+
]);
|
|
25496
|
+
return cipher;
|
|
25497
|
+
});
|
|
25498
|
+
}
|
|
25499
|
+
encryptCipherWithCipherKey(model, cipher, keyForCipherKeyEncryption, keyForCipherKeyDecryption) {
|
|
25500
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25501
|
+
// First, we get the key for cipher key encryption, in its decrypted form
|
|
25502
|
+
let decryptedCipherKey;
|
|
25503
|
+
if (cipher.key == null) {
|
|
25504
|
+
decryptedCipherKey = yield this.cryptoService.makeCipherKey();
|
|
25505
|
+
}
|
|
25506
|
+
else {
|
|
25507
|
+
decryptedCipherKey = new SymmetricCryptoKey(yield this.encryptService.decryptToBytes(cipher.key, keyForCipherKeyDecryption));
|
|
25508
|
+
}
|
|
25509
|
+
// Then, we have to encrypt the cipher key with the proper key.
|
|
25510
|
+
cipher.key = yield this.encryptService.encrypt(decryptedCipherKey.key, keyForCipherKeyEncryption);
|
|
25511
|
+
// Finally, we can encrypt the cipher with the decrypted cipher key.
|
|
25512
|
+
return this.encryptCipher(model, cipher, decryptedCipherKey);
|
|
25513
|
+
});
|
|
25514
|
+
}
|
|
25515
|
+
getCipherKeyEncryptionEnabled() {
|
|
25516
|
+
return cipher_service_awaiter(this, void 0, void 0, function* () {
|
|
25517
|
+
return (flagEnabled("enableCipherKeyEncryption") &&
|
|
25518
|
+
(yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER))));
|
|
25519
|
+
});
|
|
25520
|
+
}
|
|
25301
25521
|
}
|
|
25302
25522
|
cipher_service_decorate([
|
|
25303
25523
|
sequentialize(() => "getAllDecrypted"),
|
|
@@ -26961,6 +27181,7 @@ class CipherExport {
|
|
|
26961
27181
|
domain.notes = req.notes != null ? new EncString(req.notes) : null;
|
|
26962
27182
|
domain.favorite = req.favorite;
|
|
26963
27183
|
domain.reprompt = (_a = req.reprompt) !== null && _a !== void 0 ? _a : CipherRepromptType.None;
|
|
27184
|
+
domain.key = req.key != null ? new EncString(req.key) : null;
|
|
26964
27185
|
if (req.fields != null) {
|
|
26965
27186
|
domain.fields = req.fields.map((f) => FieldExport.toDomain(f));
|
|
26966
27187
|
}
|
|
@@ -26988,7 +27209,7 @@ class CipherExport {
|
|
|
26988
27209
|
}
|
|
26989
27210
|
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
|
26990
27211
|
build(o) {
|
|
26991
|
-
var _a, _b;
|
|
27212
|
+
var _a, _b, _c;
|
|
26992
27213
|
this.organizationId = o.organizationId;
|
|
26993
27214
|
this.folderId = o.folderId;
|
|
26994
27215
|
this.type = o.type;
|
|
@@ -27000,6 +27221,7 @@ class CipherExport {
|
|
|
27000
27221
|
else {
|
|
27001
27222
|
this.name = (_a = o.name) === null || _a === void 0 ? void 0 : _a.encryptedString;
|
|
27002
27223
|
this.notes = (_b = o.notes) === null || _b === void 0 ? void 0 : _b.encryptedString;
|
|
27224
|
+
this.key = (_c = o.key) === null || _c === void 0 ? void 0 : _c.encryptedString;
|
|
27003
27225
|
}
|
|
27004
27226
|
this.favorite = o.favorite;
|
|
27005
27227
|
if (o.fields != null) {
|
|
@@ -27398,12 +27620,15 @@ class VaultExportService {
|
|
|
27398
27620
|
if (exportData.ciphers != null && exportData.ciphers.length > 0) {
|
|
27399
27621
|
exportData.ciphers
|
|
27400
27622
|
.filter((c) => c.deletedDate === null)
|
|
27401
|
-
.forEach((c) => {
|
|
27623
|
+
.forEach((c) => vault_export_service_awaiter(this, void 0, void 0, function* () {
|
|
27402
27624
|
const cipher = new Cipher(new CipherData(c));
|
|
27403
|
-
exportPromises.push(
|
|
27625
|
+
exportPromises.push(this.cipherService
|
|
27626
|
+
.getKeyForCipherKeyDecryption(cipher)
|
|
27627
|
+
.then((key) => cipher.decrypt(key))
|
|
27628
|
+
.then((decCipher) => {
|
|
27404
27629
|
decCiphers.push(decCipher);
|
|
27405
27630
|
}));
|
|
27406
|
-
});
|
|
27631
|
+
}));
|
|
27407
27632
|
}
|
|
27408
27633
|
}
|
|
27409
27634
|
return Promise.all(exportPromises);
|
|
@@ -28409,10 +28634,11 @@ var bitwarden_json_importer_awaiter = (undefined && undefined.__awaiter) || func
|
|
|
28409
28634
|
|
|
28410
28635
|
|
|
28411
28636
|
class BitwardenJsonImporter extends base_importer_BaseImporter {
|
|
28412
|
-
constructor(cryptoService, i18nService) {
|
|
28637
|
+
constructor(cryptoService, i18nService, cipherService) {
|
|
28413
28638
|
super();
|
|
28414
28639
|
this.cryptoService = cryptoService;
|
|
28415
28640
|
this.i18nService = i18nService;
|
|
28641
|
+
this.cipherService = cipherService;
|
|
28416
28642
|
}
|
|
28417
28643
|
parse(data) {
|
|
28418
28644
|
return bitwarden_json_importer_awaiter(this, void 0, void 0, function* () {
|
|
@@ -28472,7 +28698,7 @@ class BitwardenJsonImporter extends base_importer_BaseImporter {
|
|
|
28472
28698
|
}
|
|
28473
28699
|
});
|
|
28474
28700
|
}
|
|
28475
|
-
const view = yield cipher.decrypt();
|
|
28701
|
+
const view = yield cipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
|
28476
28702
|
this.cleanupCipher(view);
|
|
28477
28703
|
this.result.ciphers.push(view);
|
|
28478
28704
|
}
|
|
@@ -28584,8 +28810,8 @@ var bitwarden_password_protected_importer_awaiter = (undefined && undefined.__aw
|
|
|
28584
28810
|
|
|
28585
28811
|
|
|
28586
28812
|
class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter {
|
|
28587
|
-
constructor(cryptoService, i18nService, promptForPassword_callback) {
|
|
28588
|
-
super(cryptoService, i18nService);
|
|
28813
|
+
constructor(cryptoService, i18nService, cipherService, promptForPassword_callback) {
|
|
28814
|
+
super(cryptoService, i18nService, cipherService);
|
|
28589
28815
|
this.promptForPassword_callback = promptForPassword_callback;
|
|
28590
28816
|
}
|
|
28591
28817
|
parse(data) {
|
|
@@ -33736,7 +33962,7 @@ class ImportService {
|
|
|
33736
33962
|
return new BitwardenCsvImporter();
|
|
33737
33963
|
case "bitwardenjson":
|
|
33738
33964
|
case "bitwardenpasswordprotected":
|
|
33739
|
-
return new BitwardenPasswordProtectedImporter(this.cryptoService, this.i18nService, promptForPassword_callback);
|
|
33965
|
+
return new BitwardenPasswordProtectedImporter(this.cryptoService, this.i18nService, this.cipherService, promptForPassword_callback);
|
|
33740
33966
|
case "lastpasscsv":
|
|
33741
33967
|
case "passboltcsv":
|
|
33742
33968
|
return new LastPassCsvImporter();
|
|
@@ -34278,6 +34504,147 @@ class NodeCryptoFunctionService {
|
|
|
34278
34504
|
}
|
|
34279
34505
|
}
|
|
34280
34506
|
|
|
34507
|
+
;// CONCATENATED MODULE: ../../libs/common/src/platform/abstractions/config/server-config.ts
|
|
34508
|
+
const dayInMilliseconds = 24 * 3600 * 1000;
|
|
34509
|
+
const eighteenHoursInMilliseconds = 18 * 3600 * 1000;
|
|
34510
|
+
class ServerConfig {
|
|
34511
|
+
constructor(serverConfigData) {
|
|
34512
|
+
var _a, _b;
|
|
34513
|
+
this.featureStates = {};
|
|
34514
|
+
this.version = serverConfigData.version;
|
|
34515
|
+
this.gitHash = serverConfigData.gitHash;
|
|
34516
|
+
this.server = serverConfigData.server;
|
|
34517
|
+
this.utcDate = new Date(serverConfigData.utcDate);
|
|
34518
|
+
this.environment = serverConfigData.environment;
|
|
34519
|
+
this.featureStates = serverConfigData.featureStates;
|
|
34520
|
+
if (((_a = this.server) === null || _a === void 0 ? void 0 : _a.name) == null && ((_b = this.server) === null || _b === void 0 ? void 0 : _b.url) == null) {
|
|
34521
|
+
this.server = null;
|
|
34522
|
+
}
|
|
34523
|
+
}
|
|
34524
|
+
getAgeInMilliseconds() {
|
|
34525
|
+
var _a;
|
|
34526
|
+
return new Date().getTime() - ((_a = this.utcDate) === null || _a === void 0 ? void 0 : _a.getTime());
|
|
34527
|
+
}
|
|
34528
|
+
isValid() {
|
|
34529
|
+
return this.getAgeInMilliseconds() <= dayInMilliseconds;
|
|
34530
|
+
}
|
|
34531
|
+
expiresSoon() {
|
|
34532
|
+
return this.getAgeInMilliseconds() >= eighteenHoursInMilliseconds;
|
|
34533
|
+
}
|
|
34534
|
+
static fromJSON(obj) {
|
|
34535
|
+
if (obj == null) {
|
|
34536
|
+
return null;
|
|
34537
|
+
}
|
|
34538
|
+
return new ServerConfig(obj);
|
|
34539
|
+
}
|
|
34540
|
+
}
|
|
34541
|
+
|
|
34542
|
+
;// CONCATENATED MODULE: ../../libs/common/src/platform/services/config/config.service.ts
|
|
34543
|
+
var config_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
34544
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
34545
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
34546
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
34547
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
34548
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34549
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
34550
|
+
});
|
|
34551
|
+
};
|
|
34552
|
+
|
|
34553
|
+
|
|
34554
|
+
|
|
34555
|
+
|
|
34556
|
+
|
|
34557
|
+
|
|
34558
|
+
const ONE_HOUR_IN_MILLISECONDS = 1000 * 3600;
|
|
34559
|
+
class ConfigService {
|
|
34560
|
+
constructor(stateService, configApiService, authService, environmentService, logService,
|
|
34561
|
+
// Used to avoid duplicate subscriptions, e.g. in browser between the background and popup
|
|
34562
|
+
subscribe = true) {
|
|
34563
|
+
this.stateService = stateService;
|
|
34564
|
+
this.configApiService = configApiService;
|
|
34565
|
+
this.authService = authService;
|
|
34566
|
+
this.environmentService = environmentService;
|
|
34567
|
+
this.logService = logService;
|
|
34568
|
+
this.subscribe = subscribe;
|
|
34569
|
+
this.inited = false;
|
|
34570
|
+
this._serverConfig = new external_rxjs_namespaceObject.ReplaySubject(1);
|
|
34571
|
+
this.serverConfig$ = this._serverConfig.asObservable();
|
|
34572
|
+
this._forceFetchConfig = new external_rxjs_namespaceObject.Subject();
|
|
34573
|
+
this.refreshTimer$ = (0,external_rxjs_namespaceObject.timer)(ONE_HOUR_IN_MILLISECONDS, ONE_HOUR_IN_MILLISECONDS); // after 1 hour, then every hour
|
|
34574
|
+
this.cloudRegion$ = this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((config) => { var _a, _b; return (_b = (_a = config === null || config === void 0 ? void 0 : config.environment) === null || _a === void 0 ? void 0 : _a.cloudRegion) !== null && _b !== void 0 ? _b : Region.US; }));
|
|
34575
|
+
}
|
|
34576
|
+
init() {
|
|
34577
|
+
if (!this.subscribe || this.inited) {
|
|
34578
|
+
return;
|
|
34579
|
+
}
|
|
34580
|
+
const latestServerConfig$ = (0,external_rxjs_namespaceObject.defer)(() => this.configApiService.get()).pipe((0,external_rxjs_namespaceObject.map)((response) => new ServerConfigData(response)), (0,external_rxjs_namespaceObject.delayWhen)((data) => this.saveConfig(data)), (0,external_rxjs_namespaceObject.catchError)((e) => {
|
|
34581
|
+
// fall back to stored ServerConfig (if any)
|
|
34582
|
+
this.logService.error("Unable to fetch ServerConfig: " + (e === null || e === void 0 ? void 0 : e.message));
|
|
34583
|
+
return this.stateService.getServerConfig();
|
|
34584
|
+
}));
|
|
34585
|
+
// If you need to fetch a new config when an event occurs, add an observable that emits on that event here
|
|
34586
|
+
(0,external_rxjs_namespaceObject.merge)(this.refreshTimer$, // an overridable interval
|
|
34587
|
+
this.environmentService.urls, // when environment URLs change (including when app is started)
|
|
34588
|
+
this._forceFetchConfig // manual
|
|
34589
|
+
)
|
|
34590
|
+
.pipe((0,external_rxjs_namespaceObject.concatMap)(() => latestServerConfig$), (0,external_rxjs_namespaceObject.map)((data) => (data == null ? null : new ServerConfig(data))))
|
|
34591
|
+
.subscribe((config) => this._serverConfig.next(config));
|
|
34592
|
+
this.inited = true;
|
|
34593
|
+
}
|
|
34594
|
+
getFeatureFlag$(key, defaultValue) {
|
|
34595
|
+
return this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((serverConfig) => {
|
|
34596
|
+
if ((serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.featureStates) == null || serverConfig.featureStates[key] == null) {
|
|
34597
|
+
return defaultValue;
|
|
34598
|
+
}
|
|
34599
|
+
return serverConfig.featureStates[key];
|
|
34600
|
+
}));
|
|
34601
|
+
}
|
|
34602
|
+
getFeatureFlag(key, defaultValue) {
|
|
34603
|
+
return config_service_awaiter(this, void 0, void 0, function* () {
|
|
34604
|
+
return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.getFeatureFlag$(key, defaultValue));
|
|
34605
|
+
});
|
|
34606
|
+
}
|
|
34607
|
+
triggerServerConfigFetch() {
|
|
34608
|
+
this._forceFetchConfig.next();
|
|
34609
|
+
}
|
|
34610
|
+
saveConfig(data) {
|
|
34611
|
+
var _a;
|
|
34612
|
+
return config_service_awaiter(this, void 0, void 0, function* () {
|
|
34613
|
+
if ((yield this.authService.getAuthStatus()) === AuthenticationStatus.LoggedOut) {
|
|
34614
|
+
return;
|
|
34615
|
+
}
|
|
34616
|
+
yield this.stateService.setServerConfig(data);
|
|
34617
|
+
this.environmentService.setCloudWebVaultUrl((_a = data.environment) === null || _a === void 0 ? void 0 : _a.cloudRegion);
|
|
34618
|
+
});
|
|
34619
|
+
}
|
|
34620
|
+
/**
|
|
34621
|
+
* Verifies whether the server version meets the minimum required version
|
|
34622
|
+
* @param minimumRequiredServerVersion The minimum version required
|
|
34623
|
+
* @returns True if the server version is greater than or equal to the minimum required version
|
|
34624
|
+
*/
|
|
34625
|
+
checkServerMeetsVersionRequirement$(minimumRequiredServerVersion) {
|
|
34626
|
+
return this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((serverConfig) => {
|
|
34627
|
+
if (serverConfig == null) {
|
|
34628
|
+
return false;
|
|
34629
|
+
}
|
|
34630
|
+
const serverVersion = new external_semver_namespaceObject.SemVer(serverConfig.version);
|
|
34631
|
+
return serverVersion.compare(minimumRequiredServerVersion) >= 0;
|
|
34632
|
+
}));
|
|
34633
|
+
}
|
|
34634
|
+
}
|
|
34635
|
+
|
|
34636
|
+
;// CONCATENATED MODULE: ./src/platform/services/cli-config.service.ts
|
|
34637
|
+
|
|
34638
|
+
|
|
34639
|
+
class CliConfigService extends ConfigService {
|
|
34640
|
+
constructor() {
|
|
34641
|
+
super(...arguments);
|
|
34642
|
+
// The rxjs timer uses setTimeout/setInterval under the hood, which prevents the node process from exiting
|
|
34643
|
+
// when the command is finished. Cli should never be alive long enough to use the timer, so we disable it.
|
|
34644
|
+
this.refreshTimer$ = external_rxjs_namespaceObject.NEVER;
|
|
34645
|
+
}
|
|
34646
|
+
}
|
|
34647
|
+
|
|
34281
34648
|
;// CONCATENATED MODULE: external "child_process"
|
|
34282
34649
|
const external_child_process_namespaceObject = require("child_process");
|
|
34283
34650
|
;// CONCATENATED MODULE: ./src/platform/services/cli-platform-utils.service.ts
|
|
@@ -34958,6 +35325,7 @@ class CipherResponse extends BaseResponse {
|
|
|
34958
35325
|
this.passwordHistory = passwordHistory.map((h) => new PasswordHistoryResponse(h));
|
|
34959
35326
|
}
|
|
34960
35327
|
this.reprompt = this.getResponseProperty("Reprompt") || CipherRepromptType.None;
|
|
35328
|
+
this.key = this.getResponseProperty("Key") || null;
|
|
34961
35329
|
}
|
|
34962
35330
|
}
|
|
34963
35331
|
|
|
@@ -38724,11 +39092,11 @@ class ShareCommand {
|
|
|
38724
39092
|
if (cipher.organizationId != null) {
|
|
38725
39093
|
return Response.badRequest("This item already belongs to an organization.");
|
|
38726
39094
|
}
|
|
38727
|
-
const cipherView = yield cipher.decrypt();
|
|
39095
|
+
const cipherView = yield cipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
|
38728
39096
|
try {
|
|
38729
39097
|
yield this.cipherService.shareWithServer(cipherView, organizationId, req);
|
|
38730
39098
|
const updatedCipher = yield this.cipherService.get(cipher.id);
|
|
38731
|
-
const decCipher = yield updatedCipher.decrypt();
|
|
39099
|
+
const decCipher = yield updatedCipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(updatedCipher));
|
|
38732
39100
|
const res = new cipher_response_CipherResponse(decCipher);
|
|
38733
39101
|
return Response.success(res);
|
|
38734
39102
|
}
|
|
@@ -39824,7 +40192,7 @@ class CreateCommand {
|
|
|
39824
40192
|
try {
|
|
39825
40193
|
yield this.cipherService.createWithServer(cipher);
|
|
39826
40194
|
const newCipher = yield this.cipherService.get(cipher.id);
|
|
39827
|
-
const decCipher = yield newCipher.decrypt();
|
|
40195
|
+
const decCipher = yield newCipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(newCipher));
|
|
39828
40196
|
const res = new cipher_response_CipherResponse(decCipher);
|
|
39829
40197
|
return Response.success(res);
|
|
39830
40198
|
}
|
|
@@ -39877,7 +40245,7 @@ class CreateCommand {
|
|
|
39877
40245
|
try {
|
|
39878
40246
|
yield this.cipherService.saveAttachmentRawWithServer(cipher, fileName, new Uint8Array(fileBuf).buffer);
|
|
39879
40247
|
const updatedCipher = yield this.cipherService.get(cipher.id);
|
|
39880
|
-
const decCipher = yield updatedCipher.decrypt();
|
|
40248
|
+
const decCipher = yield updatedCipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(updatedCipher));
|
|
39881
40249
|
return Response.success(new cipher_response_CipherResponse(decCipher));
|
|
39882
40250
|
}
|
|
39883
40251
|
catch (e) {
|
|
@@ -40200,7 +40568,7 @@ class EditCommand {
|
|
|
40200
40568
|
if (cipher == null) {
|
|
40201
40569
|
return Response.notFound();
|
|
40202
40570
|
}
|
|
40203
|
-
let cipherView = yield cipher.decrypt();
|
|
40571
|
+
let cipherView = yield cipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
|
40204
40572
|
if (cipherView.isDeleted) {
|
|
40205
40573
|
return Response.badRequest("You may not edit a deleted item. Use the restore command first.");
|
|
40206
40574
|
}
|
|
@@ -40209,7 +40577,7 @@ class EditCommand {
|
|
|
40209
40577
|
try {
|
|
40210
40578
|
yield this.cipherService.updateWithServer(encCipher);
|
|
40211
40579
|
const updatedCipher = yield this.cipherService.get(cipher.id);
|
|
40212
|
-
const decCipher = yield updatedCipher.decrypt();
|
|
40580
|
+
const decCipher = yield updatedCipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(updatedCipher));
|
|
40213
40581
|
const res = new cipher_response_CipherResponse(decCipher);
|
|
40214
40582
|
return Response.success(res);
|
|
40215
40583
|
}
|
|
@@ -40231,7 +40599,7 @@ class EditCommand {
|
|
|
40231
40599
|
try {
|
|
40232
40600
|
yield this.cipherService.saveCollectionsWithServer(cipher);
|
|
40233
40601
|
const updatedCipher = yield this.cipherService.get(cipher.id);
|
|
40234
|
-
const decCipher = yield updatedCipher.decrypt();
|
|
40602
|
+
const decCipher = yield updatedCipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(updatedCipher));
|
|
40235
40603
|
const res = new cipher_response_CipherResponse(decCipher);
|
|
40236
40604
|
return Response.success(res);
|
|
40237
40605
|
}
|
|
@@ -40448,7 +40816,7 @@ class GetCommand extends DownloadCommand {
|
|
|
40448
40816
|
if (utils_Utils.isGuid(id)) {
|
|
40449
40817
|
const cipher = yield this.cipherService.get(id);
|
|
40450
40818
|
if (cipher != null) {
|
|
40451
|
-
decCipher = yield cipher.decrypt();
|
|
40819
|
+
decCipher = yield cipher.decrypt(yield this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
|
40452
40820
|
}
|
|
40453
40821
|
}
|
|
40454
40822
|
else if (id.trim() !== "") {
|
|
@@ -43031,6 +43399,8 @@ var bw_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _argum
|
|
|
43031
43399
|
|
|
43032
43400
|
|
|
43033
43401
|
|
|
43402
|
+
|
|
43403
|
+
|
|
43034
43404
|
|
|
43035
43405
|
|
|
43036
43406
|
|
|
@@ -43089,10 +43459,7 @@ class Main {
|
|
|
43089
43459
|
this.cipherFileUploadService = new CipherFileUploadService(this.apiService, this.fileUploadService);
|
|
43090
43460
|
this.sendApiService = this.sendApiService = new SendApiService(this.apiService, this.fileUploadService, this.sendService);
|
|
43091
43461
|
this.searchService = new SearchService(this.logService, this.i18nService);
|
|
43092
|
-
this.cipherService = new CipherService(this.cryptoService, this.settingsService, this.apiService, this.i18nService, this.searchService, this.stateService, this.encryptService, this.cipherFileUploadService);
|
|
43093
43462
|
this.broadcasterService = new BroadcasterService();
|
|
43094
|
-
this.folderService = new FolderService(this.cryptoService, this.i18nService, this.cipherService, this.stateService);
|
|
43095
|
-
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
|
|
43096
43463
|
this.collectionService = new CollectionService(this.cryptoService, this.i18nService, this.stateService);
|
|
43097
43464
|
this.providerService = new ProviderService(this.stateService);
|
|
43098
43465
|
this.organizationService = new organization_service_OrganizationService(this.stateService);
|
|
@@ -43107,6 +43474,11 @@ class Main {
|
|
|
43107
43474
|
this.deviceTrustCryptoService = new DeviceTrustCryptoService(this.cryptoFunctionService, this.cryptoService, this.encryptService, this.stateService, this.appIdService, this.devicesApiService, this.i18nService, this.platformUtilsService);
|
|
43108
43475
|
this.authRequestCryptoService = new AuthRequestCryptoServiceImplementation(this.cryptoService);
|
|
43109
43476
|
this.authService = new AuthService(this.cryptoService, this.apiService, this.tokenService, this.appIdService, this.platformUtilsService, this.messagingService, this.logService, this.keyConnectorService, this.environmentService, this.stateService, this.twoFactorService, this.i18nService, this.encryptService, this.passwordStrengthService, this.policyService, this.deviceTrustCryptoService, this.authRequestCryptoService);
|
|
43477
|
+
this.configApiService = new ConfigApiService(this.apiService, this.authService);
|
|
43478
|
+
this.configService = new CliConfigService(this.stateService, this.configApiService, this.authService, this.environmentService, this.logService, true);
|
|
43479
|
+
this.cipherService = new CipherService(this.cryptoService, this.settingsService, this.apiService, this.i18nService, this.searchService, this.stateService, this.encryptService, this.cipherFileUploadService, this.configService);
|
|
43480
|
+
this.folderService = new FolderService(this.cryptoService, this.i18nService, this.cipherService, this.stateService);
|
|
43481
|
+
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
|
|
43110
43482
|
const lockedCallback = (userId) => bw_awaiter(this, void 0, void 0, function* () { return yield this.cryptoService.clearStoredUserKey(KeySuffixOptions.Auto); });
|
|
43111
43483
|
this.userVerificationService = new UserVerificationService(this.stateService, this.cryptoService, this.i18nService, this.userVerificationApiService);
|
|
43112
43484
|
this.vaultTimeoutSettingsService = new VaultTimeoutSettingsService(this.cryptoService, this.tokenService, this.policyService, this.stateService, this.userVerificationService);
|
|
@@ -43163,6 +43535,7 @@ class Main {
|
|
|
43163
43535
|
const locale = yield this.stateService.getLocale();
|
|
43164
43536
|
yield this.i18nService.init(locale);
|
|
43165
43537
|
this.twoFactorService.init();
|
|
43538
|
+
this.configService.init();
|
|
43166
43539
|
const installedVersion = yield this.stateService.getInstalledVersion();
|
|
43167
43540
|
const currentVersion = yield this.platformUtilsService.getApplicationVersion();
|
|
43168
43541
|
if (installedVersion == null || installedVersion !== currentVersion) {
|