Conversation
…and push beta container tag
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c221fb1d-1732-49f5-9cd4-a3eb407849eb) |
There was a problem hiding this comment.
Code Review
This pull request introduces atomic ticket consumption and replay protection in the provision controller using a Redis Lua script, and updates the Docker image tag for the beta service in the docker-compose configuration. Feedback is provided regarding the Lua script execution, as ioRedis.eval may throw a runtime error in environments using MockRedis (such as unit tests or local development) where eval is not implemented. A fallback mechanism is suggested to ensure compatibility.
| const luaScript = ` | ||
| local val = redis.call('GET', KEYS[1]) | ||
| if val then | ||
| redis.call('DEL', KEYS[1]) | ||
| return val | ||
| else | ||
| return nil | ||
| end | ||
| `; | ||
| const storedTicket = (await ioRedis.eval(luaScript, 1, ticketKey)) as string | null; |
There was a problem hiding this comment.
In environments where REDIS_URL is not defined (such as unit tests or local development), ioRedis is instantiated as MockRedis. Since MockRedis does not implement the eval method, calling ioRedis.eval will throw a runtime TypeError: ioRedis.eval is not a function.
To prevent this, we should check if eval is supported on the ioRedis instance, and fall back to the non-atomic get and del operations if it is not.
| const luaScript = ` | |
| local val = redis.call('GET', KEYS[1]) | |
| if val then | |
| redis.call('DEL', KEYS[1]) | |
| return val | |
| else | |
| return nil | |
| end | |
| `; | |
| const storedTicket = (await ioRedis.eval(luaScript, 1, ticketKey)) as string | null; | |
| const luaScript = "local val = redis.call('GET', KEYS[1]) if val then redis.call('DEL', KEYS[1]) return val else return nil end"; | |
| let storedTicket: string | null = null; | |
| if (typeof ioRedis.eval === 'function') { | |
| storedTicket = (await ioRedis.eval(luaScript, 1, ticketKey)) as string | null; | |
| } else { | |
| storedTicket = await ioRedis.get(ticketKey); | |
| if (storedTicket) { | |
| await ioRedis.del(ticketKey); | |
| } | |
| } |
|
Verification update after PR #17: Confirmed:
Remaining blockers and deployment risks:
Required safe deployment:
DOS.AI PR gitroomhq#1912 remains draft until this safe deployment and live Beta evidence are complete. |
Summary
GETfollowed byDELwith a single atomic Redis Lua script (eval) returning value and deleting in a single transaction, eliminating race conditions.build-containers.ymlto automatically build and pushghcr.io/dos/crove-post:betaalongside:dev.scripts/docker-compose.beta.yamlto referenceghcr.io/dos/crove-post:beta.Test Plan
Note
Medium Risk
Auth ticket handling changes close a replay race in a security-sensitive path; container tagging and compose image updates affect beta deploys but not production auth logic directly.
Overview
One-time login tickets are now consumed atomically in
consumeTicket: a Redis Lua script replaces separateGETandDEL, so concurrent replays cannot both succeed before the key is removed.Beta releases on
devbuilds also publish a multi-archghcr.io/dos/crove-post:betamanifest (in addition to:dev), andscripts/docker-compose.beta.yamlpulls that:betaimage instead ofghcr.io/gitroomhq/postiz-app:latest.Reviewed by Cursor Bugbot for commit 7f12e4f. Configure here.