mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
chore: migrate to AGPL-3.0-only
This commit is contained in:
@@ -4,7 +4,7 @@ import { jwtVerify } from 'jose'
|
||||
import { z } from 'zod'
|
||||
import type { Store } from '../store'
|
||||
import { configuration } from '../configuration'
|
||||
import { safeCompareStrings } from '../utils/crypto'
|
||||
import { constantTimeEquals } from '../utils/crypto'
|
||||
import { parseAccessToken } from '../utils/accessToken'
|
||||
import { registerCliHandlers } from './handlers/cli'
|
||||
import { registerTerminalHandlers } from './handlers/terminal'
|
||||
@@ -98,7 +98,7 @@ export function createSocketServer(deps: SocketServerDeps): {
|
||||
const auth = socket.handshake.auth as Record<string, unknown> | undefined
|
||||
const token = typeof auth?.token === 'string' ? auth.token : null
|
||||
const parsedToken = token ? parseAccessToken(token) : null
|
||||
if (!parsedToken || !safeCompareStrings(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
if (!parsedToken || !constantTimeEquals(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
return next(new Error('Invalid token'))
|
||||
}
|
||||
socket.data.namespace = parsedToken.namespace
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { timingSafeEqual } from 'node:crypto'
|
||||
|
||||
export function safeCompareStrings(a: string | null | undefined, b: string | null | undefined): boolean {
|
||||
if (a == null || b == null) {
|
||||
return false
|
||||
}
|
||||
const bufA = Buffer.from(a, 'utf8')
|
||||
const bufB = Buffer.from(b, 'utf8')
|
||||
try {
|
||||
return timingSafeEqual(bufA, bufB)
|
||||
} catch {
|
||||
export function constantTimeEquals(a: string | null | undefined, b: string | null | undefined): boolean {
|
||||
if (typeof a !== 'string' || typeof b !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
const bufferA = Buffer.from(a, 'utf8')
|
||||
const bufferB = Buffer.from(b, 'utf8')
|
||||
const maxLength = Math.max(bufferA.length, bufferB.length)
|
||||
const paddedA = Buffer.alloc(maxLength)
|
||||
const paddedB = Buffer.alloc(maxLength)
|
||||
|
||||
bufferA.copy(paddedA)
|
||||
bufferB.copy(paddedB)
|
||||
|
||||
const matches = timingSafeEqual(paddedA, paddedB)
|
||||
return matches && bufferA.length === bufferB.length
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Hono } from 'hono'
|
||||
import { SignJWT } from 'jose'
|
||||
import { z } from 'zod'
|
||||
import { configuration } from '../../configuration'
|
||||
import { safeCompareStrings } from '../../utils/crypto'
|
||||
import { constantTimeEquals } from '../../utils/crypto'
|
||||
import { parseAccessToken } from '../../utils/accessToken'
|
||||
import { validateTelegramInitData } from '../telegramInitData'
|
||||
import { getOrCreateOwnerId } from '../ownerId'
|
||||
@@ -38,7 +38,7 @@ export function createAuthRoutes(jwtSecret: Uint8Array, store: Store): Hono<WebA
|
||||
// Access Token authentication (CLI_API_TOKEN)
|
||||
if ('accessToken' in parsed.data) {
|
||||
const parsedToken = parseAccessToken(parsed.data.accessToken)
|
||||
if (!parsedToken || !safeCompareStrings(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
if (!parsedToken || !constantTimeEquals(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
return c.json({ error: 'Invalid access token' }, 401)
|
||||
}
|
||||
userId = await getOrCreateOwnerId()
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Hono } from 'hono'
|
||||
import { SignJWT } from 'jose'
|
||||
import { z } from 'zod'
|
||||
import { configuration } from '../../configuration'
|
||||
import { safeCompareStrings } from '../../utils/crypto'
|
||||
import { constantTimeEquals } from '../../utils/crypto'
|
||||
import { parseAccessToken } from '../../utils/accessToken'
|
||||
import { validateTelegramInitData } from '../telegramInitData'
|
||||
import { getOrCreateOwnerId } from '../ownerId'
|
||||
@@ -25,7 +25,7 @@ export function createBindRoutes(jwtSecret: Uint8Array, store: Store): Hono<WebA
|
||||
}
|
||||
|
||||
const parsedToken = parseAccessToken(parsed.data.accessToken)
|
||||
if (!parsedToken || !safeCompareStrings(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
if (!parsedToken || !constantTimeEquals(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
return c.json({ error: 'Invalid access token' }, 401)
|
||||
}
|
||||
const namespace = parsedToken.namespace
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Hono } from 'hono'
|
||||
import { z } from 'zod'
|
||||
import { configuration } from '../../configuration'
|
||||
import { safeCompareStrings } from '../../utils/crypto'
|
||||
import { constantTimeEquals } from '../../utils/crypto'
|
||||
import { parseAccessToken } from '../../utils/accessToken'
|
||||
import type { Machine, Session, SyncEngine } from '../../sync/syncEngine'
|
||||
|
||||
@@ -76,7 +76,7 @@ export function createCliRoutes(getSyncEngine: () => SyncEngine | null): Hono<Cl
|
||||
|
||||
const token = parsed.data.replace(/^Bearer\s+/i, '')
|
||||
const parsedToken = parseAccessToken(token)
|
||||
if (!parsedToken || !safeCompareStrings(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
if (!parsedToken || !constantTimeEquals(parsedToken.baseToken, configuration.cliApiToken)) {
|
||||
return c.json({ error: 'Invalid token' }, 401)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user