0.13.14 : fix media uploads, move plugin secrets to env vars
Build release Docker image / Build Docker Images (push) Successful in 7m54s

Tous les uploads échouaient depuis mai 2026 sur « Credential access key
has length 5, should be 32 ».

config/env/production/plugins.ts surchargeait l'upload avec l'ancien
MinIO auto-hébergé (accessKeyId "admin", 5 caractères, endpoint
container.harmonylab.ovh aujourd'hui injoignable). Strapi fusionnant les
surcharges d'environnement en profondeur, la config effective en prod
n'était ni l'une ni l'autre : endpoint R2 hérité de config/plugins.ts,
mais identifiants MinIO, le provider lisant s3Options.credentials en
priorité sur les options à plat.

- surcharge production supprimée : une seule config plugins, les
  différences d'environnement passent par les variables d'environnement
- upload en forme s3Options attendue par @strapi/provider-upload-aws-s3 5.x
  (à plat, le provider n'accepte plus qu'au prix d'une dépréciation)
- secrets R2 et SMTP sortis du fichier vers env(), .env.example à jour
- CSP de production : les médias étaient autorisés depuis
  container.harmonylab.ovh et 192.168.0.211:9000, jamais depuis le domaine
  R2 — l'hôte est désormais dérivé de R2_PUBLIC_URL
- la surcharge production des middlewares réduisait strapi::body à sa forme
  par défaut, perdant includeUnparsed nécessaire au webhook Stripe

⚠️ Déploiement : poser R2_* et SMTP_PASSWORD dans Dokploy AVANT de
déployer. Les clés historiques restent dans l'historique git : rotation
R2 et ZeptoMail à faire.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 18:44:58 +02:00
parent ca66bec45b
commit 8e672633dc
6 changed files with 99 additions and 87 deletions
+21 -18
View File
@@ -1,7 +1,19 @@
/**
* Surcharge production : uniquement la politique CSP (les médias sont servis
* par un domaine externe). Le reste de la pile reprend `config/middlewares.ts`
* à l'identique — y compris `includeUnparsed`, indispensable au webhook
* Stripe, que la fusion d'environnement écraserait si on laissait ici un
* simple `"strapi::body"`.
*/
const mediaHost = process.env.R2_PUBLIC_URL
? new URL(process.env.R2_PUBLIC_URL).host
: "container.choralsync.com";
const mediaSources = ["'self'", "data:", "blob:", "market-assets.strapi.io", mediaHost];
export default [
"strapi::logger",
"strapi::errors",
//'strapi::security',
{
name: "strapi::security",
config: {
@@ -9,22 +21,8 @@ export default [
useDefaults: true,
directives: {
"connect-src": ["'self'", "https:"],
"img-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
"192.168.0.211:9000",
"container.harmonylab.ovh",
],
"media-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
"192.168.0.211:9000",
"container.harmonylab.ovh",
],
"img-src": mediaSources,
"media-src": mediaSources,
upgradeInsecureRequests: null,
},
},
@@ -33,7 +31,12 @@ export default [
"strapi::cors",
"strapi::poweredBy",
"strapi::query",
"strapi::body",
{
name: "strapi::body",
config: {
includeUnparsed: true, // INDISPENSABLE pour les webhooks
},
},
"strapi::session",
"strapi::favicon",
"strapi::public",
-43
View File
@@ -1,43 +0,0 @@
export default () => ({
email: {
config: {
provider: "nodemailer",
providerOptions: {
host: "smtp.zeptomail.eu",
port: 587,
auth: {
user: "emailapikey",
pass: "yA6KbHsJ4lrywWtTFUc+0pSC94lm/aE/2nzks3i2fpZ1LYXp3qE71RBvd4O4c2CLjdfT5a9UbIkVJoCwvIpbfpczPIBXJpTGTuv4P2uV48xh8ciEYNYjhJivALIWFqVOeBsnDyo4QfEjWA==",
},
debug: true,
logger: true,
},
settings: {
defaultFrom: "ChoralSync <noreply@choralsync.com>",
defaultReplyTo: "contact@choralsync.com",
},
},
},
upload: {
config: {
provider: "aws-s3",
providerOptions: {
//baseUrl: "http://192.168.0.211:9000/harmony",
baseUrl: "https://container.harmonylab.ovh/harmony",
s3Options: {
credentials: {
accessKeyId: "admin",
secretAccessKey: "Apslxnap12bn23",
},
//endpoint: "http://192.168.0.211:9000",
endpoint: "https://container.harmonylab.ovh",
region: "eu-west-3",
forcePathStyle: true,
params: {
Bucket: "harmony",
},
},
},
},
},
});