[ { "id": "F001", "description": "Add Microsoft provider card to Settings -> Integrations -> Providers.", "implemented": true, "prdRefs": ["Functional Requirements #1"] }, { "id": "F002", "description": "Create `getMicrosoftIntegrationStatus` action returning masked status plus derived redirect URI/scope metadata.", "implemented": true, "prdRefs": ["Functional Requirements #2"] }, { "id": "F003", "description": "Create `saveMicrosoftIntegrationSettings` action with validation for client ID, client secret, and optional tenant ID.", "implemented": true, "prdRefs": ["Functional Requirements #2", "Functional Requirements #3"] }, { "id": "F004", "description": "Create `resetMicrosoftProvidersToDisconnected` action to clear Microsoft provider connection state/tokens for tenant providers.", "implemented": true, "prdRefs": ["Functional Requirements #2"] }, { "id": "F005", "description": "Export new Microsoft integration actions from integrations action entrypoints used by settings UI.", "implemented": true, "prdRefs": ["Functional Requirements #2"] }, { "id": "F006", "description": "Persist `microsoft_client_id` as tenant secret from Providers settings.", "implemented": true, "prdRefs": ["Functional Requirements #3"] }, { "id": "F007", "description": "Persist `microsoft_client_secret` as tenant secret from Providers settings.", "implemented": true, "prdRefs": ["Functional Requirements #3"] }, { "id": "F008", "description": "Persist `microsoft_tenant_id` as tenant secret with default `common` when omitted.", "implemented": true, "prdRefs": ["Functional Requirements #3"] }, { "id": "F009", "description": "Render masked saved-secret indicators in Microsoft settings status response/UI.", "implemented": true, "prdRefs": ["Acceptance Criteria #2"] }, { "id": "F010", "description": "Enforce RBAC (`system_settings:update`) on Microsoft settings save/reset actions.", "implemented": true, "prdRefs": ["Security / Permissions"] }, { "id": "F011", "description": "Restrict Microsoft settings actions from client portal user context.", "implemented": true, "prdRefs": ["Security / Permissions"] }, { "id": "F012", "description": "Add provider-readiness check helper for Microsoft (`microsoft_client_id` + `microsoft_client_secret`).", "implemented": true, "prdRefs": ["Functional Requirements #5"] }, { "id": "F013", "description": "Add provider-readiness check helper for Google (`google_client_id` + `google_client_secret`) for MSP SSO usage.", "implemented": true, "prdRefs": ["Functional Requirements #5"] }, { "id": "F014", "description": "Update CE Microsoft email form to remove required manual client ID/client secret inputs.", "implemented": true, "prdRefs": ["Functional Requirements #12"] }, { "id": "F015", "description": "Update CE Microsoft email form to display 'Configure Providers first' CTA when Microsoft provider settings are missing.", "implemented": true, "prdRefs": ["Functional Requirements #12"] }, { "id": "F016", "description": "Update CE Microsoft calendar form to use provider-settings-first behavior and CTA when Microsoft settings are missing.", "implemented": true, "prdRefs": ["Functional Requirements #12"] }, { "id": "F017", "description": "Ensure CE Microsoft email provider persistence no longer depends on per-provider client credential form fields.", "implemented": true, "prdRefs": ["Functional Requirements #12"] }, { "id": "F018", "description": "Ensure CE Microsoft calendar provider persistence no longer depends on per-provider client credential form fields.", "implemented": true, "prdRefs": ["Functional Requirements #12"] }, { "id": "F019", "description": "Replace CE SSO button stub with MSP-login-capable SSO buttons component.", "implemented": true, "prdRefs": ["Functional Requirements #9", "Acceptance Criteria #3"] }, { "id": "F020", "description": "Require non-empty email before enabling MSP SSO buttons.", "implemented": true, "prdRefs": ["UX / UI Notes", "Acceptance Criteria #3"] }, { "id": "F021", "description": "Wire Microsoft MSP button to resolver + NextAuth OAuth flow.", "implemented": true, "prdRefs": ["Primary Flow A", "Primary Flow B"] }, { "id": "F022", "description": "Wire Google MSP button to resolver + NextAuth OAuth flow.", "implemented": true, "prdRefs": ["Primary Flow A", "Primary Flow B"] }, { "id": "F023", "description": "Show one generic resolver/start failure message across all failure reasons.", "implemented": true, "prdRefs": ["Security / Permissions", "Acceptance Criteria #5"] }, { "id": "F024", "description": "Keep client portal login SSO behavior unchanged (no new SSO buttons/flow).", "implemented": true, "prdRefs": ["Non-goals", "Acceptance Criteria #8"] }, { "id": "F025", "description": "Add unauthenticated `POST /api/auth/msp/sso/resolve` endpoint.", "implemented": true, "prdRefs": ["Data / API / Integrations"] }, { "id": "F026", "description": "Validate/normalize resolver input (`provider`, `email`, `callbackUrl`) and reject malformed requests generically.", "implemented": true, "prdRefs": ["Data / API / Integrations", "Security / Permissions"] }, { "id": "F027", "description": "Resolver performs internal-user lookup by normalized email for source selection only.", "implemented": true, "prdRefs": ["Functional Requirements #4", "Functional Requirements #5"] }, { "id": "F028", "description": "Resolver chooses tenant source when user exists and tenant provider is configured for selected provider.", "implemented": true, "prdRefs": ["Functional Requirements #5"] }, { "id": "F029", "description": "Resolver chooses app fallback source when tenant source is not available but app fallback keys are available.", "implemented": true, "prdRefs": ["Functional Requirements #5"] }, { "id": "F030", "description": "Resolver applies same external behavior for unknown user as known-user-missing-provider paths.", "implemented": true, "prdRefs": ["Functional Requirements #6", "Security / Permissions"] }, { "id": "F031", "description": "Resolver returns identical response schema and status across lookup outcomes.", "implemented": true, "prdRefs": ["Functional Requirements #6", "Functional Requirements #7"] }, { "id": "F032", "description": "Resolver sets signed, short-lived httpOnly context cookie with source metadata.", "implemented": true, "prdRefs": ["Functional Requirements #7"] }, { "id": "F033", "description": "Resolver context cookie excludes raw client IDs/secrets.", "implemented": true, "prdRefs": ["Functional Requirements #7", "Security / Permissions"] }, { "id": "F034", "description": "Resolver uses app fallback keys `MICROSOFT_OAUTH_*` for Microsoft fallback source.", "implemented": true, "prdRefs": ["Functional Requirements #5", "Secret keys"] }, { "id": "F035", "description": "Resolver uses app fallback keys `GOOGLE_OAUTH_*` for Google fallback source.", "implemented": true, "prdRefs": ["Functional Requirements #5", "Secret keys"] }, { "id": "F036", "description": "Resolver returns generic failure when neither tenant source nor app fallback is available.", "implemented": true, "prdRefs": ["Primary Flow C"] }, { "id": "F037", "description": "Add basic resolver endpoint rate limiting keyed by request IP + normalized email hash bucket.", "implemented": true, "prdRefs": ["Non-functional Requirements #2"] }, { "id": "F038", "description": "Add sanitized structured logs for resolver decisions/failures without user-existence leakage.", "implemented": true, "prdRefs": ["Observability", "Non-functional Requirements #3"] }, { "id": "F039", "description": "Allow CE MSP OAuth provider registration by removing effective EE-only gating for Google/Microsoft in NextAuth options path.", "implemented": true, "prdRefs": ["Functional Requirements #9"] }, { "id": "F040", "description": "Refactor auth options caching so OAuth provider credentials can be resolved per request (remove/alter static cache).", "implemented": true, "prdRefs": ["Functional Requirements #11"] }, { "id": "F041", "description": "Update OAuth secret resolution to read resolver context cookie and select tenant source when requested and valid.", "implemented": true, "prdRefs": ["Functional Requirements #8"] }, { "id": "F042", "description": "When resolver context is absent/invalid/expired, fall back to app-level OAuth keys only.", "implemented": true, "prdRefs": ["Functional Requirements #13"] }, { "id": "F043", "description": "Validate resolver cookie signature and TTL before applying tenant selection.", "implemented": true, "prdRefs": ["Non-functional Requirements #1"] }, { "id": "F044", "description": "Overwrite resolver cookie on each new start attempt with short TTL to minimize stale context.", "implemented": true, "prdRefs": ["Non-functional Requirements #1"] }, { "id": "F045", "description": "Add CE-safe OAuth profile mapping helper for MSP internal users (Google + Microsoft) in auth package.", "implemented": true, "prdRefs": ["Functional Requirements #10"] }, { "id": "F046", "description": "Use CE-safe mapper in provider profile callbacks when edition is community.", "implemented": true, "prdRefs": ["Functional Requirements #10"] }, { "id": "F047", "description": "Preserve existing EE registry-based mapper path when edition is enterprise.", "implemented": true, "prdRefs": ["Functional Requirements #10"] }, { "id": "F048", "description": "Ensure CE MSP OAuth sign-in path does not require EE-only account-link persistence to succeed.", "implemented": true, "prdRefs": ["Non-goals", "Acceptance Criteria #7"] }, { "id": "F049", "description": "Ensure Microsoft tenant ID selection for OAuth issuer/authorization defaults to `common` when tenant value is empty.", "implemented": true, "prdRefs": ["Secret keys", "Functional Requirements #3"] }, { "id": "F050", "description": "Document in code comments that resolver lookup result must never be surfaced to client-facing messages.", "implemented": true, "prdRefs": ["Security / Permissions"] }, { "id": "F051", "description": "Update `.env.example` comments to indicate `GOOGLE_OAUTH_*` and `MICROSOFT_OAUTH_*` can be used for CE MSP SSO fallback.", "implemented": true, "prdRefs": ["Rollout / Migration"] }, { "id": "F052", "description": "Add/update developer docs for provider setup order: Providers settings first, then Microsoft/Google integration-level connection.", "implemented": true, "prdRefs": ["UX / UI Notes", "Acceptance Criteria #9"] } ]