Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

164 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PRD — Microsoft 365 Inbound Email Diagnostics
- Slug: `microsoft-365-inbound-email-diagnostics`
- Date: `2025-12-31`
- Status: Draft
## Summary
Add a Microsoft 365 (Entra ID + Exchange Online) diagnostics tool inside the Admin email setup UI to help customers self-diagnose OAuth, mailbox access, folder access, and webhook subscription creation issues. The diagnostics should produce an actionable, copy/pasteable “support bundle” with Graph correlation IDs and concrete remediation steps (scopes, mailbox permissions, folder selection).
## Problem
Inbound email for Microsoft 365 relies on:
1. User OAuth consent (delegated permissions)
2. Selecting a mailbox (user mailbox or shared mailbox)
3. Resolving a folder to monitor (typically Inbox)
4. Creating a Microsoft Graph webhook subscription to the folders messages
Customers frequently fail at steps 24 due to:
- Insufficient OAuth scopes or missing admin consent
- Lack of delegated access to a shared mailbox/folder
- Mailbox is not a mailbox (group/contact) or is not provisioned/initialized
- Folder selection/resolution mismatch (“Inbox not found”, non-English display names, custom folder, etc.)
Today we surface generic errors (e.g. Graph `404 ExtensionError` “Default folder Inbox not found”) without enough context for the customer to resolve the issue independently.
## Goals
- Provide an in-app, Microsoft-only diagnostics workflow that:
- Runs deterministic Graph preflight checks.
- Classifies failures (401/403/404/429/etc.) with targeted recommendations.
- Shows the exact mailbox path decision (`/me` vs `/users/{mailbox}`) and why.
- Helps resolve folder issues by enumerating folders and identifying the selected folder.
- Produces a redacted “support bundle” including Graph `request-id` / `client-request-id`.
- Reduce support tickets and time-to-resolution for Microsoft inbound email setup.
## Non-goals
- Build a standalone CLI tool (diagnostics must be in-app first).
- Add Google/Gmail diagnostics (this plan is Microsoft-only).
- Replace or redesign the OAuth flow itself (only add observability + diagnostics around it).
- Persist or display raw access tokens/refresh tokens to end users.
## Users and Primary Flows
### Persona: Tenant Admin setting up inbound email
1. Admin opens Admin → Email Settings → Inbound Email Providers.
2. Admin selects a Microsoft provider and clicks “Run Microsoft 365 diagnostics”.
3. The app runs checks and renders results step-by-step:
- Green/Yellow/Red status per check
- Key facts (tenant id, authorized user, target mailbox, target folder)
- Suggested fixes (missing scopes, mailbox permissions, choose different folder, provisioning hints)
4. Admin copies the “support bundle” and shares it with support if needed.
### Persona: Support engineer assisting customer
1. Customer provides the support bundle.
2. Support uses Graph request IDs + error classification to quickly identify likely root cause.
## UX / UI Notes
- Entry point: add a “Diagnostics” action for Microsoft providers in the existing admin email provider configuration UI.
- Output format:
- A compact table/list of checks with status, duration, and expandable details.
- A single “Copy support bundle” action (JSON and/or text) with redaction applied.
- Include warnings for actions that may create/renew subscriptions.
- Keep diagnostics results ephemeral (in-memory response) unless explicitly saved by an admin.
## Requirements
### Functional Requirements
Diagnostics should run a checklist of Microsoft Graph checks using the providers stored OAuth tokens and configuration, including:
- Token validity and expiry (preflight)
- Decoded token claims for customer visibility (scopes, tenant id, delegated vs app)
- Graph connectivity to `/me`
- Mailbox base path decision (`/me` vs `/users/{mailbox}`), and validation that the chosen mailbox exists/works
- Folder reachability:
- Prefer Graph well-known folder endpoint (`.../mailFolders/inbox`)
- Enumerate available folders if Inbox/folder resolution fails
- Determine whether the configured folder is resolvable by id or display name
- Message read preflight for the exact target resource we intend to subscribe to
- Error classification with actionable suggestions
- Correlation identifiers:
- Capture Graph `request-id` from response headers/errors
- Set and capture `client-request-id` for each request
### Non-functional Requirements
- Safety:
- Do not leak secrets (tokens, client secrets) in UI output or support bundle.
- Diagnostics must be restricted to authorized admin users.
- Performance:
- End-to-end diagnostics should complete in ~1020 seconds in normal conditions.
- Concurrency limits to prevent a tenant from triggering excessive Graph calls.
- Reliability:
- Each step should fail independently and record its own error context.
- Compatibility:
- Must support both personal mailbox (`/me`) and shared/delegated mailbox (`/users/{mailbox}`).
## Data / API / Integrations
### New server-side entrypoint
Add a server action (or admin API route) like:
- `runMicrosoft365Diagnostics(providerId: string, options?: DiagnosticsOptions): Promise<DiagnosticsReport>`
Where `DiagnosticsReport` includes:
- `summary` (overall status + key facts)
- `steps[]` (ordered checks; each with status, timing, sanitized request/response metadata)
- `recommendations[]` (deduplicated)
- `supportBundle` (redacted JSON payload)
### Adapter integration
Implement Microsoft-specific diagnostic helpers close to existing Graph logic:
- Add a diagnostics method to `shared/services/email/providers/MicrosoftGraphAdapter.ts` that:
- Reuses the existing authenticated HTTP client (including token refresh).
- Emits structured diagnostic step results.
- Adds `client-request-id` on every Graph request for correlation.
## Security / Permissions
- Diagnostics UI only visible to tenant admins (same access level as provider setup).
- Redaction rules:
- Access/refresh tokens: never shown; optionally show fingerprint (first 4 + length).
- Client secrets: never shown.
- Email addresses: show fully to the tenant admin (tenant-owned), but redact in the exported “support bundle” unless the admin explicitly opts in.
- Avoid storing diagnostics results in DB by default.
## Observability
- For each diagnostic step log structured events including:
- provider id, tenant id, mailbox, folder, step id, duration, outcome
- Graph `request-id` / `client-request-id`
- Sanitized error code/status/message
- Ensure the UI can display the Graph `request-id` prominently when failures occur.
## Rollout / Migration
- Feature-gated behind “Microsoft 365 Diagnostics” flag (tenant-level or global) if available; otherwise ship as admin-only UI.
- No DB migrations required unless we later choose to persist diagnostics runs.
## Open Questions
1. Should the diagnostics include an optional “subscription create/delete” live test, or remain read-only (preflight GETs only)?
2. Should the exported support bundle include mailbox address by default, or redact unless “Include identifiers” is toggled?
3. What exact OAuth scopes do we currently request for Microsoft inbound email, and do we want diagnostics to assert a minimum set?
4. Do we support national cloud endpoints (GCC/DoD), or only `graph.microsoft.com` public cloud?
## Acceptance Criteria (Definition of Done)
- Admins can run Microsoft 365 diagnostics for a configured Microsoft inbound email provider from the UI.
- Diagnostics provide clear pass/fail results for mailbox + folder reachability and token/scope visibility.
- Known failure modes (401/403/404 Inbox not found/429) produce targeted recommendations.
- A “support bundle” can be copied/exported and includes Graph correlation IDs while redacting secrets.