Visitar URL original
Refactor game services and API endpoints with security improvements by cwchanap · Pull Request #18 · cwchanap/cetus · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions .claude/settings.local.json

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ test-results/
.eslintcache
playwright-report/

.turso

# Claude settings
.claude/settings.local.json
.turbo
6 changes: 4 additions & 2 deletions src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ export const auth = betterAuth({
updateAge: 60 * 60 * 24, // 1 day
cookie: {
sameSite: 'lax',
secure: false,
secure: import.meta.env.PROD,
httpOnly: true,
},
},
trustedOrigins: ['http://localhost:4325'],
trustedOrigins: [
import.meta.env.BETTER_AUTH_URL || 'http://localhost:4325',
],
secret: import.meta.env.BETTER_AUTH_SECRET!,
Comment thread
cwchanap marked this conversation as resolved.
Resolved
baseURL: import.meta.env.BETTER_AUTH_URL || '',
Comment thread
cwchanap marked this conversation as resolved.
Resolved
})
Expand Down
13 changes: 8 additions & 5 deletions src/lib/games/2048/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export async function init2048Game(
return undefined
}

const abortController = new AbortController()
const { signal } = abortController

// Initialize game state
let state = createGameState()
let totalMerges = 0
Expand Down Expand Up @@ -350,10 +353,7 @@ export async function init2048Game(

// Destroy and cleanup
function destroy(): void {
document.removeEventListener('keydown', handleKeyDown)
gameContainer.removeEventListener('touchstart', handleTouchStart)
gameContainer.removeEventListener('touchend', handleTouchEnd)
gameContainer.removeEventListener('touchmove', handleTouchMove)
abortController.abort()

if (renderer) {
destroyRenderer(renderer)
Expand All @@ -362,15 +362,18 @@ export async function init2048Game(
}

// Setup event listeners
document.addEventListener('keydown', handleKeyDown)
document.addEventListener('keydown', handleKeyDown, { signal })
gameContainer.addEventListener('touchstart', handleTouchStart, {
passive: false,
signal,
})
gameContainer.addEventListener('touchend', handleTouchEnd, {
passive: false,
signal,
})
gameContainer.addEventListener('touchmove', handleTouchMove, {
passive: false,
signal,
})

// Initial draw
Expand Down
26 changes: 17 additions & 9 deletions src/lib/games/bejeweled/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export async function initBejeweledGame(
const renderer = new BejeweledRenderer(rendererConfig)
await renderer.initialize()

const abortController = new AbortController()
const { signal } = abortController

// Enhance callbacks to wire up rendering + UI updates
const enhancedCallbacks: BaseGameCallbacks = {
...customCallbacks,
Expand Down Expand Up @@ -151,27 +154,31 @@ export async function initBejeweledGame(
'start-btn'
) as HTMLButtonElement | null
if (startBtn) {
startBtn.addEventListener('click', () => game.start())
startBtn.addEventListener('click', () => game.start(), { signal })
}

const endBtn = document.getElementById(
'end-btn'
) as HTMLButtonElement | null
if (endBtn) {
endBtn.addEventListener('click', () => game.end())
endBtn.addEventListener('click', () => game.end(), { signal })
}

const playAgainBtn = document.getElementById(
'play-again-btn'
) as HTMLButtonElement | null
if (playAgainBtn) {
playAgainBtn.addEventListener('click', () => {
const overlay = document.getElementById('game-over-overlay')
if (overlay) {
overlay.classList.add('hidden')
}
game.reset()
})
playAgainBtn.addEventListener(
'click',
() => {
const overlay = document.getElementById('game-over-overlay')
if (overlay) {
overlay.classList.add('hidden')
}
game.reset()
},
{ signal }
)
}

// Initial render
Expand All @@ -181,6 +188,7 @@ export async function initBejeweledGame(
game,
renderer,
cleanup: () => {
abortController.abort()
renderer.cleanup()
game.destroy()
},
Expand Down
76 changes: 51 additions & 25 deletions src/lib/games/memory-matrix/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ import { GameID } from '@/lib/games'

let game: MemoryMatrixGame | null = null
let renderer: MemoryMatrixRenderer | null = null
let abortController: AbortController | null = null

export async function initMemoryMatrixGame(callbacks?: {
onGameComplete?: (finalScore: number, stats: any) => void
}): Promise<any> {
Comment thread
cwchanap marked this conversation as resolved.
Resolved
// Clean up previous instance if any
if (abortController) {
abortController.abort()
}
abortController = new AbortController()
const { signal } = abortController

// Initialize game and renderer
game = new MemoryMatrixGame()
renderer = new MemoryMatrixRenderer('memory-matrix-container')
Comment thread
cwchanap marked this conversation as resolved.
Resolved
Expand Down Expand Up @@ -40,12 +48,16 @@ export async function initMemoryMatrixGame(callbacks?: {
})

// Set up game controls
setupGameControls()
setupGameControls(signal)

// Set up restart listener
window.addEventListener('memory-matrix-restart', () => {
game?.resetGame()
})
window.addEventListener(
'memory-matrix-restart',
() => {
game?.resetGame()
},
{ signal }
)

// Initial render
const initialState = game.getGameState()
Expand All @@ -58,42 +70,55 @@ export async function initMemoryMatrixGame(callbacks?: {
getState: () => game?.getGameState(),
getStats: () => game?.getGameStats(),
endGame: () => game?.endGameEarly(),
cleanup,
}
Comment thread
cwchanap marked this conversation as resolved.
Resolved
}

function setupGameControls(): void {
function setupGameControls(signal: AbortSignal): void {
const startBtn = document.getElementById('start-btn')
const resetBtn = document.getElementById('reset-btn')

if (startBtn) {
startBtn.addEventListener('click', () => {
if (game) {
const state = game.getGameState()
if (!state.gameStarted) {
game.startGame()
startBtn.textContent = 'Game Started'
;(startBtn as HTMLButtonElement).disabled = true
startBtn.addEventListener(
'click',
() => {
if (game) {
const state = game.getGameState()
if (!state.gameStarted) {
game.startGame()
startBtn.textContent = 'Game Started'
;(startBtn as HTMLButtonElement).disabled = true
}
}
}
})
},
{ signal }
)
}

if (resetBtn) {
resetBtn.addEventListener('click', () => {
if (game) {
game.resetGame()
if (startBtn) {
startBtn.textContent = 'Start Game'
;(startBtn as HTMLButtonElement).disabled = false
resetBtn.addEventListener(
'click',
() => {
if (game) {
game.resetGame()
if (startBtn) {
startBtn.textContent = 'Start Game'
;(startBtn as HTMLButtonElement).disabled = false
}
}
}
})
},
{ signal }
)
}

// Handle page unload
window.addEventListener('beforeunload', () => {
cleanup()
})
window.addEventListener(
'beforeunload',
() => {
cleanup()
},
{ signal }
)
}

async function saveScore(score: number): Promise<void> {
Expand All @@ -118,6 +143,7 @@ async function saveScore(score: number): Promise<void> {
}

function cleanup(): void {
abortController?.abort()
game?.destroy()
renderer?.destroy()
game = null
Expand Down
8 changes: 5 additions & 3 deletions src/lib/games/path-navigator/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export async function initializePathNavigatorGame(

const gameConfig = { ...DEFAULT_CONFIG, ...config }

const abortController = new AbortController()
const { signal } = abortController

let renderer: RendererState | null = null
let game: PathNavigatorGame | null = null
let animationFrame: number | null = null
Expand Down Expand Up @@ -244,7 +247,7 @@ export async function initializePathNavigatorGame(
}

// Enable keyboard controls
document.addEventListener('keydown', handleKeyPress)
document.addEventListener('keydown', handleKeyPress, { signal })
animationFrame = requestAnimationFrame(gameLoop)

// Call game start callback
Expand Down Expand Up @@ -299,8 +302,7 @@ export async function initializePathNavigatorGame(
cancelAnimationFrame(animationFrame)
}

// Remove keyboard event listener
document.removeEventListener('keydown', handleKeyPress)
abortController.abort()

if (game) {
game.cleanup()
Expand Down
Loading
Loading