feat(recover): stolen account recovery step 1#302
Open
ety001 wants to merge 12 commits into
Open
Conversation
Port legacy step-1 UX: validate account, check owner history, then submit recovery request email. Includes owner-history query API and recovery request shim endpoint.
Add unit tests for owner-history + recovery request routes and client helpers to keep coverage threshold green.
- Add CSRF protection to /api/recovery/request route (verifyCSRF) and client (withCSRFHeader), matching legacy checkCSRF behavior - Add CSRF fail test case in recover-request-route.test - Remove unnecessary type assertion on last_owner_update (SteemAccount already has the field) - Add es/zh translations for recoverAccountStep1Page namespace - Add stale-check version counter in validateAccount to prevent onBlur race conditions - Add console.info logging in recovery shim for debugging before backend is wired - Add comment explaining JULY_14_HACK_MS (2016 Steem hack event) - Define OwnerHistoryEntry type in types.ts; use it in server.ts, client.ts, and recover-account-step-1-page.tsx (replaces unknown[] and inline type assertions)
- Replace recovery shim with real DB persistence - Add drizzle-orm, mysql2, and drizzle-kit - Create schema src/lib/db/schema/index.ts (arecs table) - Create connection module src/lib/db/index.ts with singleton pool - Add drizzle.config.ts and migration files - Update next.config.ts to externalize mysql2 - Add unit tests for recovery route with Drizzle mocks - Remove stale recover-request-route.test.ts
…rmat - Replace hardcoded timestamp in migration with CURRENT_TIMESTAMP / ON UPDATE CURRENT_TIMESTAMP so migration file is portable - Add STM public key format validation (STM + 50+ base58 chars) in recovery request route - Add test case for invalid owner_key format - Update existing tests to use realistic-length public keys
- GET /api/recovery/verify/[code]: verify validation_code, return account_name - POST /api/recovery/confirm: CSRF-protected, validates code + owner keys, updates arecs status to closed - POST /api/broadcast/recover-account: server relay for signed recover_account tx - RecoverAccountConfirmationPage: client-side component with old/new password form, owner history check, sign + broadcast flow - SteemSigner.signRecoverAccount: derive owner keys, sign recover_account operation - apiClient: add verifyRecoveryCode, confirmAccountRecovery, broadcastRecoverAccountTx - i18n: en/es/zh translations for confirmation page - Tests: 11 new test cases for verify and confirm routes (382 total passing) Note: request_account_recovery (Conveyor step) is stubbed as TODO. The client-side recover_account broadcast flow is complete.
- SteemService.requestAccountRecovery: call kingdom.recovery_account
via steem.api.signedCallAsync (signed with conveyor account credentials)
- confirm route now calls requestAccountRecovery before updating arecs
- .env.example: add CONVEYOR_USERNAME and CONVEYOR_POSTING_WIF
- Test: mock SteemService.requestAccountRecovery in confirm route tests
Flow: confirm API -> kingdom.recovery_account -> arecs closed
-> client signs recover_account locally -> server relay broadcasts
bd20c8e to
c5f70c6
Compare
P1.1: confirm route — atomic CAS update (confirmed→processing) prevents TOCTOU race P1.2: confirmation page — useState→useEffect for mount-time side effect P1.3: confirm route — processing state prevents kingdom/DB inconsistency P2.1: broadcast route — validate operation body against DB record before relay P2.2: verify route — add rate limiting (20 req/60s) P2.3: request route — server-side email normalization (trim + lowercase) P2.4: schema — add index on validation_code for verify/confirm lookups P2.5: .env.example — add DATABASE_URL entry P3.1: signRecoverAccount — correct return type from sync Promise to async P3.2: owner_key regex — strict base58 character set (no 0/O/I/l) P3.3: getDb() — retry on subsequent calls instead of permanent failure Tests: 383/383 passing
S1: confirm route cross-validate old_owner_key vs DB ownerKey S2: broadcast route reject null newOwnerKey S3: request route account_name format validation + trim/lowercase S4: signRecoverAccount add direct privateKey branch C1: confirm route Step 3 WHERE clause add accountName R2: request route account_name trim (merged into S3) R3: docs document processing status cleanup requirement T1: add broadcast/recover-account route tests (11 cases) T2: add owner-history route tests (6 cases) T3: steem-client-recover test verify request structure 403/403 tests passing
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
/recover_account_step_1flow to start stolen account recovery.Test plan
pnpm verify/recover_account_step_1: