Auth / FaceID — eingeloggt bleiben funktioniert jetzt: - AppLock-Init idempotent: late re-init durch router.replace-Re-Mount behält locked-State (fixt Endlosschleife: unlock → re-mount → init reset → lock) - LockScreen-Auto-Prompt nur wenn AppState=active (verhindert silent FaceID- Fail wenn LockScreen während background-Event mountet — User sah dann nur Fallback-Button) - index.tsx: wenn Session schon in AsyncStorage liegt → router.replace zu /(app), Landing wird übersprungen; early-return nach allen Hooks (Rules of Hooks) - WebBrowser.dismissAuthSession vor openAuthSessionAsync (verhindert "Another web browser is already open" nach abgebrochenen OAuth-Flows) UI — iOS-Grouped-Look auf Settings + Profile: - Neue Theme-Tokens groupedBg (#F2F2F7 / #000) + card (#fff / #1c1c1e), identisch zu Apples systemGroupedBackground / secondarySystemGroupedBackground - settings.tsx + profile/index.tsx + profile/[userId].tsx: Page-BG → groupedBg - StreakSection / UrgeStatsCard / DemographicsAccordion / StatsBar / ApprovedDomainsList: Card-BG colors.surface → colors.card Mail-Connect — Outlook-Tile entschärft: - Microsoft hat App-Passwords für consumer-Outlook (.com/hotmail/live/msn) im September 2024 abgeschaltet, der bisherige Guide-Flow ist seit ~8 Monaten wirkungslos → AUTHENTICATIONFAILED - Tile bleibt sichtbar mit opacity 0.45, "Kommt bald"-Sub-Label, disabled=true - Provider-Typ um disabled? + disabledLabelKey? erweitert (wiederverwendbar) - Backend-OAuth-Plan unter backend/docs/mail-outlook-oauth-plan.md (mo) → Generisches AuthMethod-Framework (app_password | oauth) geplant Profile — Cooldown-Verlauf als Sparkline statt Endlos-Liste: - 8 Wochen-Buckets, Bar-Höhe nach Frequenz (cap 5/Woche), leere Wochen als 2px-Flatlines - Sub-Label: "{n} Cooldowns in 8 Wochen · Ø 1 pro {avg} Wochen · zuletzt {date}" - Neutral formuliert (Sucht-/Stigma-Sensibilität: Cooldown = Schutz-Pause, kein Rückfall) - useProfileData.ts liefert rawStartedAt (ISO) zusätzlich zum formatierten Wert - i18n-Keys unter profile.cooldown.* in DE + EN Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
477 lines
19 KiB
Markdown
477 lines
19 KiB
Markdown
# Outlook OAuth2 — Implementierungsplan
|
|
|
|
Stand: 2026-05-13
|
|
Autor: Mo (Mail-Stack-Owner)
|
|
Status: Plan, kein Code
|
|
|
|
---
|
|
|
|
## 1. Status-Recherche: Microsoft Basic-Auth-Deprecation
|
|
|
|
### Was ist passiert
|
|
|
|
Microsoft hat Basic-Auth (username + password) für consumer-Outlook-Mailboxen
|
|
(outlook.com, hotmail.com, hotmail.de, live.com, live.de, msn.com) schrittweise
|
|
abgeschaltet:
|
|
|
|
- **September 2024**: Vollständige Abschaltung für neue IMAP/POP/SMTP-Verbindungen
|
|
mit Basic-Auth auf consumer-Tenants. Bestehende Verbindungen hatten eine
|
|
Übergangsfrist.
|
|
- **Stand Mai 2026**: Basic-Auth ist für alle consumer-Outlook-Postfächer tot.
|
|
IMAP-Login mit Passwort schlägt mit `[AUTHENTICATIONFAILED]` fehl — egal ob
|
|
App-Passwort oder normales Passwort.
|
|
|
|
### Edge-Cases
|
|
|
|
| Szenario | Basic-Auth möglich? |
|
|
|---|---|
|
|
| outlook.com / hotmail / live / msn — consumer | Nein, komplett tot |
|
|
| Microsoft 365 Business (firmeneigene Domain, Azure-AD-Tenant) | Nein, Admins können es nicht reaktivieren |
|
|
| Outlook.com custom domain (eigene Domain via Outlook-Webmail) | Nein, gleiche Infrastruktur |
|
|
| On-Premise Exchange (eigener Firmen-Server) | Hypothetisch ja, aber nicht unser Use-Case |
|
|
|
|
**Fazit**: Es gibt keinen Edge-Case der uns rettet. Der App-Passwort-Guide im
|
|
ConnectMailSheet ist für Outlook-User seit September 2024 nutzlos. Jeder
|
|
Outlook-User der jetzt "Verbinden" drückt bekommt vom Backend
|
|
`AUTHENTICATIONFAILED` zurück.
|
|
|
|
### Benoetigte OAuth-Scopes
|
|
|
|
Fuer IMAP read + delete via XOAUTH2 gegen Microsoft Identity Platform:
|
|
|
|
```
|
|
https://outlook.office.com/IMAP.AccessAsUser.All
|
|
offline_access
|
|
openid
|
|
```
|
|
|
|
- `IMAP.AccessAsUser.All` — erlaubt IMAP-Zugriff im Namen des Users (lesen,
|
|
loeschen, verschieben). Kein weiterer Mail-Scope noetig.
|
|
- `offline_access` — liefert einen refresh_token (ohne ihn gibt es keinen
|
|
refresh_token, nur kurze access_tokens). Pflicht fuer langlebige IDLE-Sessions.
|
|
- `openid` — liefert sub/email im ID-Token fuer Account-Identifikation.
|
|
|
|
Explizit NICHT anfordern: `Mail.Read`, `Mail.ReadWrite`, `Contacts.*`,
|
|
`Calendars.*`, `User.Read` (ausser sub/email). Minimale Scope-Anforderung.
|
|
|
|
### Consumer Identity Platform vs Azure-AD
|
|
|
|
Microsoft hat zwei Systeme:
|
|
- **Microsoft Identity Platform v2 (consumers)** — fuer outlook.com/hotmail-Privat-
|
|
konten. Endpoint: `https://login.microsoftonline.com/consumers/oauth2/v2.0/...`
|
|
oder tenant-agnostisch `common`. Azure-App-Registrierung mit "Supported account
|
|
types: Personal Microsoft accounts only" oder "Any Microsoft account (multi-tenant
|
|
+ personal)".
|
|
- **Azure-AD / Entra ID (work/school)** — fuer M365-Business. Nicht unser
|
|
primaerer Use-Case.
|
|
|
|
Fuer Rebreak: App-Registrierung mit `consumers`-Endpoint — deckt alle genannten
|
|
Domains ab (outlook.com, hotmail, live, msn). Wer ein M365-Business-Konto hat,
|
|
faellt spaeter unter den gleichen Flow wenn wir auf `common` wechseln.
|
|
|
|
---
|
|
|
|
## 2. Architektur-Plan
|
|
|
|
### 2.1 Azure-App-Registrierung
|
|
|
|
Einmaliges Setup im Azure-Portal (portal.azure.com):
|
|
|
|
| Feld | Wert |
|
|
|---|---|
|
|
| Name | Rebreak Mail Access |
|
|
| Supported account types | Personal Microsoft accounts only |
|
|
| Redirect URI (Mobile) | `msauth.org.rebreak.app://auth` (MSAL-Schema) |
|
|
| Redirect URI (Web/BFF) | `https://api.rebreak.org/api/mail/oauth/microsoft/callback` |
|
|
| API Permissions | `IMAP.AccessAsUser.All` (delegated), `offline_access`, `openid` |
|
|
| Client secret | Ja (fuer BFF-Token-Exchange) |
|
|
| Public client flows | Ja aktivieren (fuer PKCE) |
|
|
|
|
Scopes muessen im Portal unter "API Permissions" explizit hinzugefuegt und fuer
|
|
`consumers`-Tenant fuer alle User freigegeben werden. Kein "Grant admin consent"
|
|
noetig fuer delegated permissions auf consumer-Tenant.
|
|
|
|
**Multi-Tenant-Approval erforderlich?** Nein. Bei "Personal Microsoft accounts
|
|
only" gibt es keinen App-Review-Prozess bei Microsoft — jeder MS-User kann der
|
|
App konsentieren. App-Reviews sind nur noetig wenn man `All organizations`-Tenant
|
|
anfordert und enterprise-Features braucht.
|
|
|
|
### 2.2 OAuth-Flow: BFF-Pattern (Backend-mediated)
|
|
|
|
Empfehlung: **BFF-Pattern**, nicht PKCE direkt im Mobile-Client.
|
|
|
|
Begruendung:
|
|
- Client-secret darf nicht im App-Bundle liegen (App-Store-Guidelines, Reverse-
|
|
Engineering). PKCE ohne client_secret ist moeglich aber dann kein refresh_token
|
|
via MSAL fuer native — Microsoft erlaubt es fuer public clients, aber Token-
|
|
Rotation ist dann Clients-Sache.
|
|
- Wir haben bereits den BFF-Ansatz beim Auth-Login. Konsistenz.
|
|
- Token-Storage (encrypted, server-side) ist ohnehin Backend-Aufgabe.
|
|
|
|
**Flow-Sequenz:**
|
|
|
|
```
|
|
Native App Backend Microsoft
|
|
| | |
|
|
| GET /api/mail/oauth/ | |
|
|
| microsoft/authorize | |
|
|
| (mit state+code_challenge) | |
|
|
|---------------------------->| |
|
|
| | build auth URL |
|
|
| 302 redirect URL | (PKCE, state, scopes) |
|
|
|<----------------------------| |
|
|
| | |
|
|
| WebBrowser.openAuthSession | |
|
|
| oeffnet MS-Login | |
|
|
|-------------------------------------------->| |
|
|
| | | User loggt |
|
|
| | | ein, |
|
|
| | | konsentiert |
|
|
|<--------------------------------------------| |
|
|
| redirect: .../callback?code=XXX&state=YYY | |
|
|
| | |
|
|
| POST /api/mail/oauth/ | |
|
|
| microsoft/exchange | |
|
|
| body: { code, state } | |
|
|
|---------------------------->| |
|
|
| | POST token endpoint |
|
|
| | (code + code_verifier) |
|
|
| |---------------------------->|
|
|
| |<----------------------------|
|
|
| | { access_token, |
|
|
| | refresh_token, |
|
|
| | expires_in } |
|
|
| | |
|
|
| | decrypt+store tokens |
|
|
| | upsert MailConnection |
|
|
| | |
|
|
| { connected: true } | |
|
|
|<----------------------------| |
|
|
```
|
|
|
|
Zwei neue Backend-Endpoints:
|
|
- `GET /api/mail/oauth/microsoft/authorize` — generiert state + PKCE-Verifier,
|
|
speichert state temporaer in DB/Session, gibt redirect URL zurueck
|
|
- `POST /api/mail/oauth/microsoft/exchange` — empfaengt code + state, tauscht
|
|
gegen tokens, speichert in MailConnection
|
|
|
|
### 2.3 Token-Storage: Schema-Aenderung (Eskalation an rebreak-backend)
|
|
|
|
**ESKALATION AN rebreak-backend erforderlich.**
|
|
|
|
Das aktuelle `MailConnection`-Schema hat `passwordEncrypted: String`. Fuer OAuth
|
|
brauchen wir:
|
|
|
|
```prisma
|
|
// Neue Felder in MailConnection:
|
|
authMethod String @default("password") @map("auth_method")
|
|
// "password" | "oauth2_microsoft" | "oauth2_google" (future)
|
|
|
|
oauthAccessToken String? @map("oauth_access_token") // AES-256-GCM encrypted
|
|
oauthRefreshToken String? @map("oauth_refresh_token") // AES-256-GCM encrypted
|
|
oauthTokenExpiry DateTime? @map("oauth_token_expiry") // UTC, naechste Ablaufzeit
|
|
oauthScope String? @map("oauth_scope") // gespeicherter Scope-String
|
|
```
|
|
|
|
`passwordEncrypted` bleibt fuer bestehende password-basierte Connections.
|
|
|
|
**Fuer OAuth-Connections**: `passwordEncrypted` = leer string oder `"oauth"` als
|
|
Marker, damit bestehender Code nicht bricht. Besser: `authMethod`-Flag pruefe
|
|
zuerst.
|
|
|
|
Schema-Migration: `ALTER TABLE rebreak.mail_connections ADD COLUMN ...` (4 neue
|
|
Spalten). Kein Breaking Change fuer bestehende Rows.
|
|
|
|
### 2.4 IMAP-Connect-Logik: XOAUTH2 in ImapFlow
|
|
|
|
**Gute Nachricht**: `imapflow` (aktuell `^1.2.18`) unterstuetzt XOAUTH2 nativ.
|
|
|
|
Aktueller Auth-Block in `connect.post.ts` und `imap-idle/index.mjs`:
|
|
```js
|
|
auth: { user: email, pass: password }
|
|
```
|
|
|
|
Fuer OAuth: ImapFlow akzeptiert stattdessen:
|
|
```js
|
|
auth: {
|
|
user: email,
|
|
accessToken: decryptedAccessToken
|
|
}
|
|
```
|
|
|
|
ImapFlow baut daraus automatisch den XOAUTH2-SASL-String. Kein manueller
|
|
Base64-Encoding noetig, keine Library-Aenderung erforderlich.
|
|
|
|
`imap-providers.ts` braucht ein neues Interface:
|
|
```ts
|
|
export interface ImapAuth {
|
|
type: 'password' | 'oauth2';
|
|
value: string; // password (plaintext, decrypted) ODER access_token
|
|
}
|
|
```
|
|
|
|
Die Resolve-Logik in `connect.post.ts` muss `authMethod` aus MailConnection
|
|
lesen und die richtige `ImapAuth` zusammenbauen.
|
|
|
|
### 2.5 Token-Refresh-Flow
|
|
|
|
**Das haerteste Problem.** Access-tokens laufen bei Microsoft nach 1 Stunde ab.
|
|
|
|
Betroffen sind zwei Stellen:
|
|
|
|
**A. IMAP-Idle-Daemon** (langlebige Verbindung, laeuft tage-/wochenlang):
|
|
|
|
Der Daemon muss vor jedem connect (und nach AUTHENTICATIONFAILED-Fehlern) pruefen
|
|
ob der access_token noch gueltig ist. Refresh-Logik:
|
|
|
|
```
|
|
1. oauthTokenExpiry aus DB lesen
|
|
2. Wenn expiry < now + 5min:
|
|
a. POST https://login.microsoftonline.com/consumers/oauth2/v2.0/token
|
|
mit: grant_type=refresh_token, refresh_token=<decrypted>, client_id, client_secret
|
|
b. Neues access_token + refresh_token in DB speichern (encrypted)
|
|
c. oauthTokenExpiry updaten
|
|
3. ImapFlow mit frischem access_token verbinden
|
|
```
|
|
|
|
Refresh im Daemon direkt (kein HTTP-Roundtrip zum Backend noetig — Daemon hat
|
|
direkten DB-Zugriff). Der Daemon erhaelt client_id + client_secret als Env-Vars.
|
|
|
|
**Token-Rotation**: Microsoft kann bei refresh auch ein neues refresh_token liefern
|
|
("refresh token rotation"). Daemon muss das neue refresh_token persistieren,
|
|
sonst ist nach einem Refresh der naechste fehlgeschlagen.
|
|
|
|
**B. scan.post.ts / connect.post.ts** (kurze Connections):
|
|
|
|
Beim On-Demand-Scan: pruefe `oauthTokenExpiry` und refresh wenn noetig, bevor
|
|
IMAP-Connection aufgebaut wird. Da dieser Code im Nitro-Kontext laeuft, kann
|
|
er direkt Prisma nutzen.
|
|
|
|
**Refresh-Token-Revocation bei User-Logout / Account-Loeschung**: Backend muss
|
|
`POST https://login.microsoftonline.com/consumers/oauth2/v2.0/logout` aufrufen
|
|
wenn User die Verbindung trennt oder Account loescht. Sonst bleibt unsere App-
|
|
Autorisierung bei Microsoft aktiv.
|
|
|
|
---
|
|
|
|
## 3. ConnectMailSheet UX-Plan (fuer rebreak-native-ui-Agent)
|
|
|
|
### Geaenderter Flow fuer Outlook
|
|
|
|
Aktuell: Outlook-Provider-Tile -> Formular mit Email + App-Passwort-Hinweis + Link.
|
|
|
|
Neu: Outlook-Provider-Tile -> Anderer View (kein Passwort-Formular):
|
|
|
|
```
|
|
[Tile: Outlook / Hotmail / Live]
|
|
|
|
|
v
|
|
View: "outlook-oauth"
|
|
+---------------------------------+
|
|
| [Outlook-Icon] |
|
|
| Mit Microsoft anmelden |
|
|
| |
|
|
| Rebreak benoetigt Zugriff auf |
|
|
| dein Postfach um Gluecksspiel- |
|
|
| Mails automatisch zu loeschen. |
|
|
| |
|
|
| [Schild-Icon] Datenschutz: |
|
|
| Wir lesen keine Inhalte. Nur |
|
|
| Absender + Betreff zum Matching|
|
|
| |
|
|
| [Button] Mit Microsoft anmelden|
|
|
| |
|
|
| [Spinner waehrend OAuth laeuft]|
|
|
+---------------------------------+
|
|
```
|
|
|
|
States:
|
|
- **idle**: Button aktiv, Datenschutz-Hinweis sichtbar
|
|
- **loading**: Button disabled, ActivityIndicator, Text "Verbindung wird hergestellt..."
|
|
- **error**: Roter Error-Text unter Button (z.B. "Zugriff verweigert" wenn User
|
|
Consent ablehnt, oder "Verbindung fehlgeschlagen" bei Network-Error)
|
|
- **success**: Sheet schliesst sich, onSuccess() wird aufgerufen
|
|
|
|
Technisch im Client:
|
|
```
|
|
1. Button-Tap → GET /api/mail/oauth/microsoft/authorize
|
|
2. Backend gibt { authUrl: "https://login.microsoftonline.com/..." } zurueck
|
|
3. expo-web-browser: WebBrowser.openAuthSessionAsync(authUrl, redirectUri)
|
|
4. Deep-Link-Handler empfaengt Callback-URL mit code + state
|
|
5. POST /api/mail/oauth/microsoft/exchange mit { code, state }
|
|
6. On success: handleClose() + onSuccess()
|
|
```
|
|
|
|
Redirect-URI in der App: `msauth.org.rebreak.app://auth` — muss in
|
|
`app.json`-Scheme registriert und in Azure-App-Registrierung eingetragen sein.
|
|
|
|
**Bestehende Provider unveraendert**: Gmail, iCloud, Yahoo, GMX, Other behalten
|
|
den Passwort-Formular-Flow. Nur Outlook-Tile bekommt anderen View.
|
|
|
|
---
|
|
|
|
## 4. DSGVO-/Compliance-Aspekte (fuer Hans-Mueller-DSB-Review)
|
|
|
|
**ESKALATION AN hans-mueller** fuer formelles Review.
|
|
|
|
### 4.1 Microsoft als Sub-Auftragsverarbeiter
|
|
|
|
Microsoft wird durch den OAuth-Flow zusaetzlicher Sub-AV (Art. 28 DSGVO).
|
|
Microsoft hat ein Standard-DPA das automatisch gilt wenn man Azure-Services nutzt
|
|
(Microsoft Products and Services Data Protection Addendum — DPA). Zu pruefen:
|
|
- Gilt das DPA auch fuer consumer Microsoft Identity Platform?
|
|
- Muss in unserem AV-Vertraege-Verzeichnis (VVT) erwaehnt werden?
|
|
- Microsoft hat EU-Datenzentren — Transfer-Grundlage sollte Standard-Vertragsklauseln
|
|
oder Adequacy-Decision sein.
|
|
|
|
### 4.2 Token-Speicherung = sensibler als Passwort
|
|
|
|
Ein refresh_token gibt persistenten Zugriff auf das Postfach bis zur Revocation —
|
|
laenger als ein App-Passwort (das der User jederzeit in Sekunden zurueckziehen
|
|
kann). Konsequenzen:
|
|
- Verschluesselung at-rest: gleicher AES-256-GCM wie bei `passwordEncrypted`.
|
|
Gleicher ENCRYPTION_KEY. Kein anderer Speicherweg.
|
|
- Zugriff auf refresh_token = Zugriff auf gesamtes Postfach. Breach-Impact hoeher
|
|
als bei App-Passwort.
|
|
- Im Datenschutzhinweis in der App und in der Datenschutzerklaerung explizit
|
|
erwaehnen: "Wir speichern einen Zugriffstoken der im Namen des Users auf das
|
|
Postfach zugreift".
|
|
|
|
### 4.3 Datenminimierung
|
|
|
|
Scopes beschraenken auf:
|
|
- `IMAP.AccessAsUser.All` — Minimum fuer IMAP
|
|
- `offline_access` — Minimum fuer Token-Refresh
|
|
- `openid` — fuer Email-Identifikation (kein `profile`-Scope)
|
|
|
|
Kein `User.Read.All`, kein `Contacts.*`, kein `Calendars.*`.
|
|
|
|
### 4.4 Loeschpflicht / Widerrufs-Pflicht
|
|
|
|
Bei User-Disconnect oder Account-Loeschung:
|
|
1. refresh_token + access_token aus DB loeschen
|
|
2. Token bei Microsoft revoken via:
|
|
`POST https://login.microsoftonline.com/consumers/oauth2/v2.0/token/revoke`
|
|
(mit refresh_token als Parameter)
|
|
|
|
Ohne Revocation bleibt Rebreaks App-Autorisierung bei Microsoft aktiv — auch wenn
|
|
wir die DB-Eintraege loeschen.
|
|
|
|
### 4.5 Speicherort
|
|
|
|
Token in `MailConnection`-Tabelle, gleicher Postgres-Host wie alle anderen User-
|
|
daten. Kein separater Secret-Store noetig wenn AES-256-GCM konsistent angewandt
|
|
wird.
|
|
|
|
---
|
|
|
|
## 5. Aufwands-Schaetzung
|
|
|
|
### MVP-Scope
|
|
|
|
MVP = OAuth-Login funktioniert, User kann Outlook verbinden, IMAP-IDLE loescht
|
|
Gambling-Mails, Token-Refresh laeuft automatisch.
|
|
|
|
| Komponente | Aufwand |
|
|
|---|---|
|
|
| Azure-App-Registrierung (einmaliges Setup) | 0.5 Tage |
|
|
| Schema-Migration (4 neue Spalten, rebreak-backend) | 0.5 Tage |
|
|
| Backend: 2 neue Endpoints (authorize + exchange) | 1.5 Tage |
|
|
| connect.post.ts: authMethod-Logik + XOAUTH2-Support | 0.5 Tage |
|
|
| imap-idle: Token-Refresh-Logik + XOAUTH2-Auth | 1.5 Tage |
|
|
| scan.post.ts: Token-Refresh vor on-demand-scan | 0.5 Tage |
|
|
| disconnect.delete.ts: Token-Revocation bei MS | 0.5 Tage |
|
|
| ConnectMailSheet: Outlook-OAuth-View (native-ui-agent) | 1.0 Tag |
|
|
| Deep-Link-Handling in App + expo-web-browser Setup | 0.5 Tage |
|
|
| Testen end-to-end (inkl. Token-Refresh-Simulation) | 1.0 Tag |
|
|
| **Gesamt** | **~8 Personentage** |
|
|
|
|
### Risiken
|
|
|
|
**1. Microsoft Rate Limits auf Free-Tier Azure-App**
|
|
|
|
Azure-Apps haben per default Rate-Limits auf den Token-Endpoint. Bei vielen
|
|
Usern gleichzeitig (Token-Refresh alle ~55min pro User) koennte das ein Problem
|
|
werden. Grenzwert: 30 Requests/Sekunde per App fuer `/token`-Endpoint.
|
|
Bei 1000 aktiven Outlook-Usern: ~18 Refreshes/Minute → kein Problem. Bei 10.000
|
|
Users: Grenzwert naeherungsweise erreicht. Fruehzeitig Azure-Subscription-Limit
|
|
pruefen.
|
|
|
|
**2. Token-Rotation race condition im IDLE-Daemon**
|
|
|
|
Wenn mehrere IDLE-Sessions parallel starten (z.B. nach Daemon-Restart) und alle
|
|
gleichzeitig ein abgelaufenes Token refreshen wollen, koennen race conditions
|
|
entstehen: doppelter Refresh → alter refresh_token ungueltig → zweite Session
|
|
failt. Loesung: DB-Lock oder last-writer-wins mit Timestamp-Check.
|
|
|
|
**3. Consumer-Tenant Consent-Screen**
|
|
|
|
Beim ersten OAuth-Login sieht der User den Microsoft-Consent-Screen mit der
|
|
Formulierung "Rebreak moechte auf dein Postfach zugreifen". Fuer manche User
|
|
(besonders aengstliche) koennte das abschreckend wirken. Das ist kein technisches
|
|
Risiko aber ein UX-Risiko — der Datenschutz-Hinweis im Sheet muss das vorab
|
|
erklaeren.
|
|
|
|
**4. App-Registrierung: Publisher-Verification**
|
|
|
|
Microsoft kann nicht-verifizierte Publisher-Apps auf dem Consent-Screen als
|
|
"unverified" markieren. Fuer Produktivbetrieb sollte Publisher-Verification in
|
|
Azure abgeschlossen werden (Domain-Verifikation von rebreak.org). Aufwand: ~1 Tag
|
|
einmalig. Ohne Verifikation funktioniert der Flow trotzdem, aber der Consent-
|
|
Screen zeigt "unverified publisher" — schlechtes Vertrauen.
|
|
|
|
**5. Apple App-Store-Review: OAuth-Flows**
|
|
|
|
OAuth-Flows in iOS-Apps koennen zu App-Store-Review-Verzoegerungen fuehren wenn
|
|
der Reviewer nicht einen echten Microsoft-Account zum Testen hat. Testaccount
|
|
fuer Review bereitstellen (outlook.com-Testaccount mit Gambling-Mails).
|
|
|
|
**6. Kein App-Review bei Microsoft selbst erforderlich**
|
|
|
|
"Personal Microsoft accounts only"-Apps brauchen keine Microsoft-seitige
|
|
Freigabe. Kein Warten auf MS-Approval.
|
|
|
|
---
|
|
|
|
## 6. Abhaengigkeiten und naechste Schritte
|
|
|
|
### Sofortige Eskalationen
|
|
|
|
1. **rebreak-backend**: Schema-Migration fuer 4 neue Felder in `MailConnection`.
|
|
Neue Felder: `auth_method`, `oauth_access_token`, `oauth_refresh_token`,
|
|
`oauth_token_expiry`. Migration kann non-destructive (additive) sein.
|
|
|
|
2. **hans-mueller**: DSGVO-Review der Token-Speicherung (Abschnitt 4). Insbesondere:
|
|
Microsoft als Sub-AV ins VVT aufnehmen, Datenschutzerklaerung anpassen
|
|
(refresh_token = persistenter Zugriff), Revocations-Pflicht bei Loeschung.
|
|
|
|
### Entscheidung vor Implementierungsstart
|
|
|
|
- Azure-Account + App-Registrierung: wer legt an? (ops-Aufgabe)
|
|
- client_id + client_secret: werden via Infisical verwaltet (klar), aber
|
|
Infisical-Secret-Naming vorab festlegen.
|
|
- Redirect-URI-Schema (`msauth.org.rebreak.app`): muss in `app.json` registriert
|
|
sein bevor iOS-Build fuer Tests.
|
|
|
|
### Kein Handlungsbedarf bis Schema-Migration done
|
|
|
|
Die Backend-Endpoints koennen erst nach dem Schema-Change implementiert werden.
|
|
Warten auf rebreak-backend, dann direkt loslegen.
|
|
|
|
---
|
|
|
|
## 7. Was wir heute sofort tun koennen (ohne Schema-Change)
|
|
|
|
Unabhaengig vom OAuth-Implementierungs-Timeline:
|
|
|
|
1. **ConnectMailSheet**: Outlook-Tile sofort deaktivieren oder Hinweis einblenden
|
|
"Outlook wird bald unterstuetzt". Besser als den User einen Fehler erleben
|
|
lassen ("AUTHENTICATIONFAILED" nach Eingabe eines App-Passworts das sowieso
|
|
nicht funktioniert). Das ist eine UI-Aenderung fuer native-ui-agent.
|
|
|
|
2. **imap-providers.ts**: `isOAuthRequired`-Flag fuer Outlook-Domains vorbereiten,
|
|
damit connect.post.ts frueizeitig auf "oauth not yet implemented" antworten
|
|
kann statt mit generischem Auth-Fehler zu failen.
|
|
|
|
Diese zwei Punkte koennen vor der Schema-Migration deployed werden.
|