Auth hardening: - payments: per-customer JWT authorization on dual-use /payments routes (balance/methods/invoice/checkout/setup/portal/toggle-ppa) via authorizeCustomer + PAYMENTS_AUTH=enforce; portal retains+sends magic-link JWT (sessionStorage) - hub: fail-closed Stripe webhook, /accept/doc-pdf IDOR gate, telephony field-name guard (SQLi), modem-bridge private-IP guard (SSRF), ALWAYS_ENFORCE expansion Leaked-credential cleanup (token already rotated in ERPNext): - de-hardcode ERPNext API token -> env in bulk_submit.py, import_items.py, apps/client/deploy.sh; placeholder in apps/ops/infra/nginx.conf (nginx injects) - ops prod build no longer bakes VITE_ERP_TOKEN (.env.production empty) - de-hardcode legacy DB password -> env in import_items.py - gitignore legacy migration PII exports (tsv/json) Conversations/UI: - floating (un-docked) conversation panel; full-width mailbox - per-message real sender from email headers; unified scroll; header spacing - campaign pre-send review (subject/from/channel), Gmail send channel, clone-as-draft Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
389 lines
12 KiB
JSON
389 lines
12 KiB
JSON
{
|
||
"counters": {
|
||
"u_row": 3,
|
||
"u_column": 3,
|
||
"u_content_text": 5,
|
||
"u_content_image": 1,
|
||
"u_content_button": 0,
|
||
"u_content_divider": 0,
|
||
"u_content_html": 0
|
||
},
|
||
"body": {
|
||
"id": "u_body",
|
||
"rows": [
|
||
{
|
||
"id": "u_row_1",
|
||
"cells": [
|
||
1
|
||
],
|
||
"columns": [
|
||
{
|
||
"id": "u_column_1",
|
||
"contents": [
|
||
{
|
||
"id": "u_content_image_1",
|
||
"type": "image",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "28px 28px 10px",
|
||
"anchor": "",
|
||
"src": {
|
||
"url": "https://xqy3m.mjt.lu/img2/xqy3m/eed4d18c-8065-4c5f-b47c-58af63171cd0/content",
|
||
"width": 140,
|
||
"height": "auto",
|
||
"autoWidth": false,
|
||
"maxWidth": "140px"
|
||
},
|
||
"textAlign": "left",
|
||
"altText": "TARGO",
|
||
"action": {
|
||
"name": "web",
|
||
"values": {
|
||
"href": "",
|
||
"target": "_blank"
|
||
}
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_image_1",
|
||
"htmlClassNames": "u_content_image"
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"_meta": {
|
||
"htmlID": "u_column_1",
|
||
"htmlClassNames": "u_column"
|
||
},
|
||
"padding": "0px",
|
||
"border": {},
|
||
"borderRadius": "0px",
|
||
"backgroundColor": ""
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"columns": false,
|
||
"backgroundColor": "#ffffff",
|
||
"columnsBackgroundColor": "",
|
||
"backgroundImage": {
|
||
"url": "",
|
||
"fullWidth": true,
|
||
"repeat": "no-repeat",
|
||
"size": "custom",
|
||
"position": "center"
|
||
},
|
||
"padding": "0px",
|
||
"anchor": "",
|
||
"borderRadius": "",
|
||
"_meta": {
|
||
"htmlID": "u_row_1",
|
||
"htmlClassNames": "u_row"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"id": "u_row_2",
|
||
"cells": [
|
||
1
|
||
],
|
||
"columns": [
|
||
{
|
||
"id": "u_column_2",
|
||
"contents": [
|
||
{
|
||
"id": "u_content_text_1",
|
||
"type": "text",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "20px 28px 0",
|
||
"anchor": "",
|
||
"fontWeight": 400,
|
||
"fontSize": "15px",
|
||
"color": "#1e293b",
|
||
"textAlign": "left",
|
||
"lineHeight": "160%",
|
||
"linkStyle": {
|
||
"inherit": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_text_1",
|
||
"htmlClassNames": "u_content_text"
|
||
},
|
||
"text": "Bonjour {{firstname}},"
|
||
}
|
||
},
|
||
{
|
||
"id": "u_content_text_2",
|
||
"type": "text",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "14px 28px 0",
|
||
"anchor": "",
|
||
"fontWeight": 400,
|
||
"fontSize": "15px",
|
||
"color": "#1e293b",
|
||
"textAlign": "left",
|
||
"lineHeight": "160%",
|
||
"linkStyle": {
|
||
"inherit": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_text_2",
|
||
"htmlClassNames": "u_content_text"
|
||
},
|
||
"text": "À la suite d’une erreur dans notre nouveau système de paiement automatique, certains paiements peuvent avoir été prélevés plus d’une fois pour quelques clients, dont vous. <strong>La situation a été corrigée et les montants prélevés en trop ont été remboursés sur votre carte.</strong>"
|
||
}
|
||
},
|
||
{
|
||
"id": "u_content_text_3",
|
||
"type": "text",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "14px 28px 0",
|
||
"anchor": "",
|
||
"fontWeight": 400,
|
||
"fontSize": "15px",
|
||
"color": "#1e293b",
|
||
"textAlign": "left",
|
||
"lineHeight": "160%",
|
||
"linkStyle": {
|
||
"inherit": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_text_3",
|
||
"htmlClassNames": "u_content_text"
|
||
},
|
||
"text": "Nous nous excusons sincèrement pour ce désagrément. Selon l’émetteur de votre carte, un délai de quelques jours peut être nécessaire avant que le remboursement apparaisse sur votre relevé. Si vous remarquez quoi que ce soit d’inhabituel ou si vous avez une question, vous pouvez nous écrire à <a href=\"mailto:facturation@targo.ca\">facturation@targo.ca</a>."
|
||
}
|
||
},
|
||
{
|
||
"id": "u_content_text_4",
|
||
"type": "text",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "20px 28px 28px",
|
||
"anchor": "",
|
||
"fontWeight": 400,
|
||
"fontSize": "15px",
|
||
"color": "#1e293b",
|
||
"textAlign": "left",
|
||
"lineHeight": "160%",
|
||
"linkStyle": {
|
||
"inherit": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_text_4",
|
||
"htmlClassNames": "u_content_text"
|
||
},
|
||
"text": "Merci de votre compréhension,<br><strong>L’équipe Facturation — TARGO</strong>"
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"_meta": {
|
||
"htmlID": "u_column_2",
|
||
"htmlClassNames": "u_column"
|
||
},
|
||
"padding": "0px",
|
||
"border": {},
|
||
"borderRadius": "0px",
|
||
"backgroundColor": ""
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"columns": false,
|
||
"backgroundColor": "#ffffff",
|
||
"columnsBackgroundColor": "",
|
||
"backgroundImage": {
|
||
"url": "",
|
||
"fullWidth": true,
|
||
"repeat": "no-repeat",
|
||
"size": "custom",
|
||
"position": "center"
|
||
},
|
||
"padding": "0px",
|
||
"anchor": "",
|
||
"borderRadius": "",
|
||
"_meta": {
|
||
"htmlID": "u_row_2",
|
||
"htmlClassNames": "u_row"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"id": "u_row_3",
|
||
"cells": [
|
||
1
|
||
],
|
||
"columns": [
|
||
{
|
||
"id": "u_column_3",
|
||
"contents": [
|
||
{
|
||
"id": "u_content_text_5",
|
||
"type": "text",
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"containerPadding": "14px 28px",
|
||
"anchor": "",
|
||
"fontWeight": 400,
|
||
"fontSize": "12px",
|
||
"color": "#94a3b8",
|
||
"textAlign": "left",
|
||
"lineHeight": "160%",
|
||
"linkStyle": {
|
||
"inherit": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_content_text_5",
|
||
"htmlClassNames": "u_content_text"
|
||
},
|
||
"text": " "
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"_meta": {
|
||
"htmlID": "u_column_3",
|
||
"htmlClassNames": "u_column"
|
||
},
|
||
"padding": "0px",
|
||
"border": {},
|
||
"borderRadius": "0px",
|
||
"backgroundColor": ""
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"selectable": true,
|
||
"draggable": true,
|
||
"duplicatable": true,
|
||
"deletable": true,
|
||
"hideable": true,
|
||
"hideDesktop": false,
|
||
"displayCondition": null,
|
||
"columns": false,
|
||
"backgroundColor": "#f8fafc",
|
||
"columnsBackgroundColor": "",
|
||
"backgroundImage": {
|
||
"url": "",
|
||
"fullWidth": true,
|
||
"repeat": "no-repeat",
|
||
"size": "custom",
|
||
"position": "center"
|
||
},
|
||
"padding": "0px",
|
||
"anchor": "",
|
||
"borderRadius": "",
|
||
"_meta": {
|
||
"htmlID": "u_row_3",
|
||
"htmlClassNames": "u_row"
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"values": {
|
||
"popupPosition": "center",
|
||
"popupWidth": "600px",
|
||
"popupHeight": "auto",
|
||
"borderRadius": "10px",
|
||
"contentAlign": "center",
|
||
"contentVerticalAlign": "center",
|
||
"contentWidth": "600px",
|
||
"fontFamily": {
|
||
"label": "Plus Jakarta Sans",
|
||
"value": "'Plus Jakarta Sans', sans-serif",
|
||
"url": "https://fonts.googleapis.com/css?family=Plus+Jakarta+Sans:400,500,600,700"
|
||
},
|
||
"textColor": "#1e293b",
|
||
"popupBackgroundColor": "#ffffff",
|
||
"backgroundColor": "#f4f6f8",
|
||
"preheaderText": "Remboursement appliqué à votre compte — nos excuses.",
|
||
"linkStyle": {
|
||
"body": true,
|
||
"linkColor": "#2563eb",
|
||
"linkHoverColor": "#1d4ed8",
|
||
"linkUnderline": false,
|
||
"linkHoverUnderline": true
|
||
},
|
||
"_meta": {
|
||
"htmlID": "u_body",
|
||
"htmlClassNames": "u_body"
|
||
}
|
||
}
|
||
},
|
||
"schemaVersion": 16
|
||
} |