diff --git a/CliClient/app/command-cat.js b/CliClient/app/command-cat.js index 3a66acc211..ff52f91595 100644 --- a/CliClient/app/command-cat.js +++ b/CliClient/app/command-cat.js @@ -2,6 +2,7 @@ const { BaseCommand } = require('./base-command.js'); const { app } = require('./app.js'); const { _ } = require('lib/locale.js'); const BaseModel = require('lib/BaseModel.js'); +const BaseItem = require('lib/models/BaseItem.js'); const Note = require('lib/models/Note.js'); class Command extends BaseCommand { @@ -23,15 +24,17 @@ class Command extends BaseCommand { const item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() }); if (!item) throw new Error(_('Cannot find "%s".', title)); - const content = args.options.verbose ? await Note.serialize(item) : await Note.serializeForEdit(item); - this.stdout(content); + let content = ''; - app() - .gui() - .showConsole(); - app() - .gui() - .maximizeConsole(); + if (item.encryption_applied) { + content = BaseItem.displayTitle(item); + } else { + content = args.options.verbose ? await Note.serialize(item) : await Note.serializeForEdit(item); + } + + this.stdout(content); + app().gui().showConsole(); + app().gui().maximizeConsole(); } } diff --git a/CliClient/app/command-e2ee.js b/CliClient/app/command-e2ee.js index 82b3d99a95..3a4082dbdb 100644 --- a/CliClient/app/command-e2ee.js +++ b/CliClient/app/command-e2ee.js @@ -48,7 +48,11 @@ class Command extends BaseCommand { while (true) { try { - await DecryptionWorker.instance().start(); + const result = await DecryptionWorker.instance().start(); + const line = []; + line.push(_('Decrypted items: %d', result.decryptedItemCount)); + if (result.skippedItemCount) line.push(_('Skipped items: %d (use --retry-failed-items to retry decrypting them)', result.skippedItemCount)); + this.stdout(line.join('\n')); break; } catch (error) { if (error.code === 'masterKeyNotLoaded') { diff --git a/ReactNativeClient/lib/reducer.js b/ReactNativeClient/lib/reducer.js index 757f61a0b5..618a6b4347 100644 --- a/ReactNativeClient/lib/reducer.js +++ b/ReactNativeClient/lib/reducer.js @@ -46,6 +46,8 @@ const defaultState = { itemIndex: 0, itemCount: 0, decryptedItemCounts: {}, + decryptedItemCount: 0, + skippedItemCount: 0, }, selectedNoteTags: [], resourceFetcher: { diff --git a/ReactNativeClient/lib/services/DecryptionWorker.js b/ReactNativeClient/lib/services/DecryptionWorker.js index 18b407cbfa..a47c2e55ef 100644 --- a/ReactNativeClient/lib/services/DecryptionWorker.js +++ b/ReactNativeClient/lib/services/DecryptionWorker.js @@ -138,6 +138,7 @@ class DecryptionWorker { const excludedIds = []; const decryptedItemCounts = {}; + let skippedItemCount = 0; this.dispatch({ type: 'ENCRYPTION_HAS_DISABLED_ITEMS', value: false }); this.dispatchReport({ state: 'started' }); @@ -172,6 +173,7 @@ class DecryptionWorker { if (decryptCounter > this.maxDecryptionAttempts_) { this.logger().debug(`DecryptionWorker: ${BaseModel.modelTypeToName(item.type_)} ${item.id}: Decryption has failed more than 2 times - skipping it`); this.dispatch({ type: 'ENCRYPTION_HAS_DISABLED_ITEMS', value: true }); + skippedItemCount++; excludedIds.push(item.id); continue; } @@ -245,24 +247,34 @@ class DecryptionWorker { this.state_ = 'idle'; - this.dispatchReport({ - state: 'idle', + let decryptedItemCount = 0; + for (const itemType in decryptedItemCounts) decryptedItemCount += decryptedItemCounts[itemType]; + + const finalReport = { + skippedItemCount: skippedItemCount, decryptedItemCounts: decryptedItemCounts, - }); + decryptedItemCount: decryptedItemCount, + }; + + this.dispatchReport(Object.assign({}, finalReport, { state: 'idle' })); if (downloadedButEncryptedBlobCount) { this.logger().info(`DecryptionWorker: Some resources have been downloaded but are not decrypted yet. Scheduling another decryption. Resource count: ${downloadedButEncryptedBlobCount}`); this.scheduleStart(); } + + return finalReport; } async start(options) { this.startCalls_.push(true); + let output = null; try { - await this.start_(options); + output = await this.start_(options); } finally { this.startCalls_.pop(); } + return output; } async destroy() {