Skip to content

bug: wallet login authentication is broken due to empty Zod validation schema #452

@Pcmhacker-piro

Description

@Pcmhacker-piro

Description

The wallet login endpoint (POST /api/auth/wallet-login) is completely non-functional because the walletLoginSchema at backend/controllers/authController.js:314 is defined as z.object({}) — an empty schema that validates zero fields. The handler destructures address, signature, and nonce from validationResult.data, but since the schema accepts any empty object, all three values resolve to undefined. This breaks nonce lookup in Redis, signature verification, and wallet address lookup in MongoDB.

The same z.object({}) issue affects wallet registration at the same line since both share the schema.

Steps to Reproduce

  1. Register a user with a wallet address via POST /api/auth/wallet-register
  2. Try to login via POST /api/auth/wallet-login with { address, signature, nonce }
  3. Observe the server receives undefined for all three fields because z.object({}) strips them during validation
  4. Redis nonce lookup fails with undefined key, nonce verification fails, wallet login returns an error

Expected Behavior

  • walletLoginSchema should validate address (string, required), signature (string, required), and nonce (string, required)
  • Nonce should be correctly retrieved from Redis and verified against the signature using ethers.verifyMessage
  • On successful verification, the user should be authenticated and receive JWT tokens
  • Wallet registration flow should work end-to-end

Implementation Hints

Fix the schema at backend/controllers/authController.js line 314:

const walletLoginSchema = z.object({
  address: z.string().min(1, "Wallet address is required"),
  signature: z.string().min(1, "Signature is required"),
  nonce: z.string().min(1, "Nonce is required"),
});

Consider extracting a shared wallet schema since both walletRegister and walletLogin use the same base fields:

const walletFields = {
  address: z.string().min(1).transform((v) => v.toLowerCase()),
  signature: z.string().min(1),
  nonce: z.string().min(1),
};
const walletLoginSchema = z.object(walletFields);

Verify the fix by testing the full wallet auth flow:

  1. Generate nonce for wallet address
  2. Sign the nonce with the wallet private key
  3. Call wallet-login with address, signature, and nonce
  4. Confirm successful authentication

Affected Files

  • backend/controllers/authController.js (line 314)

Labels

type:bug, level:intermediate, GSSoC-26

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions