feat(auth): add MFA factors policy card - #3166
Merged
Merged
Conversation
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.
Console (appwrite/console)Project ID: Tip SSR frameworks are fully supported with configurable build runtimes |
Contributor
Greptile SummaryThe 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.
Confidence Score: 5/5The 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
Reviews (3): Last reviewed commit: "fix(usage): scope the executions breakdo..." | Re-trigger Greptile |
…cy-card # Conflicts: # bun.lock
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.
Meldiron
approved these changes
Aug 17, 2026
`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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

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()omitsmfa-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/consolebuild was 15.3.0 and predates it. This bumps the pin toed09983(16.0.0), which is a major release; the first commit carries the resulting migration:Healthservice removedModels.CloudLocale→Models.LocalecreateTextEmbeddingsmoved offVectorsDBEmbeddingsserviceUsageProject.executionsBreakdownremovedUsage.listEvents)resourceIdsplitdatabaseId+collectionId;csvImportBoxreadsparentResourceId+resourceIdModels.Database.typeis now the SDKDatabaseTypeenumtoDatabaseType()narrows at the boundaryThe SDK enum adds
mysql,postgresql, andmongodb— dedicated backings this console has no UI for. Rather than widening the local union, it is nowExtract<...>-ed from the SDK enum so a renamed or dropped value breaks theswitchcases 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), andbun run buildall pass. Warning counts are unchanged from the pre-bump baseline (91 / 319).bun install --frozen-lockfilesucceeds.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 asexecutionsTotal; it now comes fromUsage.listEventsplus afunctions.listcall to resolve names, capped at 25 rows ordered by value. It needs a sanity check against a project with real execution history.Notes
bun installdropped thesha512-integrity hashes from the threepkg.vcentries inbun.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 highreports 4 high advisories (nanoid,js-yamlviaeslint). These are unchanged frommain— the lockfile diff touches only the three appwrite entries — and want a separate fix.