diff --git a/docker/dinum-frontend/Dockerfile b/docker/dinum-frontend/Dockerfile index 85af99fc..6a6a58b3 100644 --- a/docker/dinum-frontend/Dockerfile +++ b/docker/dinum-frontend/Dockerfile @@ -38,6 +38,20 @@ COPY ./docker/dinum-frontend/assets/ \ COPY ./docker/dinum-frontend/fonts/ \ ./dist/assets/fonts/ +# ---- Outlook add-in builder image ---- +FROM node:20-alpine AS outlook-addin-builder + +WORKDIR /home/outlook-addin + +COPY ./src/addins/outlook-addin/package.json ./package.json +COPY ./src/addins/outlook-addin/package-lock.json ./package-lock.json + +RUN npm ci + +COPY ./src/addins/outlook-addin/ . + +RUN npx webpack --mode production + # ---- Front-end image ---- FROM nginxinc/nginx-unprivileged:alpine3.21 AS frontend-production @@ -59,6 +73,10 @@ COPY --from=meet-builder \ /home/frontend/dist \ /usr/share/nginx/html +COPY --from=outlook-addin-builder \ + /home/outlook-addin/dist \ + /usr/share/nginx/html/outlook-addin + COPY ./src/frontend/default.conf /etc/nginx/conf.d COPY ./docker/files/usr/local/bin/entrypoint /usr/local/bin/entrypoint diff --git a/src/addins/outlook-addin/package-lock.json b/src/addins/outlook-addin/package-lock.json index 24d5f6b3..ce03e686 100644 --- a/src/addins/outlook-addin/package-lock.json +++ b/src/addins/outlook-addin/package-lock.json @@ -23,6 +23,7 @@ "eslint-plugin-office-addins": "^4.0.3", "file-loader": "^6.2.0", "html-loader": "^5.0.0", + "html-webpack-inject-attributes-plugin": "^1.0.6", "html-webpack-plugin": "^5.6.0", "office-addin-cli": "^2.0.3", "office-addin-debugging": "^6.0.3", @@ -9063,6 +9064,18 @@ "node": "^14.13.1 || >=16.0.0" } }, + "node_modules/html-webpack-inject-attributes-plugin": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/html-webpack-inject-attributes-plugin/-/html-webpack-inject-attributes-plugin-1.0.6.tgz", + "integrity": "sha512-ZsXpT8kPQwEFuJOnaNpy2esxlQtvPmLxXiWP1rsLV9HNKXU3ltyWGFUqxgEzQr7sMtkm3eY0NwqeiNUBWfZZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.assign": "^4.2.0", + "lodash.foreach": "^4.5.0", + "safe-require": "^1.0.3" + } + }, "node_modules/html-webpack-plugin": { "version": "5.6.6", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz", @@ -10822,6 +10835,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10829,6 +10849,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -13645,6 +13672,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-require": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/safe-require/-/safe-require-1.0.4.tgz", + "integrity": "sha512-1elAbSH1u7HVMfbuqktLWAN0wMOeT+FnJVqMhBgEJLvL95m+KT433tiJdGMV1e3TstQXRt1YrKQDRBu0Kpk4WA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "Fair" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", diff --git a/src/addins/outlook-addin/package.json b/src/addins/outlook-addin/package.json index cac619f4..3f6e8e84 100644 --- a/src/addins/outlook-addin/package.json +++ b/src/addins/outlook-addin/package.json @@ -40,6 +40,7 @@ "eslint-plugin-office-addins": "^4.0.3", "file-loader": "^6.2.0", "html-loader": "^5.0.0", + "html-webpack-inject-attributes-plugin": "^1.0.6", "html-webpack-plugin": "^5.6.0", "office-addin-cli": "^2.0.3", "office-addin-debugging": "^6.0.3", diff --git a/src/addins/outlook-addin/src/commands/commands.html b/src/addins/outlook-addin/src/commands/commands.html index e72f2f6c..c9c39683 100644 --- a/src/addins/outlook-addin/src/commands/commands.html +++ b/src/addins/outlook-addin/src/commands/commands.html @@ -3,7 +3,7 @@ - + diff --git a/src/addins/outlook-addin/src/taskpane/taskpane.html b/src/addins/outlook-addin/src/taskpane/taskpane.html index d26ea729..1b246434 100644 --- a/src/addins/outlook-addin/src/taskpane/taskpane.html +++ b/src/addins/outlook-addin/src/taskpane/taskpane.html @@ -6,7 +6,7 @@ Visio - +
Veuillez charger le complément.
diff --git a/src/addins/outlook-addin/webpack.config.js b/src/addins/outlook-addin/webpack.config.js index ece751bb..3fac9f60 100644 --- a/src/addins/outlook-addin/webpack.config.js +++ b/src/addins/outlook-addin/webpack.config.js @@ -3,6 +3,7 @@ const devCerts = require("office-addin-dev-certs"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); +const htmlWebpackInjectAttributesPlugin = require("html-webpack-inject-attributes-plugin"); const urlDev = "https://localhost:3000/"; const urlProd = "https://meet.127.0.0.1.nip.io/outlook-addin/"; @@ -55,6 +56,10 @@ module.exports = async (env, options) => { filename: "taskpane.html", template: "./src/taskpane/taskpane.html", chunks: ["polyfill", "taskpane"], + scriptLoading: "defer", + attributes: { + nonce: "NONCE_PLACEHOLDER", + }, }), new CopyWebpackPlugin({ patterns: [ @@ -79,7 +84,12 @@ module.exports = async (env, options) => { filename: "commands.html", template: "./src/commands/commands.html", chunks: ["polyfill", "commands"], + scriptLoading: "defer", + attributes: { + nonce: "NONCE_PLACEHOLDER", + }, }), + new htmlWebpackInjectAttributesPlugin(), ], devServer: { headers: { @@ -87,7 +97,10 @@ module.exports = async (env, options) => { }, server: { type: "https", - options: env.WEBPACK_BUILD || options.https !== undefined ? options.https : await getHttpsOptions(), + options: + env.WEBPACK_BUILD || options.https !== undefined + ? options.https + : await getHttpsOptions(), }, port: process.env.npm_package_config_dev_server_port || 3000, }, diff --git a/src/frontend/default.conf b/src/frontend/default.conf index 51889be8..aba44623 100644 --- a/src/frontend/default.conf +++ b/src/frontend/default.conf @@ -11,10 +11,39 @@ server { add_header Content-Disposition "attachment; filename=windows-app-web-link"; } + + # Manifest — fetched, never iframed + location = /outlook-addin/manifest.xml { + alias /usr/share/nginx/html/outlook-addin/manifest.xml; + + add_header Access-Control-Allow-Origin "*"; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header X-Frame-Options "DENY"; + add_header Content-Security-Policy "frame-ancestors 'none'"; + } + location ~ ^/outlook-addin(/.*)?$ { alias /usr/share/nginx/html/outlook-addin$1; add_header Access-Control-Allow-Origin "*"; add_header Cache-Control "no-cache, no-store, must-revalidate"; + + set $ms_domains "https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com"; + + set $nonce $request_id; + + set $csp "upgrade-insecure-requests; "; + set $csp "${csp}frame-ancestors ${ms_domains}; "; + set $csp "${csp}script-src 'nonce-${nonce}' 'strict-dynamic' ${ms_domains} 'self'; "; + set $csp "${csp}connect-src 'self' 'strict-dynamic' ${ms_domains}; "; + set $csp "${csp}frame-src 'none'; "; + set $csp "${csp}object-src 'none'; "; + set $csp "${csp}base-uri 'none'; "; + + add_header Content-Security-Policy $csp; + + sub_filter 'NONCE_PLACEHOLDER' $nonce; + sub_filter_once off; + sub_filter_types text/html; } # Serve static files with caching