Repository navigation
feat(tickets): add ticket lookup, QR image and rotating QR tokens - #460
Merged
EmmanuelOchaje merged 1 commit intoOct 18, 2026
Conversation
|
@c4182657-ship-it Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
✅ Deploy Preview for stellarticketsbackend ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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.
Summary
Adds the ticket lookup, QR image and rotating QR token endpoints from #121, #125 and #129, and a route-level test for the verify rate limit from #131.
Changes
#121 —
GET /tickets/:ticketIdevent,organizationandticketType) to its owner or to members of the event's organization; anyone else gets403, an unknown id404.qrSecret; the owner does.mine,resale,offline-public-keys,by-chain/:id), which a test confirms it does not shadow.#125 —
GET /tickets/:ticketId/qrContent-Type: image/png,Cache-Control: no-store) encoding the ticket'sqrSecret. Owner only: a non-owner, including organization staff, gets403.qrcodedependency (@types/qrcodeas a dev dependency); the lockfile change is limited to it and its transitive packages.@Res(), because the globalBigIntSerializerInterceptorwould flatten a returnedBufferinto a plain object.#129 — rotating QR tokens
QrTokenService.GET /tickets/:ticketId/qr-token(owner only,no-store) issuesv1.<ticketId>.<exp>.<signature>, an HMAC-SHA256 token whose key is derived from the existing JWT signing secret for this purpose only. It is deliberately not a JWT, so it can never be used as a bearer credential. No new secret is required.GET /tickets/verify/:valuenow accepts either a staticqrSecretor one of these tokens. An expired token is rejected with400; a forged or malformed one is404, like an unknown secret.QR_TOKEN_TTL_SECONDS(default 30) andQR_TOKEN_CLOCK_SKEW_SECONDS(default 5, the configurable tolerance) are added to.env.example, the env-docs generator anddocs/CONFIGURATION.md.#131 — verify rate limiting
GET /tickets/verify/:qrSecretis already bound toScanRateLimitGuard(per-IP and per-secret,429past the limit, configurable viaSCAN_RATE_LIMIT_*), with guard unit tests and a metadata test for the binding. No production code changes here.tickets.verify-rate-limit.spec.ts, which sends real HTTP requests through the real guard and an in-memory store and asserts429past the limit without the handler being reached.Docs and generated files
docs/API.md, the README endpoint table andCHANGELOG.mdcover the new routes and settings.npm run docs:apialso wantsstellar/Get Transaction Status.bruandtickets/Build Issue Batch.bru, which were already missing onmainand are unrelated, so they are not included.Tests
qr-token.service.spec.ts(issue/verify, expiry and skew boundaries, tampering, wrong secret, malformed tokens, invalid config) andtickets.verify-rate-limit.spec.ts.tickets.service.spec.ts(findOne,getQrImage,issueQrToken, token path ofverify) andtickets.controller.spec.ts(routes, status codes, headers, PNG body, unauthenticated 401s).Issues
Resolves #131
Resolves #129
Resolves #125
Resolves #121
Verification
Manual code review of the full diff only.
cargo buildandcargo testwere not run (this is not a Rust project), and the new tests and the app itself were not built or executed locally, so CI is their first real run.npm run docs:env -- --checkpasses; formatting of the added code was checked with the repo's pinned prettier version. No snapshots were committed.