Skip to content

Backend: /api/user/identities/verify reports success for unrecognised providers without verifying anything #100

Description

@Adron

Found while wiring the verify route for #92 (see PR #99).

The problem

app/api/user/identities/verify/route.ts dispatches on identity.provider through a chain of if
branches — bluesky, github, mastodon:*, linkedin, twitter. For any provider string that
matches none of them:

  • no branch runs, so nothing is verified
  • the route still stamps lastVerifiedAt
  • it answers 200 {"success":true}

So an unrecognised provider is reported as a healthy, freshly-verified credential.

Why this is reachable, not theoretical

Mastodon identities are stored as mastodon:{instance}, and the branch matches that prefix. But a
bare "mastodon" string — which linkedIdentities can return — matches no branch and takes the
silent-success path. Any provider added to the product in future, or any row written before a naming
convention changed, lands there too.

Why the client cannot compensate

A 200 {"success":true} from a genuine verification and a 200 {"success":true} from the
no-branch-matched path are byte-identical. iOS has no way to distinguish them, so #99 does not try —
it takes the 200 at face value and reports the identity as connected. That means a user with such a
row is told their connection is fine when it has never been checked, which is worse than not
offering the check.

Ask

Make the unrecognised case explicit rather than silently successful. Either:

  1. Return an error — 400/422 with a distinguishable code (e.g. unsupported_provider), so
    the client can say "can't check this one" rather than "verified"; or
  2. Return a success shape that says it didn't check — e.g. {"success":true,"verified":false,"reason":"unsupported_provider"}
    — and do not stamp lastVerifiedAt in that case.

(2) is friendlier to clients that already treat 200 as success. Either way, lastVerifiedAt should
not be written when no verification happened — it currently makes an unchecked credential look
recently confirmed.

Also worth checking while in there

  • Should a bare "mastodon" provider string exist at all? If not, that is a separate data-integrity
    question about what linkedIdentities can return.

iOS follow-up

Once the contract is decided, Models/IdentityHealth.swift gains a third state alongside
connected / needsReconnect — something like "can't check" — and LinkedIdentitiesView renders it.
Small change; blocked on the decision above.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-askNeeds a change in the interlinedlist backendbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions