Skip to content

fix: resolve LNURL-pay usernames case-insensitively (#3058)#3115

Open
protivon wants to merge 1 commit into
stackernews:masterfrom
protivon:fix/lnurlp-username-case-insensitive
Open

fix: resolve LNURL-pay usernames case-insensitively (#3058)#3115
protivon wants to merge 1 commit into
stackernews:masterfrom
protivon:fix/lnurlp-username-case-insensitive

Conversation

@protivon

Copy link
Copy Markdown

Description

Fixes #3058. Paying a mixed-case Lightning address such as SwapMarket@stacker.news returned "user @SwapMarket does not exist", while the lowercase form worked.

Both LNURL-pay endpoints resolved the recipient with:

models.user.findUnique({ where: { name: username } })

The users.name column is Citext, so equality in Postgres is case-insensitive — but Prisma's findUnique on the unique key does not reliably fold case for the bound parameter here, so a mixed-case username from the URL missed the row. The codebase already compensates for this elsewhere by comparing names with .toUpperCase() (see api/resolvers/user.js).

This PR makes the two LNURL-pay lookups explicitly case-insensitive:

models.user.findFirst({ where: { name: { equals: username, mode: 'insensitive' } } })

in pages/api/lnurlp/[username]/index.js (the LNURL-pay metadata response) and pages/api/lnurlp/[username]/pay.js (the invoice/callback). Any casing of an existing username now resolves to the same account.

Screenshots

N/A — server-side payment-resolution fix, no UI change.

Additional Context

name is both @unique and Citext, so a case-insensitive match returns at most one row; findFirst is therefore equivalent to findUnique for valid data while tolerating casing. This cannot create users or change who an address maps to — it only lets an already-existing recipient be found regardless of the sender's casing.

Checklist

Are your changes backward compatible? Please answer below:

Yes. Lowercase addresses behave exactly as before; only previously-failing mixed-case lookups now succeed. No schema, GraphQL, or API-shape changes.

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:

7/10. Verified the root cause by reading the schema (name … @db.Citext, line 19 of prisma/schema.prisma) and confirming both LNURL-pay routes used the case-sensitive findUnique. Confirmed mode: 'insensitive' is supported on the project's Prisma 5.20 findFirst. Both changed files pass node --check. I did not spin up the full stack to send a live mixed-case LNURL payment, so an end-to-end test against a running node would be the remaining QA step.

For frontend changes: Tested on mobile, light and dark mode? Please answer below:

N/A — no frontend changes.

LNURL-pay (`/api/lnurlp/[username]` and `.../pay`) looked the recipient up
with `models.user.findUnique({ where: { name: username } })`. Despite `name`
being a Citext column, this lookup did not reliably fold case, so paying a
mixed-case Lightning address such as `SwapMarket@stacker.news` returned
"user does not exist" while `k00b@stacker.news` worked.

Use a case-insensitive lookup (`findFirst` with `mode: 'insensitive'`) in both
the LNURL-pay metadata route and the pay route so any casing of an existing
username resolves to the same account. No new users can be created by this, and
since `name` is unique+Citext there is at most one match.
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.

bug report: lnurl request fails for usernames with upper case letters

1 participant