diff --git a/lib/Controller/AccountsController.php b/lib/Controller/AccountsController.php index bc1d6b3567..4eaf204fdf 100644 --- a/lib/Controller/AccountsController.php +++ b/lib/Controller/AccountsController.php @@ -216,6 +216,7 @@ public function update(int $id, * @param int|null $archiveMailboxId * @param int|null $snoozeMailboxId * @param bool|null $signatureAboveQuote + * @param bool|null $signatureSeparator * @param bool|null $classificationEnabled * * @return JSONResponse @@ -233,6 +234,7 @@ public function patchAccount(int $id, ?int $archiveMailboxId = null, ?int $snoozeMailboxId = null, ?bool $signatureAboveQuote = null, + ?bool $signatureSeparator = null, ?int $trashRetentionDays = null, ?int $junkMailboxId = null, ?bool $searchBody = null, @@ -276,6 +278,9 @@ public function patchAccount(int $id, if ($signatureAboveQuote !== null) { $dbAccount->setSignatureAboveQuote($signatureAboveQuote); } + if ($signatureSeparator !== null) { + $dbAccount->setSignatureSeparator($signatureSeparator); + } if ($trashRetentionDays !== null) { // Passing 0 (or lower) disables retention $dbAccount->setTrashRetentionDays($trashRetentionDays <= 0 ? null : $trashRetentionDays); diff --git a/lib/Db/MailAccount.php b/lib/Db/MailAccount.php index f3e8b900cb..60e60fffad 100644 --- a/lib/Db/MailAccount.php +++ b/lib/Db/MailAccount.php @@ -79,6 +79,8 @@ * @method void setSievePassword(?string $sievePassword) * @method bool|null isSignatureAboveQuote() * @method void setSignatureAboveQuote(bool $signatureAboveQuote) + * @method bool|null isSignatureSeparator() + * @method void setSignatureSeparator(bool $signatureSeparator) * @method string getAuthMethod() * @method void setAuthMethod(string $method) * @method int getSignatureMode() @@ -165,6 +167,8 @@ class MailAccount extends Entity { protected $sievePassword; /** @var bool */ protected $signatureAboveQuote = false; + /** @var bool */ + protected $signatureSeparator = true; /** @var int|null */ protected $provisioningId; @@ -245,6 +249,9 @@ public function __construct(array $params = []) { if (isset($params['signatureAboveQuote'])) { $this->setSignatureAboveQuote($params['signatureAboveQuote']); } + if (isset($params['signatureSeparator'])) { + $this->setSignatureSeparator($params['signatureSeparator']); + } if (isset($params['trashRetentionDays'])) { $this->setTrashRetentionDays($params['trashRetentionDays']); } @@ -276,6 +283,7 @@ public function __construct(array $params = []) { $this->addType('sieveEnabled', 'boolean'); $this->addType('sievePort', 'integer'); $this->addType('signatureAboveQuote', 'boolean'); + $this->addType('signatureSeparator', 'boolean'); $this->addType('signatureMode', 'integer'); $this->addType('smimeCertificateId', 'integer'); $this->addType('quotaPercentage', 'integer'); @@ -327,6 +335,7 @@ public function toJson() { 'snoozeMailboxId' => $this->getSnoozeMailboxId(), 'sieveEnabled' => ($this->isSieveEnabled() === true), 'signatureAboveQuote' => ($this->isSignatureAboveQuote() === true), + 'signatureSeparator' => ($this->isSignatureSeparator() !== false), 'signatureMode' => $this->getSignatureMode(), 'smimeCertificateId' => $this->getSmimeCertificateId(), 'quotaPercentage' => $this->getQuotaPercentage(), diff --git a/lib/Migration/Version5009Date20260617000000.php b/lib/Migration/Version5009Date20260617000000.php new file mode 100644 index 0000000000..6f14b251e2 --- /dev/null +++ b/lib/Migration/Version5009Date20260617000000.php @@ -0,0 +1,45 @@ +getTable('mail_accounts'); + + if (!$accountsTable->hasColumn('signature_separator')) { + $accountsTable->addColumn('signature_separator', Types::BOOLEAN, [ + 'notnull' => false, + 'default' => true, + ]); + } + + return $schema; + } +} diff --git a/lib/UserMigration/MailAccountMigrator.php b/lib/UserMigration/MailAccountMigrator.php index 424028f67e..d0571129c4 100644 --- a/lib/UserMigration/MailAccountMigrator.php +++ b/lib/UserMigration/MailAccountMigrator.php @@ -147,6 +147,7 @@ public function import(IUser $user, IImportSource $importSource, OutputInterface $newAccount->setSearchBody($accountData['searchBody'] ?? false); $newAccount->setClassificationEnabled($accountData['classificationEnabled'] ?? false); $newAccount->setSignatureAboveQuote($accountData['signatureAboveQuote'] ?? false); + $newAccount->setSignatureSeparator($accountData['signatureSeparator'] ?? true); $newAccount->setPersonalNamespace($accountData['personalNamespace'] ?? null); if (isset($accountData['inboundPassword'])) { $newAccount->setInboundPassword($this->crypto->encrypt($accountData['inboundPassword'])); diff --git a/src/ckeditor/signature/InsertSignatureCommand.js b/src/ckeditor/signature/InsertSignatureCommand.js index 0eeab5bb21..210bca4697 100644 --- a/src/ckeditor/signature/InsertSignatureCommand.js +++ b/src/ckeditor/signature/InsertSignatureCommand.js @@ -34,8 +34,9 @@ export default class InsertSignatureCommand extends Command { * @param {module:engine/model/writer~Writer} writer instance * @param {string} signature text * @param {boolean} signatureAboveQuote signature position: above/below the quoted text + * @param {boolean} signatureSeparator whether to prepend the "-- " separator above the signature */ - insertSignatureElement(editor, writer, signature, signatureAboveQuote) { + insertSignatureElement(editor, writer, signature, signatureAboveQuote, signatureSeparator) { // Skip empty signature if (signature.length === 0) { return @@ -55,8 +56,10 @@ export default class InsertSignatureCommand extends Command { const modelFragment = editor.data.toModel(viewFragment) const signatureElement = writer.createElement('signature') - writer.append(writer.createText('-- '), signatureElement) - writer.append(writer.createElement('paragraph'), signatureElement) + if (signatureSeparator !== false) { + writer.append(writer.createText('-- '), signatureElement) + writer.append(writer.createElement('paragraph'), signatureElement) + } writer.append(modelFragment, signatureElement) if (signatureAboveQuote) { writer.append(writer.createElement('paragraph'), signatureElement) @@ -122,8 +125,9 @@ export default class InsertSignatureCommand extends Command { * @param {string} trigger TRIGGER_CHANGE_ALIAS or TRIGGER_EDITOR_READY * @param {string} signature text * @param {boolean} signatureAboveQuote signature position: above/below the quoted text + * @param {boolean} signatureSeparator whether to prepend the "-- " separator above the signature */ - execute(trigger, signature, signatureAboveQuote) { + execute(trigger, signature, signatureAboveQuote, signatureSeparator) { this.editor.model.change((writer) => { /** * TRIGGER_CHANGE_ALIAS: @@ -139,11 +143,11 @@ export default class InsertSignatureCommand extends Command { if (trigger === TRIGGER_CHANGE_ALIAS) { this.removeSignatureElement(this.editor, writer) - this.insertSignatureElement(this.editor, writer, signature, signatureAboveQuote) + this.insertSignatureElement(this.editor, writer, signature, signatureAboveQuote, signatureSeparator) } if (trigger === TRIGGER_EDITOR_READY && !this.hasSignatureElement(this.editor)) { - this.insertSignatureElement(this.editor, writer, signature, signatureAboveQuote) + this.insertSignatureElement(this.editor, writer, signature, signatureAboveQuote, signatureSeparator) } }) } diff --git a/src/components/Composer.vue b/src/components/Composer.vue index e8c217aeb1..8a5d31c221 100644 --- a/src/components/Composer.vue +++ b/src/components/Composer.vue @@ -798,6 +798,7 @@ export default { name: account.name, emailAddress: account.emailAddress, signatureAboveQuote: account.signatureAboveQuote, + signatureSeparator: account.signatureSeparator, smimeCertificateId: account.smimeCertificateId, selectable: account.connectionStatus, }, @@ -811,6 +812,7 @@ export default { name: alias.name, emailAddress: alias.alias, signatureAboveQuote: account.signatureAboveQuote, + signatureSeparator: account.signatureSeparator, smimeCertificateId: alias.smimeCertificateId, selectable: account.connectionStatus, } @@ -1307,6 +1309,7 @@ export default { trigger, toHtml(detect(this.selectedAlias.signature)).value, this.selectedAlias.signatureAboveQuote, + this.selectedAlias.signatureSeparator, ) this.changeSignature = false diff --git a/src/components/SignatureSettings.vue b/src/components/SignatureSettings.vue index e5bdc18d27..42299c9ee2 100644 --- a/src/components/SignatureSettings.vue +++ b/src/components/SignatureSettings.vue @@ -15,6 +15,16 @@ {{ t("mail", "Place signature above quoted text") }} +
bonjour bonjour
' + const expected = 'bonjour bonjour
Jane Doe
Jane Doe
', + false, + false, + ) + + expect(editor.getData()).toEqual(expected) + }) + it('Add signature to content above quote', async () => { const text = 'bonjour bonjour
bonjour bonjour
bonjour bonjour
Jane Doe
"John Doe" john.doe@localhost - January 1, 1970 1:00 AM
bonjour bonjour