(global) allow to add image block into template and signature composers

Images are embedded as base64 data URLs directly in the BlockNote content,
unlike the message composer which uses blob uploads + CID references.
This approach keeps templates and signatures self-contained without
requiring an attachment system.

Furthermore, a email-safe safe html exporter has been created to
serialize blocknote content into html.

A new backend setting MAX_TEMPLATE_IMAGE_SIZE (default 2 MiB) controls
the maximum allowed image size for these composers.
This commit is contained in:
jbpenrath
2026-02-17 19:02:28 +01:00
parent 100f671e1e
commit c53e8bfcd4
58 changed files with 3809 additions and 1025 deletions
+68 -74
View File
@@ -235,6 +235,11 @@
"description": "Maximum number of recipients per message (to + cc + bcc)",
"readOnly": true
},
"MAX_TEMPLATE_IMAGE_SIZE": {
"type": "integer",
"description": "Maximum size in bytes for images embedded in templates and signatures",
"readOnly": true
},
"IMAGE_PROXY_ENABLED": {
"type": "boolean",
"description": "Whether external images should be proxied",
@@ -260,6 +265,7 @@
"MAX_OUTGOING_BODY_SIZE",
"MAX_INCOMING_EMAIL_SIZE",
"MAX_RECIPIENTS_PER_MESSAGE",
"MAX_TEMPLATE_IMAGE_SIZE",
"IMAGE_PROXY_ENABLED",
"MESSAGES_MANUAL_RETRY_MAX_AGE"
]
@@ -1309,6 +1315,63 @@
}
}
},
"/api/v1.0/draft/{message_id}/placeholders/": {
"get": {
"operationId": "draft_placeholders_retrieve",
"description": "Resolve placeholder values for the authenticated user in the context of a draft message. The mailbox is derived from the draft's sender. recipient_name is resolved from the draft's TO recipients.",
"summary": "Resolve placeholder values for a draft",
"parameters": [
{
"in": "path",
"name": "message_id",
"schema": {
"type": "string",
"format": "uuid"
},
"required": true
}
],
"tags": [
"messages"
],
"security": [
{
"cookieAuth": []
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"description": "Placeholder keys mapped to their resolved values",
"additionalProperties": {
"type": "string"
},
"example": {
"name": "John Doe",
"recipient_name": "Jane Smith",
"job_title": "Developer"
}
}
}
},
"description": ""
},
"404": {
"content": {
"application/json": {
"schema": {
"description": "Draft not found"
}
}
},
"description": ""
}
}
}
},
"/api/v1.0/flag/": {
"post": {
"operationId": "flag_create",
@@ -2851,7 +2914,7 @@
},
"post": {
"operationId": "mailboxes_message_templates_create",
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
"description": "ViewSet for managing message templates for a mailbox.",
"parameters": [
{
"in": "path",
@@ -2903,7 +2966,7 @@
"/api/v1.0/mailboxes/{mailbox_id}/message-templates/{id}/": {
"get": {
"operationId": "mailboxes_message_templates_retrieve",
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
"description": "ViewSet for managing message templates for a mailbox.",
"parameters": [
{
"in": "path",
@@ -2946,7 +3009,7 @@
},
"put": {
"operationId": "mailboxes_message_templates_update",
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
"description": "ViewSet for managing message templates for a mailbox.",
"parameters": [
{
"in": "path",
@@ -3004,7 +3067,7 @@
},
"patch": {
"operationId": "mailboxes_message_templates_partial_update",
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
"description": "ViewSet for managing message templates for a mailbox.",
"parameters": [
{
"in": "path",
@@ -3061,7 +3124,7 @@
},
"delete": {
"operationId": "mailboxes_message_templates_destroy",
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
"description": "ViewSet for managing message templates for a mailbox.",
"parameters": [
{
"in": "path",
@@ -3096,75 +3159,6 @@
}
}
},
"/api/v1.0/mailboxes/{mailbox_id}/message-templates/{id}/render/": {
"get": {
"operationId": "mailboxes_message_templates_render_retrieve",
"description": "Render a template with the provided context variables.",
"parameters": [
{
"in": "query",
"name": "*",
"schema": {
"type": "string"
},
"description": "Any other parameter will be available in the template context",
"examples": {
"Example": {
"value": "value"
}
}
},
{
"in": "path",
"name": "id",
"schema": {
"type": "string"
},
"required": true
},
{
"in": "path",
"name": "mailbox_id",
"schema": {
"type": "string",
"format": "uuid"
},
"required": true
}
],
"tags": [
"mailboxes"
],
"security": [
{
"cookieAuth": []
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"html_body": {
"type": "string"
},
"text_body": {
"type": "string"
}
}
}
}
},
"description": "Template rendered with provided context"
},
"404": {
"description": "Template not found"
}
}
}
},
"/api/v1.0/mailboxes/{mailbox_id}/message-templates/available/": {
"get": {
"operationId": "mailboxes_message_templates_available_list",