From 4a07525fd04a55708178b231953e5aac226a3de4 Mon Sep 17 00:00:00 2001 From: edgebrow <125250363+edgebrow@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:41:37 -0500 Subject: [PATCH] Fix fragile address extraction and improve provider logic in verification API --- lib/trait-validator.ts | 2 +- pages/api/coinbase/verify-token.ts | 25 +++++++++++-------------- pages/api/verify-token.ts | 30 +++++++++++++++++------------- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/lib/trait-validator.ts b/lib/trait-validator.ts index 2f03871..ef261f9 100644 --- a/lib/trait-validator.ts +++ b/lib/trait-validator.ts @@ -26,7 +26,7 @@ export interface ValidationResult { */ function parseTraitsFromMessage(message: string): { provider: string; traits: TraitRequirement } | null { // Extract resources section from SIWE message - const resourcesMatch = message.match(/Resources:\s*\n((?:- .+\n)+)/); + const resourcesMatch = message.match(/Resources:\s*\n((?:- .+(?:\n|$))+)/); if (!resourcesMatch) { return null; } diff --git a/pages/api/coinbase/verify-token.ts b/pages/api/coinbase/verify-token.ts index 5c6534c..4b47948 100644 --- a/pages/api/coinbase/verify-token.ts +++ b/pages/api/coinbase/verify-token.ts @@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from "next"; import { config } from "../../../lib/config"; import prisma from "../../../lib/prisma"; import { validateTraits } from "../../../lib/trait-validator"; +import { SiweMessage } from "siwe"; export default async function handler( req: NextApiRequest, @@ -21,6 +22,16 @@ export default async function handler( }); } + // Parse SIWE message to get address + let siweMessage: SiweMessage; + try { + siweMessage = new SiweMessage(message); + } catch (e) { + return res.status(400).json({ error: "Invalid SIWE message" }); + } + + const walletAddress = siweMessage.address; + // Define expected trait requirements for Coinbase verification // This MUST match what the frontend generates const expectedTraits = { @@ -108,22 +119,8 @@ export default async function handler( // Store the verification data in the database try { - // Extract user data from verification response - const addressMatch = message.match(/0x[a-fA-F0-9]{40}/); - const walletAddress = addressMatch ? addressMatch[0] : ""; - console.log("Extracted wallet address:", walletAddress); - if (!walletAddress) { - console.error( - "Failed to extract wallet address from message:", - message - ); - return res.status(400).json({ - error: "Could not extract wallet address from message", - }); - } - console.log("Attempting to store user in database:", walletAddress); // Enforce uniqueness of the base verify token before writing diff --git a/pages/api/verify-token.ts b/pages/api/verify-token.ts index 008b770..baac86b 100644 --- a/pages/api/verify-token.ts +++ b/pages/api/verify-token.ts @@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from 'next'; import { config } from '../../lib/config'; import prisma from '../../lib/prisma'; import { validateTraits } from '../../lib/trait-validator'; +import { SiweMessage } from 'siwe'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method !== 'POST') { @@ -18,14 +19,28 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }); } - // Define expected trait requirements for X verification + // Parse SIWE message to get address and provider + let siweMessage: SiweMessage; + try { + siweMessage = new SiweMessage(message); + } catch (e) { + return res.status(400).json({ error: 'Invalid SIWE message' }); + } + + const walletAddress = siweMessage.address; + + // Define expected trait requirements for verification // This MUST match what the frontend generates const expectedTraits = { 'verified': 'true' }; + // Extract provider from message or default to 'x' + const providerMatch = message.match(/urn:verify:provider:([^:\s\n]+)/); + const provider = providerMatch ? providerMatch[1] : 'x'; + // Validate that the message contains the expected trait requirements - const validation = validateTraits(message, 'x', expectedTraits); + const validation = validateTraits(message, provider, expectedTraits); if (!validation.valid) { console.error('Trait validation failed:', validation.error); @@ -101,19 +116,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // Store the verification data in the database try { - // Extract user data from verification response - const addressMatch = message.match(/0x[a-fA-F0-9]{40}/); - const walletAddress = addressMatch ? addressMatch[0] : ''; - console.log('Extracted wallet address:', walletAddress); - if (!walletAddress) { - console.error('Failed to extract wallet address from message:', message); - return res.status(400).json({ - error: 'Could not extract wallet address from message' - }); - } - console.log('Attempting to store user in database:', walletAddress); // Enforce uniqueness of the base verify token before writing