@@ -8,10 +8,9 @@ import {
88import { sha256Hex } from '@/lib/auth/crypto'
99import { signSessionToken , verifySessionToken } from '@/lib/auth/jwt'
1010import {
11- findValidRefreshToken ,
1211 revokeRefreshToken ,
12+ rotateRefreshToken ,
1313 storeRefreshToken ,
14- touchRefreshToken ,
1514} from '@/lib/auth/store'
1615import { normalizeWalletAddress } from '@/lib/auth/stellar'
1716
@@ -42,23 +41,20 @@ function getClientIp(request: NextRequest): string | null {
4241 return request . headers . get ( 'x-real-ip' )
4342}
4443
45- export async function createSession (
46- request : NextRequest ,
47- walletAddress : string
48- ) : Promise < AuthSession > {
49- const normalizedWallet = normalizeWalletAddress ( walletAddress )
50- const secret = getJwtSecret ( )
51-
44+ function buildSessionTokens (
45+ walletAddress : string ,
46+ secret : string
47+ ) : Omit < AuthSession , 'walletAddress' > {
5248 const access = signSessionToken ( {
53- subject : normalizedWallet ,
54- walletAddress : normalizedWallet ,
49+ subject : walletAddress ,
50+ walletAddress,
5551 type : 'access' ,
5652 expiresInSeconds : ACCESS_TOKEN_TTL_SECONDS ,
5753 secret,
5854 } )
5955 const refresh = signSessionToken ( {
60- subject : normalizedWallet ,
61- walletAddress : normalizedWallet ,
56+ subject : walletAddress ,
57+ walletAddress,
6258 type : 'refresh' ,
6359 expiresInSeconds : REFRESH_TOKEN_TTL_SECONDS ,
6460 secret,
@@ -67,22 +63,36 @@ export async function createSession(
6763 const accessTokenExpiresAt = new Date ( access . payload . exp * 1000 )
6864 const refreshTokenExpiresAt = new Date ( refresh . payload . exp * 1000 )
6965
66+ return {
67+ accessToken : access . token ,
68+ refreshToken : refresh . token ,
69+ accessTokenExpiresAt,
70+ refreshTokenExpiresAt,
71+ refreshJti : refresh . payload . jti ,
72+ }
73+ }
74+
75+ export async function createSession (
76+ request : NextRequest ,
77+ walletAddress : string
78+ ) : Promise < AuthSession > {
79+ const normalizedWallet = normalizeWalletAddress ( walletAddress )
80+ const secret = getJwtSecret ( )
81+
82+ const tokens = buildSessionTokens ( normalizedWallet , secret )
83+
7084 await storeRefreshToken ( {
7185 walletAddress : normalizedWallet ,
72- jti : refresh . payload . jti ,
73- tokenHash : sha256Hex ( refresh . token ) ,
74- expiresAt : refreshTokenExpiresAt ,
86+ jti : tokens . refreshJti ,
87+ tokenHash : sha256Hex ( tokens . refreshToken ) ,
88+ expiresAt : tokens . refreshTokenExpiresAt ,
7589 userAgent : request . headers . get ( 'user-agent' ) ,
7690 ipAddress : getClientIp ( request ) ,
7791 } )
7892
7993 return {
8094 walletAddress : normalizedWallet ,
81- accessToken : access . token ,
82- refreshToken : refresh . token ,
83- accessTokenExpiresAt,
84- refreshTokenExpiresAt,
85- refreshJti : refresh . payload . jti ,
95+ ...tokens ,
8696 }
8797}
8898
@@ -96,24 +106,27 @@ export async function rotateSession(
96106 return null
97107 }
98108
99- const tokenHash = sha256Hex ( refreshToken )
100- const isValid = await findValidRefreshToken ( {
101- walletAddress : payload . wallet ,
102- jti : payload . jti ,
103- tokenHash,
109+ const normalizedWallet = normalizeWalletAddress ( payload . wallet )
110+ const nextTokens = buildSessionTokens ( normalizedWallet , secret )
111+
112+ const rotated = await rotateRefreshToken ( {
113+ walletAddress : normalizedWallet ,
114+ currentJti : payload . jti ,
115+ currentTokenHash : sha256Hex ( refreshToken ) ,
116+ newJti : nextTokens . refreshJti ,
117+ newTokenHash : sha256Hex ( nextTokens . refreshToken ) ,
118+ newExpiresAt : nextTokens . refreshTokenExpiresAt ,
119+ userAgent : request . headers . get ( 'user-agent' ) ,
120+ ipAddress : getClientIp ( request ) ,
104121 } )
105- if ( ! isValid ) {
122+ if ( ! rotated ) {
106123 return null
107124 }
108125
109- await touchRefreshToken ( payload . jti )
110- const session = await createSession ( request , payload . wallet )
111- await revokeRefreshToken ( {
112- jti : payload . jti ,
113- replacedByJti : session . refreshJti ,
114- } )
115-
116- return session
126+ return {
127+ walletAddress : normalizedWallet ,
128+ ...nextTokens ,
129+ }
117130}
118131
119132export async function revokeSession ( refreshToken : string ) : Promise < void > {
0 commit comments