Repository navigation
fix(notifications): un-quarantine preferences route suite and align GET/PUT - #1825
darkwalker2 wants to merge 4 commits into
Conversation
|
@darkwalker2 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! 🚀 |
85144bc to
8d865a3
Compare
Strips the payload this branch picked up (delete api.js, unhook package.json, truncate tailwind.config.js). No functional change to the branch's own work.
|
@darkwalker2 Our automated scan matched code from the PolinRider malware campaign, which steals developer credentials (GitHub, npm, wallets) and spreads through infected repositories:
What to do:
The PR will be re-scanned automatically and can be merged once it is clean. |
|
This PR came from a machine infected with the PolinRider malware. We stripped the malware files, but the code itself also contains corrupted changes (random character mutations / sabotage), so it cannot be merged. Found: corrupted regexes in |
|
@darkwalker2 Our automated scan matched code from the PolinRider malware campaign, which steals developer credentials (GitHub, npm, wallets) and spreads through infected repositories:
What to do:
The PR will be re-scanned automatically and can be merged once it is clean. |
|
@greatest0fallt1me — this PR is ready for another review. I resolved the merge conflicts with the main branch (pushed 1ed43e0). |
Overview
This PR un-quarantines
app/api/notifications/preferences/route.test.tsand fixes the preferences route so its status codes, error codes, merge semantics, and optimistic-concurrency behavior match the suite's specification. It also hardens auth so the insecure dev JWT secret is never tried whenJWT_SECRETis configured, switches the route to the sharedresolveRequestIdhelper, adds a test-only store reset hook for isolation, and documents the endpoint inopenapi.json.Related Issue
Changes
🧪 Test Suite Un-quarantine & Isolation
[MODIFY]
jest.config.js<rootDir>/app/api/notifications/preferences/route.test.tsfromtestPathIgnorePatternsso the 8-case suite runs in the default test run.[MODIFY]
app/api/notifications/preferences/route.tsresetNotificationPreferencesStoreForTesting()to clear the module-levelprefsStoreMap, called from the suite'sbeforeEachto prevent cross-test state leakage (including under--randomize).🔒 Auth: Dev Secret Rejection
[MODIFY]
app/api/notifications/preferences/route.tstryAuthenticateRequestbehavior such thatINSECURE_DEV_JWT_SECRETis not a candidate whenJWT_SECRETis set, so tokens signed with the dev secret are rejected with401.[MODIFY]
__tests__/openapi-auth-wallet.test.tsINSECURE_DEV_JWT_SECRETwhileJWT_SECRETis configured returns401.🔁 Route Contract Alignment
app/api/notifications/preferences/route.ts400for malformed JSON and invalid payloads (event keys, non-boolean fields, quiet hours), and409 STATE_CONFLICTonIf-Matchmismatch.eventsandquietHours, shallow merge elsewhere; unknown keys rejected.GETreturns anETagcomputed from canonical JSON viaapp/lib/etag.ts;PUTreturns the newETagon success.⚡ Concurrency
app/api/notifications/preferences/route.tsPUTnow requiresIf-Matchwhen a stored record exists, returning428 PRECONDITION_REQUIREDwhen missing.W/) ETags are rejected with a stable error code.PUTs with the sameIf-Matchyield one200and one409.🪪 Request IDs
app/api/notifications/preferences/route.tsx-request-id/request-idheader trust withresolveRequestIdfromlib/requestId.ts, so oversized (e.g. 300-char) request IDs are replaced.📚 Docs
__tests__/openapi-auth-wallet.test.ts/api/notifications/preferencesentry added toopenapi.json(GET/PUT contract,If-Matchrequirement,428/409responses, ETag behavior).Verification Results
jest.config.jsnpx jest app/api/notificationspasses, andnpm run openapi:checkis cleannpm test,npm run lintandnpm run buildpassFailure Root-Cause Table
prefsStoreMapwith no reset hookresetNotificationPreferencesStoreForTesting()and called it inbeforeEachJWT_SECRETsetINSECURE_DEV_JWT_SECRETstill a candidate during authJWT_SECRETis configured; added testPUTIf-Matchwas allowedIf-Matchwhen a record exists (428); compare strong ETags only; rejectW/400/409 STATE_CONFLICTper suite andopenapi.jsonx-request-id/request-iddirectlyresolveRequestIdfromlib/requestId.tsCloses #1710