Skip to content

feat(auth): add MFA factors policy card - #3166

Merged
HarshMN2345 merged 5 commits into
mainfrom
feat-mfa-factors-policy-card
Aug 17, 2026
Merged

feat(auth): add MFA factors policy card#3166
HarshMN2345 merged 5 commits into
mainfrom
feat-mfa-factors-policy-card

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

Adds the project-level MFA factors policy card to Auth → Security, so the new custom MFA factor is configurable from the console.

Appwrite generates and verifies the second-factor code without sending it; the app delivers it over whatever channel it likes (WhatsApp, Telegram, a voice call, a push notification). The card exposes all four factors — TOTP, email, phone, and custom — backed by PATCH /v1/project/policies/mfa-factors.

The card is hidden when listPolicies() omits mfa-factors, so a self-hosted server older than 1.9.6 never renders a control whose PATCH would 404.

SDK bump

The endpoint is in the published 1.9.x console spec (spec version 1.9.6, live on Cloud), but the pinned @appwrite.io/console build was 15.3.0 and predates it. This bumps the pin to ed09983 (16.0.0), which is a major release; the first commit carries the resulting migration:

Change in 16.0.0 Migration
Health service removed Dropped from the SDK store — it was registered but never called
Models.CloudLocaleModels.Locale Type annotation swap in 7 billing/address components; fields are identical
createTextEmbeddings moved off VectorsDB Now via the new Embeddings service
UsageProject.executionsBreakdown removed Re-sourced from the dimensional usage API (Usage.listEvents)
Composite resourceId split Import/export calls now send databaseId + collectionId; csvImportBox reads parentResourceId + resourceId
Models.Database.type is now the SDK DatabaseType enum Local union extracted from the SDK enum; toDatabaseType() narrows at the boundary

The SDK enum adds mysql, postgresql, and mongodb — dedicated backings this console has no UI for. Rather than widening the local union, it is now Extract<...>-ed from the SDK enum so a renamed or dropped value breaks the switch cases instead of drifting silently. toDatabaseType() throws on the unsupported ones, matching the entity dispatchers in (entity)/helpers/sdk.ts, which already threw on an unknown type.

Verification

bun run check (0 errors), bun run lint (0 errors), bun run test:unit (239 passing), and bun run build all pass. Warning counts are unchanged from the pre-bump baseline (91 / 319). bun install --frozen-lockfile succeeds.

Please review the usage breakdown change most closely — it is the one piece that is not a mechanical rename. The old per-function table arrived inside the same getUsage() response as executionsTotal; it now comes from Usage.listEvents plus a functions.list call to resolve names, capped at 25 rows ordered by value. It needs a sanity check against a project with real execution history.

Notes

  • bun install dropped the sha512- integrity hashes from the three pkg.vc entries in bun.lock (bun 1.3.8). The frozen install still passes, but it is worth regenerating if CI pins a different bun.
  • bun audit --audit-level high reports 4 high advisories (nanoid, js-yaml via eslint). These are unchanged from main — the lockfile diff touches only the three appwrite entries — and want a separate fix.

The 1.9.6 console spec adds the mfa-factors project policy, which the
pinned 15.3.0 build predates.

The major bump also removes the Health service (registered in the SDK
store but never called), renames Models.CloudLocale to Models.Locale,
moves createTextEmbeddings from VectorsDB to a new Embeddings service,
drops UsageProject.executionsBreakdown in favour of the dimensional
usage API, and splits the composite `databaseId:collectionId` migration
resourceId into resourceId plus parentResourceId.

Models.Database.type is now the SDK's DatabaseType enum, which also
covers the dedicated backings (mysql, postgresql, mongodb) this console
has no UI for. The local union is extracted from the SDK enum so a
renamed or dropped value breaks the switches instead of drifting
silently, and toDatabaseType() narrows at the boundary — matching the
entity dispatchers, which already throw on an unknown type.
Lets a project choose which factors can complete an MFA challenge,
including the new custom factor, where Appwrite generates and verifies
the code and the app delivers it over a channel of its own.

The card stays hidden when listPolicies() omits mfa-factors, so a
self-hosted server older than 1.9.6 does not render a control whose
PATCH would 404.
@appwrite

appwrite Bot commented Aug 17, 2026

Copy link
Copy Markdown

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

SSR frameworks are fully supported with configurable build runtimes

@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds project-level MFA-factor policy controls and upgrades the console SDK, including the required database, embeddings, locale, CSV migration, and usage API adaptations.

  • Adds an MFA factors card for TOTP, email, phone, and custom factors, hidden when unsupported by the server.
  • Gates MFA policy controls and submission on the project write scope.
  • Replaces the removed execution breakdown field with dimensional usage events and function-name resolution.
  • Migrates affected SDK calls and model types to the 16.0.0 API.

Confidence Score: 5/5

The PR appears safe to merge.

The previously reported permission failure is addressed by applying the established project-write gate to every MFA factor control and the submit button, and no blocking failure remains.

Important Files Changed

Filename Overview
src/routes/(console)/project-[region]-[project]/auth/security/updateMfaFactors.svelte Adds the MFA-factor policy form and now consistently disables its controls and submit action when the member lacks project write access.
src/routes/(console)/project-[region]-[project]/auth/security/+page.ts Loads the optional MFA factors policy while preserving compatibility with servers that omit it.
src/routes/(console)/project-[region]-[project]/auth/security/+page.svelte Conditionally renders the MFA factors policy card only when the policy is available.
src/lib/sdk/usage.ts Reconstructs per-function execution totals from dimensional usage events and resolves display names in a bounded function query.
src/lib/stores/sdk.ts Migrates SDK service registration by removing Health and adding Embeddings and Usage.
src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.ts Integrates the new asynchronous execution-breakdown source into usage-page loading.
src/lib/components/csvImportBox.svelte Adapts CSV migration tracking to the SDK's split parent and resource identifiers.

Reviews (3): Last reviewed commit: "fix(usage): scope the executions breakdo..." | Re-trigger Greptile

Matches the project settings cards, which disable their controls on
!$canWriteProjects rather than letting a read-only member submit a
request the API rejects.

Also fills in labels, installationScopes, and installationRedirectUrl on
the App literal built from a CIMD document. Those three became required
on Models.App in SDK 16 and a CIMD document carries none of them, so
they take the same empty defaults as the other fields the document
does not provide.
`executions` is the umbrella metric covering both functions and sites,
but the table it feeds is headed "Function" and links each row to
/functions/function-{resourceId}. A project with a trafficked site would
get rows showing a raw site ID, unresolvable by functions.list, linking
to a function that does not exist. `functions.executions` is the metric
that matches the table.

Fold the call into the load function's existing Promise.all so it no
longer serialises behind the invoice and usage requests, and report a
failure through trackError instead of swallowing it — a 403 or a
malformed response was previously indistinguishable from a project with
no executions.

Drop the duplicate database-type read in the collection layout, which
recomputed locally what the component already derives.
@HarshMN2345
HarshMN2345 merged commit f8b969c into main Aug 17, 2026
3 of 4 checks passed
@HarshMN2345
HarshMN2345 deleted the feat-mfa-factors-policy-card branch August 17, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants