From 310724708f467ff889dda5c38c67389b86a21ba5 Mon Sep 17 00:00:00 2001 From: mrKamoo Date: Wed, 30 Sep 2026 16:27:32 +0200 Subject: [PATCH] 45 --- .dockerignore | 10 + .gitattributes | 3 + .gitignore | 8 + README.md | 91 + addin/assets/icon-128.png | Bin 0 -> 12487 bytes addin/assets/icon-16.png | Bin 0 -> 6409 bytes addin/assets/icon-32.png | Bin 0 -> 7239 bytes addin/assets/icon-64.png | Bin 0 -> 8845 bytes addin/assets/icon-80.png | Bin 0 -> 9875 bytes addin/manifest.xml | 161 + addin/package-lock.json | 5462 ++++++++++ addin/package.json | 29 + addin/src/launchevent/commands.html | 12 + addin/src/launchevent/launchevent.ts | 54 + addin/src/shared/api.ts | 42 + addin/src/shared/auth.ts | 65 + addin/src/shared/cache.ts | 36 + addin/src/shared/config.ts | 13 + addin/src/shared/office.ts | 83 + addin/src/taskpane/taskpane.html | 29 + addin/src/taskpane/taskpane.ts | 64 + addin/tsconfig.json | 14 + addin/webpack.config.js | 98 + backend/.editorconfig | 18 + backend/.env.example | 65 + backend/.gitattributes | 11 + backend/.gitignore | 27 + backend/.npmrc | 2 + backend/AGENTS.md | 47 + backend/CLAUDE.md | 47 + backend/README.md | 58 + .../app/Console/Commands/SyncDirectory.php | 45 + .../Controllers/Admin/AgentController.php | 61 + .../Admin/AssignmentController.php | 77 + .../Admin/Concerns/ScopedToTenant.php | 24 + .../Controllers/Admin/DashboardController.php | 30 + .../Http/Controllers/Admin/SyncController.php | 47 + .../Controllers/Admin/TemplateController.php | 180 + .../Controllers/Api/SignatureController.php | 36 + .../Controllers/Auth/EntraLoginController.php | 93 + backend/app/Http/Controllers/Controller.php | 8 + .../Controllers/Portal/PortalController.php | 25 + .../Middleware/AuthenticateEntraToken.php | 46 + backend/app/Http/Middleware/EnsureRole.php | 19 + .../Http/Middleware/RestrictAdminNetwork.php | 25 + backend/app/Models/Assignment.php | 14 + backend/app/Models/AuditLog.php | 31 + backend/app/Models/Campaign.php | 27 + backend/app/Models/DirectoryGroup.php | 24 + backend/app/Models/DirectoryUser.php | 33 + backend/app/Models/EditableField.php | 15 + backend/app/Models/SharedMailbox.php | 18 + backend/app/Models/Template.php | 38 + backend/app/Models/TemplateVersion.php | 14 + backend/app/Models/Tenant.php | 26 + backend/app/Models/User.php | 27 + backend/app/Models/UserOverride.php | 13 + backend/app/Models/UserPreference.php | 10 + backend/app/Providers/AppServiceProvider.php | 32 + .../app/Services/Auth/EntraTokenValidator.php | 77 + backend/app/Services/Graph/DirectorySync.php | 148 + backend/app/Services/Graph/GraphClient.php | 73 + backend/app/Signature/SignatureBuilder.php | 155 + backend/app/Signature/TemplateRenderer.php | 55 + backend/app/Signature/TemplateSanitizer.php | 52 + backend/app/Signature/TemplateSelector.php | 35 + backend/app/Signature/VariableMap.php | 46 + backend/artisan | 18 + backend/bootstrap/app.php | 25 + backend/bootstrap/cache/.gitignore | 2 + backend/bootstrap/providers.php | 7 + backend/composer.json | 89 + backend/composer.lock | 8893 +++++++++++++++++ backend/config/app.php | 126 + backend/config/auth.php | 117 + backend/config/cache.php | 136 + backend/config/database.php | 184 + backend/config/filesystems.php | 80 + backend/config/logging.php | 140 + backend/config/mail.php | 118 + backend/config/queue.php | 129 + backend/config/services.php | 35 + backend/config/session.php | 233 + backend/config/signature.php | 56 + backend/database/.gitignore | 1 + backend/database/factories/UserFactory.php | 45 + .../0001_01_01_000000_create_users_table.php | 49 + .../0001_01_01_000001_create_cache_table.php | 35 + .../0001_01_01_000002_create_jobs_table.php | 59 + ...6_10_01_000001_create_signature_tables.php | 208 + backend/database/seeders/DatabaseSeeder.php | 13 + backend/database/seeders/SignatureSeeder.php | 47 + .../seeders/templates/agents-full.html | 17 + .../seeders/templates/agents-short.html | 4 + backend/package.json | 19 + backend/phpunit.xml | 36 + backend/public/.htaccess | 25 + backend/public/favicon.ico | 0 backend/public/img/.gitkeep | 0 backend/public/index.php | 20 + backend/public/robots.txt | 2 + backend/resources/css/app.css | 9 + backend/resources/js/app.js | 1 + .../views/admin/agents/index.blade.php | 42 + .../views/admin/agents/show.blade.php | 33 + .../views/admin/assignments/index.blade.php | 79 + .../resources/views/admin/dashboard.blade.php | 55 + .../views/admin/templates/edit.blade.php | 231 + .../views/admin/templates/index.blade.php | 39 + backend/resources/views/layouts/app.blade.php | 84 + .../views/partials/signature-frame.blade.php | 3 + backend/resources/views/portal/home.blade.php | 13 + backend/resources/views/welcome.blade.php | 223 + backend/routes/api.php | 9 + backend/routes/console.php | 7 + backend/routes/web.php | 54 + backend/storage/app/.gitignore | 4 + backend/storage/app/private/.gitignore | 2 + backend/storage/app/public/.gitignore | 2 + backend/storage/framework/.gitignore | 10 + backend/storage/framework/cache/.gitignore | 3 + .../storage/framework/cache/data/.gitignore | 2 + backend/storage/framework/sessions/.gitignore | 2 + backend/storage/framework/testing/.gitignore | 2 + backend/storage/framework/views/.gitignore | 2 + backend/storage/logs/.gitignore | 2 + backend/tests/Feature/AdminSyncTest.php | 59 + backend/tests/Feature/AdminTemplatesTest.php | 135 + backend/tests/Feature/ExampleTest.php | 18 + backend/tests/Feature/SignatureApiTest.php | 118 + backend/tests/TestCase.php | 10 + backend/tests/Unit/ExampleTest.php | 16 + backend/tests/Unit/TemplateRendererTest.php | 54 + backend/tests/Unit/TemplateSanitizerTest.php | 42 + backend/tests/Unit/TemplateSelectorTest.php | 31 + backend/variables-signature.example | 41 + backend/vite.config.js | 24 + deploy/deploy.sh | 227 + docker-compose.yml | 76 + docker/certs/README.txt | 1 + docker/nginx/signature.conf | 70 + docker/php/Dockerfile | 35 + docker/php/entrypoint.sh | 22 + docker/php/php.ini | 8 + docs/01-entra-app-registrations.md | 82 + docs/02-deploiement.md | 100 + install-backend.ps1 | 49 + 147 files changed, 21327 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 addin/assets/icon-128.png create mode 100644 addin/assets/icon-16.png create mode 100644 addin/assets/icon-32.png create mode 100644 addin/assets/icon-64.png create mode 100644 addin/assets/icon-80.png create mode 100644 addin/manifest.xml create mode 100644 addin/package-lock.json create mode 100644 addin/package.json create mode 100644 addin/src/launchevent/commands.html create mode 100644 addin/src/launchevent/launchevent.ts create mode 100644 addin/src/shared/api.ts create mode 100644 addin/src/shared/auth.ts create mode 100644 addin/src/shared/cache.ts create mode 100644 addin/src/shared/config.ts create mode 100644 addin/src/shared/office.ts create mode 100644 addin/src/taskpane/taskpane.html create mode 100644 addin/src/taskpane/taskpane.ts create mode 100644 addin/tsconfig.json create mode 100644 addin/webpack.config.js create mode 100644 backend/.editorconfig create mode 100644 backend/.env.example create mode 100644 backend/.gitattributes create mode 100644 backend/.gitignore create mode 100644 backend/.npmrc create mode 100644 backend/AGENTS.md create mode 100644 backend/CLAUDE.md create mode 100644 backend/README.md create mode 100644 backend/app/Console/Commands/SyncDirectory.php create mode 100644 backend/app/Http/Controllers/Admin/AgentController.php create mode 100644 backend/app/Http/Controllers/Admin/AssignmentController.php create mode 100644 backend/app/Http/Controllers/Admin/Concerns/ScopedToTenant.php create mode 100644 backend/app/Http/Controllers/Admin/DashboardController.php create mode 100644 backend/app/Http/Controllers/Admin/SyncController.php create mode 100644 backend/app/Http/Controllers/Admin/TemplateController.php create mode 100644 backend/app/Http/Controllers/Api/SignatureController.php create mode 100644 backend/app/Http/Controllers/Auth/EntraLoginController.php create mode 100644 backend/app/Http/Controllers/Controller.php create mode 100644 backend/app/Http/Controllers/Portal/PortalController.php create mode 100644 backend/app/Http/Middleware/AuthenticateEntraToken.php create mode 100644 backend/app/Http/Middleware/EnsureRole.php create mode 100644 backend/app/Http/Middleware/RestrictAdminNetwork.php create mode 100644 backend/app/Models/Assignment.php create mode 100644 backend/app/Models/AuditLog.php create mode 100644 backend/app/Models/Campaign.php create mode 100644 backend/app/Models/DirectoryGroup.php create mode 100644 backend/app/Models/DirectoryUser.php create mode 100644 backend/app/Models/EditableField.php create mode 100644 backend/app/Models/SharedMailbox.php create mode 100644 backend/app/Models/Template.php create mode 100644 backend/app/Models/TemplateVersion.php create mode 100644 backend/app/Models/Tenant.php create mode 100644 backend/app/Models/User.php create mode 100644 backend/app/Models/UserOverride.php create mode 100644 backend/app/Models/UserPreference.php create mode 100644 backend/app/Providers/AppServiceProvider.php create mode 100644 backend/app/Services/Auth/EntraTokenValidator.php create mode 100644 backend/app/Services/Graph/DirectorySync.php create mode 100644 backend/app/Services/Graph/GraphClient.php create mode 100644 backend/app/Signature/SignatureBuilder.php create mode 100644 backend/app/Signature/TemplateRenderer.php create mode 100644 backend/app/Signature/TemplateSanitizer.php create mode 100644 backend/app/Signature/TemplateSelector.php create mode 100644 backend/app/Signature/VariableMap.php create mode 100644 backend/artisan create mode 100644 backend/bootstrap/app.php create mode 100644 backend/bootstrap/cache/.gitignore create mode 100644 backend/bootstrap/providers.php create mode 100644 backend/composer.json create mode 100644 backend/composer.lock create mode 100644 backend/config/app.php create mode 100644 backend/config/auth.php create mode 100644 backend/config/cache.php create mode 100644 backend/config/database.php create mode 100644 backend/config/filesystems.php create mode 100644 backend/config/logging.php create mode 100644 backend/config/mail.php create mode 100644 backend/config/queue.php create mode 100644 backend/config/services.php create mode 100644 backend/config/session.php create mode 100644 backend/config/signature.php create mode 100644 backend/database/.gitignore create mode 100644 backend/database/factories/UserFactory.php create mode 100644 backend/database/migrations/0001_01_01_000000_create_users_table.php create mode 100644 backend/database/migrations/0001_01_01_000001_create_cache_table.php create mode 100644 backend/database/migrations/0001_01_01_000002_create_jobs_table.php create mode 100644 backend/database/migrations/2026_10_01_000001_create_signature_tables.php create mode 100644 backend/database/seeders/DatabaseSeeder.php create mode 100644 backend/database/seeders/SignatureSeeder.php create mode 100644 backend/database/seeders/templates/agents-full.html create mode 100644 backend/database/seeders/templates/agents-short.html create mode 100644 backend/package.json create mode 100644 backend/phpunit.xml create mode 100644 backend/public/.htaccess create mode 100644 backend/public/favicon.ico create mode 100644 backend/public/img/.gitkeep create mode 100644 backend/public/index.php create mode 100644 backend/public/robots.txt create mode 100644 backend/resources/css/app.css create mode 100644 backend/resources/js/app.js create mode 100644 backend/resources/views/admin/agents/index.blade.php create mode 100644 backend/resources/views/admin/agents/show.blade.php create mode 100644 backend/resources/views/admin/assignments/index.blade.php create mode 100644 backend/resources/views/admin/dashboard.blade.php create mode 100644 backend/resources/views/admin/templates/edit.blade.php create mode 100644 backend/resources/views/admin/templates/index.blade.php create mode 100644 backend/resources/views/layouts/app.blade.php create mode 100644 backend/resources/views/partials/signature-frame.blade.php create mode 100644 backend/resources/views/portal/home.blade.php create mode 100644 backend/resources/views/welcome.blade.php create mode 100644 backend/routes/api.php create mode 100644 backend/routes/console.php create mode 100644 backend/routes/web.php create mode 100644 backend/storage/app/.gitignore create mode 100644 backend/storage/app/private/.gitignore create mode 100644 backend/storage/app/public/.gitignore create mode 100644 backend/storage/framework/.gitignore create mode 100644 backend/storage/framework/cache/.gitignore create mode 100644 backend/storage/framework/cache/data/.gitignore create mode 100644 backend/storage/framework/sessions/.gitignore create mode 100644 backend/storage/framework/testing/.gitignore create mode 100644 backend/storage/framework/views/.gitignore create mode 100644 backend/storage/logs/.gitignore create mode 100644 backend/tests/Feature/AdminSyncTest.php create mode 100644 backend/tests/Feature/AdminTemplatesTest.php create mode 100644 backend/tests/Feature/ExampleTest.php create mode 100644 backend/tests/Feature/SignatureApiTest.php create mode 100644 backend/tests/TestCase.php create mode 100644 backend/tests/Unit/ExampleTest.php create mode 100644 backend/tests/Unit/TemplateRendererTest.php create mode 100644 backend/tests/Unit/TemplateSanitizerTest.php create mode 100644 backend/tests/Unit/TemplateSelectorTest.php create mode 100644 backend/variables-signature.example create mode 100644 backend/vite.config.js create mode 100644 deploy/deploy.sh create mode 100644 docker-compose.yml create mode 100644 docker/certs/README.txt create mode 100644 docker/nginx/signature.conf create mode 100644 docker/php/Dockerfile create mode 100644 docker/php/entrypoint.sh create mode 100644 docker/php/php.ini create mode 100644 docs/01-entra-app-registrations.md create mode 100644 docs/02-deploiement.md create mode 100644 install-backend.ps1 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..16ab05a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +**/node_modules +**/.git +addin/dist +backend/vendor +backend/.env +backend/storage/logs/* +backend/storage/framework/cache/* +backend/storage/framework/sessions/* +backend/storage/framework/views/* +docker/certs diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..43a4087 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.sh text eol=lf +docker/** text eol=lf +*.png binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6532fa7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +addin/dist/ +addin/.env +backend/vendor/ +backend/.env +docker/certs/* +!docker/certs/README.txt +deploy.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..15440ee --- /dev/null +++ b/README.md @@ -0,0 +1,91 @@ +# Signatures CABM + +Gestion centralisée des signatures email des agents de la CA Béziers Méditerranée : +un **add-in Outlook** insère automatiquement la signature (OWA, nouvel Outlook, Outlook mobile), +un **back-office Laravel** gère templates, affectations par groupes AD, campagnes et portail agent. + +Architecture et lotissement : document « Signatures email CABM — Architecture et lotissement ». + +## Structure + +``` +AddinOutlook/ +├── addin/ Add-in Outlook (TypeScript, manifeste XML, NAA) +│ ├── manifest.xml Modèle ; la version finale est générée dans dist/ au build +│ └── src/ +│ ├── launchevent/ Gestionnaires OnNewMessageCompose / OnNewAppointmentOrganizer / OnMessageFromChanged +│ ├── taskpane/ Volet « Ma signature » (aperçu, réinsertion, lien portail) +│ └── shared/ Authentification NAA, appel API, cache roamingSettings +├── backend/ Fichiers du back-office, à fusionner avec un Laravel neuf (install-backend.ps1) +│ ├── app/Signature/ Rendu des templates, choix du template, calcul de la signature +│ ├── app/Services/ Client Graph, synchro annuaire, validation des jetons Entra +│ ├── database/ Migration du modèle de données, seeders, templates d'exemple +│ └── tests/ Tests unitaires et fonctionnels (php artisan test) +├── docker/ Image PHP-FPM, Nginx (certificat wildcard), entrypoint +├── docker-compose.yml app + scheduler + nginx + mariadb +├── docs/ +│ ├── 01-entra-app-registrations.md Inscriptions Entra, groupes AD, déploiement Integrated Apps +│ └── 02-deploiement.md VM DMZ, flux Stormshield, exploitation +└── install-backend.ps1 Installation du back-office sur le poste de dev (Laragon) +``` + +## Démarrage sur le poste de dev (Laragon) + +1. Créer les deux inscriptions Entra et les groupes AD : `docs/01-entra-app-registrations.md`. +2. Back-office, dans le terminal Laragon : + ```powershell + cd C:\laragon\www\AddinOutlook + powershell -ExecutionPolicy Bypass -File .\install-backend.ps1 + ``` + Le script crée un Laravel neuf, y ajoute nos fichiers, installe `firebase/php-jwt`, + `laravel/socialite`, `socialiteproviders/microsoft-azure`, prépare `.env` et lance les tests. +3. Compléter `backend\.env` (base MySQL Laragon, identifiants Entra), puis : + ```powershell + cd backend + php artisan migrate --seed + php artisan signature:sync --full + php artisan serve + ``` + Pour un hôte virtuel Laragon, faire pointer la racine web sur `backend\public`. +4. Add-in : + ```powershell + cd ..\addin + copy .env.example .env # compléter + npm install + npm run build # produit dist\ (dont dist\manifest.xml) + npm run validate # validation du manifeste par le service Microsoft + ``` + +L'add-in doit être servi en HTTPS avec un certificat de confiance : les tests se font sur la VM DMZ +(`docs/02-deploiement.md`) avec un chargement manuel du manifeste dans Outlook web. + +## API + +`GET /api/v1/signature?context=new|reply|forward|appointment&mailbox=` +En-tête `Authorization: Bearer ` → `{ html, variant, template, generated_at }`. + +- Template : groupe `signature_mail_*` de plus haute priorité, sinon template par défaut. +- Réponse / transfert : variante choisie par l'agent (courte, complète, aucune), défaut `short`. +- Boîte partagée déclarée : son template, avec ou sans le nom de l'agent selon le réglage de la boîte. +- Bannière : campagne active ciblant un des groupes de l'agent (ou tous), insérée par `{{{banniere}}}`. + +## Syntaxe des templates + +| Syntaxe | Effet | +| --- | --- | +| `{{prenom}}` | Valeur échappée | +| `{{#if mobile}}Mob. {{mobile}}
{{/if}}` | Ligne masquée si le champ est vide | +| `{{#unless x}}…{{/unless}}` | Bloc affiché si le champ est vide | +| `{{{banniere}}}` | Bannière de campagne (HTML généré par le serveur) | + +Variables : `prenom`, `nom`, `nom_complet`, `fonction`, `service`, `organisation`, `bureau`, `telephone`, +`mobile`, `email`, `adresse`, `code_postal`, `ville`, `site_url`, `banniere`, et pour une boîte partagée +`boite_nom`, `boite_email`. + +## Contenu du lot 0 et suite + +Livré : socle complet (modèle de données, synchro Graph delta toutes les 15 min, API signature, +validation des jetons, add-in avec cache de secours, SSO, rôles par groupes AD, tableau de bord, portail en aperçu). + +Lots suivants : écrans d'édition des templates (HTML + éditeur visuel), affectations et priorités, +boîtes partagées, campagnes, champs modifiables par l'agent et préférence de réponse, journal d'audit consultable. diff --git a/addin/assets/icon-128.png b/addin/assets/icon-128.png new file mode 100644 index 0000000000000000000000000000000000000000..742fa10077e43189fe1eb5397b3333b63102b16a GIT binary patch literal 12487 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 literal 0 HcmV?d00001 diff --git a/addin/assets/icon-32.png b/addin/assets/icon-32.png new file mode 100644 index 0000000000000000000000000000000000000000..8cf6ae03afc878ecfccf3fee88fc0f2187ddf454 GIT binary patch literal 7239 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 WC$&m6JdD==mzWz{VICQ}hW!_X6CG3l literal 0 HcmV?d00001 diff --git a/addin/assets/icon-80.png b/addin/assets/icon-80.png new file mode 100644 index 0000000000000000000000000000000000000000..742b2c079d71de32db88cbdf3902f73064df0aa0 GIT binary patch literal 9875 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 zATezA + + + 8102c04b-a358-496c-99f3-70fac75e23b5 + 0.1.0.0 + Communauté d'agglomération Béziers Méditerranée + fr-FR + + + + + + + {{ORIGIN}} + https://login.microsoftonline.com + + + + + + + + + + +
+ + + +
+
+ ReadWriteItem + + + + + false + + + + + + + + + + + + + + + + + + + + true + + + + + + +