fix: conflict apiKeyAuth

This commit is contained in:
2025-12-11 11:17:39 +07:00
parent a19aaed329
commit 68b0c8ec4d
+81 -84
View File
@@ -94,8 +94,6 @@ export const apiKeyAuthMacro = new Elysia().macro({
if (!enabled) { if (!enabled) {
return return
} }
<<<<<<< HEAD
=======
const apiKey = headers['x-api-key'] const apiKey = headers['x-api-key']
const nonce = headers['x-nonce'] const nonce = headers['x-nonce']
const signature = headers['x-signature'] const signature = headers['x-signature']
@@ -184,7 +182,6 @@ export const apiKeyAuthMacro = new Elysia().macro({
return return
} }
>>>>>>> feature/auth
const apiKey = headers['x-api-key'] const apiKey = headers['x-api-key']
const nonce = headers['x-nonce'] const nonce = headers['x-nonce']
const signature = headers['x-signature'] const signature = headers['x-signature']
@@ -252,92 +249,92 @@ export const apiKeyAuthMacro = new Elysia().macro({
} }
}, },
}), }),
verifyKeyQuery: (enabled: boolean) => ({ // verifyKeyQuery: (enabled: boolean) => ({
async beforeHandle({ headers, query }) { // async beforeHandle({ headers, query }) {
if (!enabled) { // if (!enabled) {
return // return
} // }
const apiKey = headers['x-api-key'] // const apiKey = headers['x-api-key']
const nonce = headers['x-nonce'] // const nonce = headers['x-nonce']
const signature = headers['x-signature'] // const signature = headers['x-signature']
const rawTimestamp = headers['x-timestamp'] // const rawTimestamp = headers['x-timestamp']
const missingHeaders = [] // const missingHeaders = []
if (!apiKey) { // if (!apiKey) {
missingHeaders.push('X-API-Key') // missingHeaders.push('X-API-Key')
} // }
if (!nonce) { // if (!nonce) {
missingHeaders.push('X-Nonce') // missingHeaders.push('X-Nonce')
} // }
if (!rawTimestamp) { // if (!rawTimestamp) {
missingHeaders.push('X-Timestamp') // missingHeaders.push('X-Timestamp')
} // }
if (!signature) { // if (!signature) {
missingHeaders.push('X-Signature') // missingHeaders.push('X-Signature')
} // }
if (!apiKey || !nonce || !signature || !rawTimestamp) { // if (!apiKey || !nonce || !signature || !rawTimestamp) {
const missing = missingHeaders.join(', ') // const missing = missingHeaders.join(', ')
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to missing auth headers: ' + missing) // }, 'Failed API key authentication attempt due to missing auth headers: ' + missing)
throw new UnauthenticatedError('Missing auth headers: ' + missing) // throw new UnauthenticatedError('Missing auth headers: ' + missing)
} // }
const timestamp = Number(rawTimestamp) // const timestamp = Number(rawTimestamp)
if (!Number.isFinite(timestamp)) { // if (!Number.isFinite(timestamp)) {
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to invalid timestamp') // }, 'Failed API key authentication attempt due to invalid timestamp')
throw new UnauthenticatedError('Invalid timestamp') // throw new UnauthenticatedError('Invalid timestamp')
} // }
const nowSec = Math.floor(Date.now() / 1000) // const nowSec = Math.floor(Date.now() / 1000)
if (Math.abs(nowSec - timestamp) > apiAuth.skewSeconds) { // if (Math.abs(nowSec - timestamp) > apiAuth.skewSeconds) {
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to timestamp out of range') // }, 'Failed API key authentication attempt due to timestamp out of range')
throw new UnauthenticatedError('Timestamp out of range') // throw new UnauthenticatedError('Timestamp out of range')
} // }
const merchant = await db.query.merchants.findFirst({ // const merchant = await db.query.merchants.findFirst({
where: (t, { and, eq }) => and( // where: (t, { and, eq }) => and(
eq(t.apiKey, apiKey), // eq(t.apiKey, apiKey),
eq(t.isActive, true), // eq(t.isActive, true),
), // ),
}) // })
if (!merchant) { // if (!merchant) {
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to invalid API key') // }, 'Failed API key authentication attempt due to invalid API key')
throw new UnauthenticatedError('Invalid API key') // throw new UnauthenticatedError('Invalid API key')
} // }
const existingNonce = await db.$count($t.merchantNonces, and( // const existingNonce = await db.$count($t.merchantNonces, and(
eq($t.merchantNonces.merchantId, merchant.merchantId), // eq($t.merchantNonces.merchantId, merchant.merchantId),
eq($t.merchantNonces.nonce, nonce), // eq($t.merchantNonces.nonce, nonce),
)) // ))
if (existingNonce > 0) { // if (existingNonce > 0) {
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to replay attack detected') // }, 'Failed API key authentication attempt due to replay attack detected')
throw new UnauthenticatedError('Duplicate request detected, ensure your nonce is unique') // throw new UnauthenticatedError('Duplicate request detected, ensure your nonce is unique')
} // }
db.insert(merchantNonces).values({ // db.insert(merchantNonces).values({
merchantId: merchant.merchantId, // merchantId: merchant.merchantId,
nonce, // nonce,
}).catch((error) => { // }).catch((error) => {
logger.error({ // logger.error({
errorMessage: error.message, // errorMessage: error.message,
}, 'Failed to save merchant nonce into database') // }, 'Failed to save merchant nonce into database')
}) // })
if (!verify(query, timestamp, nonce, signature, merchant.secretKey)) { // if (!verify(query, timestamp, nonce, signature, merchant.secretKey)) {
logger.debug({ // logger.debug({
'headers.authorization': headers.authorization, // 'headers.authorization': headers.authorization,
}, 'Failed API key authentication attempt due to invalid signature') // }, 'Failed API key authentication attempt due to invalid signature')
throw new UnauthenticatedError('Invalid signature') // throw new UnauthenticatedError('Invalid signature')
} // }
}, // },
}), // }),
}) })