@@ -2,6 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
22import request from "supertest" ;
33import express from "express" ;
44import crypto from "node:crypto" ;
5+ import { Account , type TypedData } from "starknet" ;
56
67const { dbMock, schemaMock, mockState, eqMock, orMock, ltMock, isNotNullMock, mockProvider } = vi . hoisted ( ( ) => {
78 const mockState = {
@@ -96,7 +97,14 @@ const { dbMock, schemaMock, mockState, eqMock, orMock, ltMock, isNotNullMock, mo
9697 return { dbMock : db , schemaMock : schema , mockState, eqMock, orMock, ltMock, isNotNullMock, mockProvider } ;
9798} ) ;
9899
99- vi . mock ( "../db/index.js" , ( ) => ( { db : dbMock , schema : schemaMock } ) ) ;
100+ vi . mock ( "../db/index.js" , ( ) => ( {
101+ db : dbMock ,
102+ schema : schemaMock ,
103+ checkDbHealth : vi . fn ( ) . mockResolvedValue ( true ) ,
104+ getPoolStats : vi . fn ( ) . mockReturnValue ( { total : 0 , idle : 0 , active : 0 , waiting : 0 } ) ,
105+ closePool : vi . fn ( ) . mockResolvedValue ( undefined ) ,
106+ waitForDbReadiness : vi . fn ( ) . mockResolvedValue ( undefined ) ,
107+ } ) ) ;
100108vi . mock ( "../db/schema.js" , ( ) => ( { sessions : schemaMock . sessions } ) ) ;
101109vi . mock ( "drizzle-orm" , ( ) => ( {
102110 eq : eqMock ,
@@ -123,6 +131,11 @@ vi.mock("../config.js", () => ({
123131vi . mock ( "../starknet/client.js" , ( ) => ( {
124132 provider : mockProvider ,
125133 getCachedNetworkInfo : vi . fn ( ) . mockResolvedValue ( { chainId : "0x534e5f5345504f4c4941" } ) ,
134+ getEscrowAbi : vi . fn ( ) . mockReturnValue ( [ ] ) ,
135+ getAgreementAbi : vi . fn ( ) . mockReturnValue ( [ ] ) ,
136+ getCircuitBreakerSnapshots : vi . fn ( ) . mockReturnValue ( [ ] ) ,
137+ agreementContract : vi . fn ( ) ,
138+ escrowContract : vi . fn ( ) ,
126139} ) ) ;
127140
128141import { authRouter , rebuildAdminSet } from "./auth.js" ;
@@ -133,6 +146,7 @@ import {
133146} from "./auth-metrics.js" ;
134147import { lockouts } from "../auth/lockout.js" ;
135148import { clearChallengesForTesting } from "../auth/challenge.js" ;
149+ import { app } from "../index.js" ;
136150
137151/**
138152 * Issue #193: locks the authorization contract for every route on this
@@ -344,6 +358,52 @@ describe("Auth Routes Integration", () => {
344358 expect ( logoutPostLogoutRes . status ) . toBe ( 401 ) ;
345359 } ) ;
346360
361+ it ( "covers the wallet lifecycle through the real app with signed and invalidated requests" , async ( ) => {
362+ const address = "0x123456789abcdef" ;
363+ const signer = new Account ( { provider : mockProvider as any , address, signer : "0x1" } ) ;
364+
365+ const challenge = await request ( app )
366+ . post ( "/api/v1/auth/challenge" )
367+ . send ( { address } )
368+ . expect ( 200 ) ;
369+ const signature = await signer . signMessage ( challenge . body . typed_data as TypedData ) ;
370+ mockProvider . verifyMessageInStarknet . mockResolvedValue ( true ) ;
371+
372+ const verified = await request ( app )
373+ . post ( "/api/v1/auth/verify" )
374+ . send ( { address, signature : [ signature . r . toString ( ) , signature . s . toString ( ) ] } )
375+ . expect ( 200 ) ;
376+ const token = verified . body . session_token as string ;
377+
378+ await request ( app )
379+ . post ( "/api/v1/auth/logout" )
380+ . set ( "x-user-address" , address )
381+ . set ( "authorization" , `Bearer ${ token } ` )
382+ . expect ( 200 ) ;
383+
384+ await request ( app )
385+ . post ( "/api/v1/auth/logout" )
386+ . set ( "x-user-address" , address )
387+ . set ( "authorization" , `Bearer ${ token } ` )
388+ . expect ( 401 ) ;
389+
390+ await request ( app )
391+ . post ( "/api/v1/auth/verify" )
392+ . send ( { address, signature : [ signature . r . toString ( ) , signature . s . toString ( ) ] } )
393+ . expect ( 400 ) ;
394+
395+ const expiredAddress = "0x123456789abcdf0" ;
396+ await request ( app )
397+ . post ( "/api/v1/auth/challenge" )
398+ . send ( { address : expiredAddress } )
399+ . expect ( 200 ) ;
400+ vi . advanceTimersByTime ( 300_001 ) ;
401+ await request ( app )
402+ . post ( "/api/v1/auth/verify" )
403+ . send ( { address : expiredAddress , signature : [ "0x1" , "0x2" ] } )
404+ . expect ( 400 ) ;
405+ } ) ;
406+
347407 it ( "rejects verify once the challenge TTL has elapsed" , async ( ) => {
348408 const address = "0xeeee000000000001" ;
349409 const appInstance = makeApp ( ) ;
@@ -997,7 +1057,6 @@ describe("Auth Routes Integration", () => {
9971057 } ) ;
9981058 } ) ;
9991059} ) ;
1000- } ) ;
10011060
10021061// ---------------------------------------------------------------------------
10031062// rebuildAdminSet / isAdminAddress — pre-built Set contract
0 commit comments