readme aktualisiert
This commit is contained in:
parent
6f59eadf2a
commit
227b4cd194
565
README.md
565
README.md
|
|
@ -1,12 +1,253 @@
|
||||||
# flarum-msteams-webhook
|
# flarum-msteams-webhook
|
||||||
|
|
||||||
Diese Version enthält:
|
Flarum-Erweiterung zur Spiegelung ausgewählter Flarum-Benachrichtigungen in den **Microsoft Teams Activity Feed**.
|
||||||
|
|
||||||
- rudimentäres Admin-UI für Flarum 1.x
|
Die Erweiterung ergänzt Flarum um einen eigenen Benachrichtigungskanal namens **Microsoft Teams**. Benutzer können diesen Kanal in ihren persönlichen Benachrichtigungseinstellungen aktivieren. Neue Aktivitäten – beispielsweise Antworten in gefolgten Diskussionen oder Erwähnungen – werden anschließend über Microsoft Graph an den Teams Activity Feed des jeweiligen Benutzers gesendet.
|
||||||
- User Settings werden angepasst, so dass man unten MS Teams auswählen kann!
|
|
||||||
- Test-Command `php flarum teams:test-user <flarumUserId>`
|
|
||||||
|
|
||||||
## Build des Admin-Frontends
|
Beim Öffnen einer Teams-Benachrichtigung erscheint eine schlanke Zwischenansicht im persönlichen Teams-Tab. Diese enthält einen Link zur zugehörigen Flarum-Diskussion beziehungsweise direkt zum konkreten Beitrag. Das eigentliche Forum muss dadurch nicht in Microsoft Teams eingebettet werden und kann weiterhin mit restriktiven Frame-Sicherheitsheadern geschützt bleiben.
|
||||||
|
|
||||||
|
> **Projektstatus:** Interne Erweiterung für Flarum 1.8. Vor einem produktiven Einsatz sollten Konfiguration, Berechtigungen, Logging und Fehlerbehandlung an die jeweilige Umgebung angepasst und getestet werden.
|
||||||
|
|
||||||
|
## Funktionsumfang
|
||||||
|
|
||||||
|
- eigener Flarum-Benachrichtigungskanal `teams`
|
||||||
|
- rudimentäres Admin-UI zur Konfiguration der Microsoft-Graph-Anbindung
|
||||||
|
- Erweiterung der persönlichen Flarum-Benachrichtigungseinstellungen um Microsoft Teams
|
||||||
|
- asynchroner Versand über einen dedizierten Queue-Job
|
||||||
|
- Auflösung des Microsoft-Graph-Zielbenutzers über E-Mail-Adresse, UPN oder eine Benutzerpräferenz
|
||||||
|
- Abruf eines App-only Access Tokens über Microsoft Entra ID
|
||||||
|
- Versand von Activity-Feed-Benachrichtigungen über Microsoft Graph
|
||||||
|
- Vorschautext mit auslösendem Benutzer und Diskussionstitel
|
||||||
|
- Teams Deep Link zu einem persönlichen Teams-Tab
|
||||||
|
- Übergabe der konkreten Flarum-Ziel-URL über `context.subEntityId`
|
||||||
|
- Auslesen des Ziels im Teams-Tab über TeamsJS v2 und `context.page.subPageId`
|
||||||
|
- sichere Zwischenansicht mit validiertem Link zur Diskussion oder zum Beitrag
|
||||||
|
- Test-Command für einzelne Flarum-Benutzer
|
||||||
|
|
||||||
|
## Unterstützte Benachrichtigungstypen
|
||||||
|
|
||||||
|
Die Erweiterung enthält Unterstützung beziehungsweise Textvorlagen für folgende Flarum-Typen:
|
||||||
|
|
||||||
|
- `newPost` – neue Antwort in einer gefolgten Diskussion
|
||||||
|
- `postMentioned` – Erwähnung in einem Beitrag
|
||||||
|
- `userMentioned` – Benutzererwähnung
|
||||||
|
- `postLiked` – eigener Beitrag wurde mit „Gefällt mir“ markiert
|
||||||
|
- `discussionRenamed` – Diskussion wurde umbenannt
|
||||||
|
- `teamsTest` – interne Testbenachrichtigung des CLI-Commands
|
||||||
|
|
||||||
|
Welche Typen tatsächlich in den persönlichen Einstellungen angeboten oder standardmäßig aktiviert werden, wird durch die registrierten Flarum-Blueprints und die Frontend-Erweiterung bestimmt.
|
||||||
|
|
||||||
|
## Systemvoraussetzungen
|
||||||
|
|
||||||
|
- PHP 8.1 oder neuer
|
||||||
|
- Flarum 1.8
|
||||||
|
- Composer
|
||||||
|
- Node.js und npm zum Bauen des Flarum-Frontends
|
||||||
|
- ein funktionierender Flarum-Queue-Worker
|
||||||
|
- öffentlich beziehungsweise für Microsoft Teams erreichbare HTTPS-URL
|
||||||
|
- Microsoft-Entra-App-Registrierung mit den erforderlichen Microsoft-Graph-Berechtigungen
|
||||||
|
- installierte beziehungsweise im Mandanten veröffentlichte Microsoft-Teams-App
|
||||||
|
|
||||||
|
Relevante Composer-Abhängigkeiten:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"php": "^8.1",
|
||||||
|
"flarum/core": "^1.8",
|
||||||
|
"guzzlehttp/guzzle": "^7.8"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architektur und Ablauf
|
||||||
|
|
||||||
|
Der Versand läuft vereinfacht über folgende Komponenten:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Flarum Notification Blueprint
|
||||||
|
-> TeamsNotificationDriver
|
||||||
|
-> SendTeamsActivityNotificationJob
|
||||||
|
-> TeamsActivityNotifier
|
||||||
|
-> NotificationPayloadFactory
|
||||||
|
-> Microsoft Graph sendActivityNotification
|
||||||
|
-> Microsoft Teams Activity Feed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notification Driver
|
||||||
|
|
||||||
|
`TeamsNotificationDriver` ist in `extend.php` als Flarum Notification Driver registriert:
|
||||||
|
|
||||||
|
```php
|
||||||
|
(new Extend\Notification())
|
||||||
|
->driver('teams', TeamsNotificationDriver::class, []),
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Driver prüft die Benachrichtigungseinstellungen der Empfänger und legt den Versand als `SendTeamsActivityNotificationJob` in der Queue `teams` ab.
|
||||||
|
|
||||||
|
### Queue-Job
|
||||||
|
|
||||||
|
`SendTeamsActivityNotificationJob` führt den eigentlichen Versand außerhalb des Web-Requests aus. Der Job besitzt Wiederholungs- und Backoff-Einstellungen, damit vorübergehende Graph- oder Netzwerkfehler nicht sofort zum endgültigen Verlust einer Nachricht führen.
|
||||||
|
|
||||||
|
Nach Änderungen am PHP-Code müssen lang laufende Queue-Worker neu gestartet werden, da sie andernfalls weiterhin bereits geladene Klassen verwenden können.
|
||||||
|
|
||||||
|
### Token Provider
|
||||||
|
|
||||||
|
`GraphTokenProvider` ruft über den OAuth-2.0-Client-Credentials-Flow ein App-only Access Token bei Microsoft Entra ID ab. Tenant-ID, Client-ID und Client Secret werden aus den Flarum-Einstellungen gelesen.
|
||||||
|
|
||||||
|
Secrets dürfen weder in das Git-Repository eingecheckt noch in Logdateien geschrieben werden.
|
||||||
|
|
||||||
|
### Zielauflösung
|
||||||
|
|
||||||
|
`TargetResolver` ordnet einen Flarum-Benutzer einem Microsoft-Graph-Benutzer zu. Unterstützt werden – abhängig von der Admin-Konfiguration – unter anderem:
|
||||||
|
|
||||||
|
- Flarum-E-Mail-Adresse
|
||||||
|
- Microsoft Entra User Principal Name (UPN)
|
||||||
|
- benutzerdefinierte Flarum-Präferenz
|
||||||
|
|
||||||
|
Der aufgelöste Wert wird für den Graph-Endpunkt verwendet:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST https://graph.microsoft.com/v1.0/users/{target}/teamwork/sendActivityNotification
|
||||||
|
```
|
||||||
|
|
||||||
|
### Payload-Erzeugung
|
||||||
|
|
||||||
|
`NotificationPayloadFactory` erstellt den Request-Body für den Microsoft Teams Activity Feed. Der Payload enthält unter anderem:
|
||||||
|
|
||||||
|
- `topic.source`
|
||||||
|
- `topic.value`
|
||||||
|
- `topic.webUrl`
|
||||||
|
- `activityType`
|
||||||
|
- `previewText`
|
||||||
|
- `templateParameters`
|
||||||
|
|
||||||
|
Aktuell wird `systemDefault` als Activity Type verwendet. Dadurch ist kein eigener Activity Type im Teams-Manifest erforderlich.
|
||||||
|
|
||||||
|
Für Discussion- und Post-Subjects wird eine passende Ziel-URL erzeugt:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://forum.example/d/{discussionId}
|
||||||
|
https://forum.example/d/{discussionId}/{postNumber}
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Ziel-URL wird nicht direkt im Teams-Frame geladen. Stattdessen wird sie im Deep Link als `context.subEntityId` an den persönlichen Teams-Tab übergeben.
|
||||||
|
|
||||||
|
## Zwischenansicht im Teams-Tab
|
||||||
|
|
||||||
|
Die Teams-App lädt als Personal Tab eine statische Seite, beispielsweise:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://forum.example/static/flarum-notify-v2.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Seite bindet TeamsJS ein und liest den Deep-Link-Kontext aus:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
await window.microsoftTeams.app.initialize();
|
||||||
|
const context = await window.microsoftTeams.app.getContext();
|
||||||
|
const target = context.page.subPageId;
|
||||||
|
```
|
||||||
|
|
||||||
|
Anschließend wird nur dann ein Link angezeigt, wenn:
|
||||||
|
|
||||||
|
- die Ziel-URL dieselbe Origin wie die Landing Page besitzt und
|
||||||
|
- der Pfad mit `/d/` beginnt.
|
||||||
|
|
||||||
|
Dadurch kann `subEntityId` nicht als offener Redirect auf fremde Domains missbraucht werden.
|
||||||
|
|
||||||
|
Die Seite unterstützt zusätzlich einen direkten Browser-Test über einen Query-Parameter:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://forum.example/static/flarum-notify-v2.html?target=https%3A%2F%2Fforum.example%2Fd%2F123%2F17
|
||||||
|
```
|
||||||
|
|
||||||
|
## Teams-App-Manifest
|
||||||
|
|
||||||
|
Das Teams-Manifest benötigt mindestens einen persönlichen statischen Tab und die Forum-Domain in `validDomains`.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"staticTabs": [
|
||||||
|
{
|
||||||
|
"entityId": "YOUR_TEAMS_ENTITY_ID",
|
||||||
|
"name": "Flarum Notify",
|
||||||
|
"contentUrl": "https://forum.example/static/flarum-notify-v2.html",
|
||||||
|
"websiteUrl": "https://forum.example/static/flarum-notify-v2.html",
|
||||||
|
"scopes": [
|
||||||
|
"personal"
|
||||||
|
],
|
||||||
|
"context": [
|
||||||
|
"personalTab"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validDomains": [
|
||||||
|
"forum.example"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Die folgenden Werte müssen zwischen Manifest und Erweiterung übereinstimmen:
|
||||||
|
|
||||||
|
- Teams App ID
|
||||||
|
- Entity ID des Personal Tabs
|
||||||
|
- öffentliche Forum-Basis-URL
|
||||||
|
|
||||||
|
## Microsoft Entra ID und Graph
|
||||||
|
|
||||||
|
Für den App-only-Versand werden eine Microsoft-Entra-App-Registrierung und geeignete Microsoft-Graph-Anwendungsberechtigungen benötigt. Die konkrete Berechtigungskonfiguration hängt vom verwendeten Graph-Endpunkt, dem Mandanten und den internen Sicherheitsrichtlinien ab.
|
||||||
|
|
||||||
|
Erforderliche Konfigurationswerte sind typischerweise:
|
||||||
|
|
||||||
|
- Tenant ID
|
||||||
|
- Client ID
|
||||||
|
- Client Secret
|
||||||
|
- Teams App ID
|
||||||
|
- Forum Base URL
|
||||||
|
- Strategie zur Auflösung des Zielbenutzers
|
||||||
|
|
||||||
|
Nach dem Hinzufügen von Application Permissions ist in der Regel eine Administratorzustimmung im Microsoft-Entra-Mandanten erforderlich.
|
||||||
|
|
||||||
|
## Flarum-Admin-Einstellungen
|
||||||
|
|
||||||
|
Das Admin-Frontend enthält Einstellungen für:
|
||||||
|
|
||||||
|
- Aktivierung der Erweiterung
|
||||||
|
- Tenant ID
|
||||||
|
- Client ID
|
||||||
|
- Client Secret
|
||||||
|
- Forum Base URL
|
||||||
|
- User Lookup Strategy
|
||||||
|
- UPN Preference Key
|
||||||
|
- User Preference Key
|
||||||
|
- Activity Type
|
||||||
|
- Teams App ID
|
||||||
|
- optionale Icon ID
|
||||||
|
- HTTP Timeout
|
||||||
|
|
||||||
|
Beispiel für die Forum Base URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://forum.example
|
||||||
|
```
|
||||||
|
|
||||||
|
Keinen abschließenden Pfad wie `/public`, `/api` oder `/static` eintragen.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Erweiterung bereitstellen
|
||||||
|
|
||||||
|
Das Repository muss als Composer-Paket beziehungsweise lokales Flarum-Paket verfügbar sein. Danach im Flarum-Root die Abhängigkeiten beziehungsweise den Autoloader aktualisieren:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /var/www/html/flarum
|
||||||
|
composer dump-autoload
|
||||||
|
```
|
||||||
|
|
||||||
|
Je nach Installationsart kann zuvor ein `composer require` oder ein Composer-Path-Repository erforderlich sein.
|
||||||
|
|
||||||
|
### 2. Admin- und Forum-Frontend bauen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd js
|
cd js
|
||||||
|
|
@ -14,8 +255,320 @@ npm install
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
Danach im Flarum-Root:
|
Für die Entwicklung mit Watch-Modus:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd js
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Flarum-Cache leeren
|
||||||
|
|
||||||
|
Im Flarum-Root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php flarum cache:clear
|
php flarum cache:clear
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 4. Queue-Worker neu starten
|
||||||
|
|
||||||
|
Bei Supervisor beispielsweise:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo supervisorctl restart all
|
||||||
|
sudo supervisorctl status
|
||||||
|
```
|
||||||
|
|
||||||
|
In einer produktiven Umgebung sollte möglichst nur die betroffene Worker-Gruppe neu gestartet werden.
|
||||||
|
|
||||||
|
## Statische Teams-Dateien
|
||||||
|
|
||||||
|
Die Landing Page besteht aus:
|
||||||
|
|
||||||
|
```text
|
||||||
|
flarum-notify-v2.html
|
||||||
|
flarum-notify-v2.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Bei einer Apache-Konfiguration mit folgendem Alias:
|
||||||
|
|
||||||
|
```apache
|
||||||
|
Alias "/static" "/var/www/html/static"
|
||||||
|
```
|
||||||
|
|
||||||
|
liegen die Dateien beispielsweise hier:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/www/html/static/flarum-notify-v2.html
|
||||||
|
/var/www/html/static/flarum-notify-v2.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Apache-, CSP- und Frame-Konfiguration
|
||||||
|
|
||||||
|
Teams stellt Personal Tabs in einem eingebetteten Browserkontext dar. Ein globales
|
||||||
|
|
||||||
|
```http
|
||||||
|
X-Frame-Options: DENY
|
||||||
|
```
|
||||||
|
|
||||||
|
oder
|
||||||
|
|
||||||
|
```http
|
||||||
|
Content-Security-Policy: frame-ancestors 'none'
|
||||||
|
```
|
||||||
|
|
||||||
|
blockiert deshalb die Landing Page und erzeugt im Teams-Desktop typischerweise eine weiße Fläche.
|
||||||
|
|
||||||
|
Das eigentliche Forum kann weiterhin global gegen Framing geschützt bleiben. Nur die statische Landing Page sollte für Microsoft Teams freigegeben werden.
|
||||||
|
|
||||||
|
Beispiel für Apache:
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
<LocationMatch "^/static/flarum-notify-v2\.html$">
|
||||||
|
Header always unset X-Frame-Options
|
||||||
|
Header always unset Content-Security-Policy
|
||||||
|
Header always unset Content-Security-Policy-Report-Only
|
||||||
|
|
||||||
|
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://res.cdn.office.net; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'self' https://teams.microsoft.com https://*.teams.microsoft.com https://*.cloud.microsoft; base-uri 'self'; form-action 'self'"
|
||||||
|
|
||||||
|
Header always set Cache-Control "no-cache, must-revalidate, max-age=0"
|
||||||
|
</LocationMatch>
|
||||||
|
</IfModule>
|
||||||
|
```
|
||||||
|
|
||||||
|
Anschließend:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apache2ctl configtest
|
||||||
|
sudo systemctl reload apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
Header prüfen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sSI https://forum.example/static/flarum-notify-v2.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Für die Landing Page darf kein restriktiver `X-Frame-Options`-Header mehr ausgeliefert werden. Die CSP muss die benötigten Teams-Hosts als `frame-ancestors` und das TeamsJS-CDN unter `script-src` erlauben.
|
||||||
|
|
||||||
|
Das eigentliche Forum – insbesondere `/d/...`, Login und Admin-Bereiche – muss für diesen Ansatz nicht in einem Frame freigegeben werden.
|
||||||
|
|
||||||
|
## Cache-Verhalten in Microsoft Teams
|
||||||
|
|
||||||
|
Microsoft Teams kann persönliche Tabs im Desktop-Client im Speicher halten beziehungsweise suspendieren. Änderungen an HTML oder JavaScript werden deshalb nicht immer bei jedem Klick sofort neu geladen.
|
||||||
|
|
||||||
|
Empfehlungen:
|
||||||
|
|
||||||
|
- Landing-Page-HTML mit `Cache-Control: no-cache, must-revalidate` ausliefern
|
||||||
|
- JavaScript bei Änderungen versionieren, zum Beispiel:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="/static/flarum-notify-v2.js?v=20260728-1" defer></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
- nach größeren Änderungen Teams vollständig beenden und neu starten
|
||||||
|
- ein manuelles Löschen des vollständigen Teams-Caches sollte im Normalbetrieb nicht erforderlich sein
|
||||||
|
|
||||||
|
## Test-Command
|
||||||
|
|
||||||
|
Eine Testbenachrichtigung kann an einen einzelnen Flarum-Benutzer gesendet werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php flarum teams:test-user <flarumUserId>
|
||||||
|
```
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php flarum teams:test-user 42
|
||||||
|
```
|
||||||
|
|
||||||
|
Nur das aufgelöste Graph-Ziel anzeigen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php flarum teams:test-user 42 --show-target
|
||||||
|
```
|
||||||
|
|
||||||
|
Ziel testweise überschreiben:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php flarum teams:test-user 42 --target user@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Test-Blueprint besitzt keinen realen Discussion- oder Post-Subject. Deshalb führt eine reine Testbenachrichtigung üblicherweise nicht zu einem konkreten Beitragslink, sondern zur allgemeinen Zwischenansicht.
|
||||||
|
|
||||||
|
## Benutzerkonfiguration
|
||||||
|
|
||||||
|
Die Erweiterung ergänzt die persönlichen Flarum-Benachrichtigungseinstellungen um Microsoft Teams. Benutzer können Teams für die angebotenen Benachrichtigungstypen ein- oder ausschalten.
|
||||||
|
|
||||||
|
Wenn ein Benutzer keine Teams-Benachrichtigungen erhält, sollten folgende Punkte geprüft werden:
|
||||||
|
|
||||||
|
1. Ist Microsoft Teams für den betreffenden Typ in Flarum aktiviert?
|
||||||
|
2. Kann `TargetResolver` eine E-Mail-Adresse oder einen UPN auflösen?
|
||||||
|
3. Ist die Teams-App für den Benutzer installiert beziehungsweise verfügbar?
|
||||||
|
4. Besitzt die Entra-App die benötigten Berechtigungen und Admin Consent?
|
||||||
|
5. Läuft der Queue-Worker?
|
||||||
|
6. Enthalten Worker- und Supervisor-Logs Graph-Fehler?
|
||||||
|
|
||||||
|
## Fehlersuche
|
||||||
|
|
||||||
|
### Weiße Fläche im Teams-Desktop
|
||||||
|
|
||||||
|
Response Header prüfen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sSI https://forum.example/static/flarum-notify-v2.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Typische Ursachen:
|
||||||
|
|
||||||
|
- `X-Frame-Options: DENY`
|
||||||
|
- `X-Frame-Options: SAMEORIGIN`
|
||||||
|
- `frame-ancestors 'none'`
|
||||||
|
- `frame-ancestors 'self'` ohne Teams-Domains
|
||||||
|
|
||||||
|
### Seite wird ohne CSS dargestellt
|
||||||
|
|
||||||
|
Wenn CSS als `<style>`-Block in der HTML-Datei enthalten ist, benötigt die CSP entweder einen Hash/Nonce oder – für diese kleine interne statische Seite – beispielsweise:
|
||||||
|
|
||||||
|
```text
|
||||||
|
style-src 'self' 'unsafe-inline'
|
||||||
|
```
|
||||||
|
|
||||||
|
Langfristig kann das CSS in eine separate Datei ausgelagert werden, damit `'unsafe-inline'` nicht erforderlich ist.
|
||||||
|
|
||||||
|
### Allgemeiner Link statt konkretem Beitrag
|
||||||
|
|
||||||
|
Prüfen, ob die PHP-Datei den Deep-Link-Kontext erzeugt:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep -nE 'subEntityId|context|subjectUrl' \
|
||||||
|
vendor/sbp-jm/flarum-msteams-webhook/src/Support/NotificationPayloadFactory.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Prüfen, ob die Landing Page TeamsJS lädt und `page.subPageId` ausliest:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep -nE 'microsoftTeams|subPageId|getContext|initialize' \
|
||||||
|
/var/www/html/static/flarum-notify-v2.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Nur neu versendete Activity-Feed-Einträge enthalten den aktualisierten Deep Link. Bereits vorhandene Teams-Aktivitäten werden nicht nachträglich geändert.
|
||||||
|
|
||||||
|
### Änderungen am PHP-Code werden nicht verwendet
|
||||||
|
|
||||||
|
Queue-Worker neu starten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php flarum cache:clear
|
||||||
|
sudo supervisorctl restart all
|
||||||
|
```
|
||||||
|
|
||||||
|
### Queue und Supervisor prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo supervisorctl status
|
||||||
|
```
|
||||||
|
|
||||||
|
Logs – abhängig von der lokalen Supervisor-Konfiguration – beispielsweise:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo supervisorctl tail \
|
||||||
|
flarum-teams-worker:flarum-teams-worker_00 \
|
||||||
|
stderr
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTTP-Aufrufe der Landing Page beobachten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo tail -f /var/log/apache2/access.log |
|
||||||
|
grep --line-buffered 'flarum-notify-v2'
|
||||||
|
```
|
||||||
|
|
||||||
|
Teams kann den Tab nach dem ersten Laden im Speicher halten. Weitere Klicks müssen daher nicht zwingend neue HTTP-Requests erzeugen.
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
Wichtige Dateien und Verzeichnisse:
|
||||||
|
|
||||||
|
```text
|
||||||
|
extend.php
|
||||||
|
composer.json
|
||||||
|
js/
|
||||||
|
admin.js
|
||||||
|
forum.js
|
||||||
|
src/admin/
|
||||||
|
src/forum/
|
||||||
|
locale/
|
||||||
|
de.yml
|
||||||
|
en.yml
|
||||||
|
src/
|
||||||
|
Console/
|
||||||
|
TestTeamsUserCommand.php
|
||||||
|
Job/
|
||||||
|
SendTeamsActivityNotificationJob.php
|
||||||
|
Notification/
|
||||||
|
TeamsNotificationDriver.php
|
||||||
|
TestActivityBlueprint.php
|
||||||
|
Service/
|
||||||
|
GraphTokenProvider.php
|
||||||
|
TeamsActivityNotifier.php
|
||||||
|
Support/
|
||||||
|
NotificationPayloadFactory.php
|
||||||
|
TargetResolver.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Im Repository können zusätzlich ältere oder experimentelle Klassen wie `TeamsChannel` oder `TeamsDriver` vorhanden sein. Der aktuell in `extend.php` registrierte Einstiegspunkt ist `TeamsNotificationDriver`.
|
||||||
|
|
||||||
|
## Sicherheitshinweise
|
||||||
|
|
||||||
|
- Client Secrets niemals im Repository speichern.
|
||||||
|
- Tokens und vollständige Graph-Payloads nur kurzfristig und geschützt protokollieren.
|
||||||
|
- Die Landing Page darf nur Links zur eigenen Forum-Origin akzeptieren.
|
||||||
|
- Das eigentliche Forum nicht pauschal für fremde Frames freigeben.
|
||||||
|
- HTTPS ist verpflichtend.
|
||||||
|
- Berechtigungen der Entra-App nach dem Least-Privilege-Prinzip vergeben.
|
||||||
|
- Produktive Secrets regelmäßig rotieren.
|
||||||
|
- Logdateien auf Benutzerkennungen, E-Mail-Adressen und Diskussionstitel prüfen und angemessen schützen.
|
||||||
|
|
||||||
|
## Entwicklung
|
||||||
|
|
||||||
|
Frontend-Abhängigkeiten installieren:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd js
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
Produktions-Build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Watch-Modus:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Formatierung:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run format
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach einem Frontend-Build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /var/www/html/flarum
|
||||||
|
php flarum cache:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach PHP-Änderungen zusätzlich den Queue-Worker neu starten.
|
||||||
|
|
||||||
|
## Lizenz
|
||||||
|
|
||||||
|
MIT – siehe `composer.json` beziehungsweise eine vorhandene `LICENSE`-Datei.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue