diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-12-30 22:12:04 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-12-30 22:12:04 +0900 |
| commit | 953e6aeca4a1cf5dcba2148ab638a357cd6e60a0 (patch) | |
| tree | 8bd3f373640eb18eb497d05caac958edce286d9e /src | |
| parent | c2eb7513834eeb5adfa53fff897f585de87e4821 (diff) | |
| download | kioku-953e6aeca4a1cf5dcba2148ab638a357cd6e60a0.tar.gz kioku-953e6aeca4a1cf5dcba2148ab638a357cd6e60a0.tar.zst kioku-953e6aeca4a1cf5dcba2148ab638a357cd6e60a0.zip | |
fix(sync): verify card ownership before update in push
Previously, when updating an existing card during sync push, only the
target deck ownership was verified. This allowed a user who knew another
user's card ID to potentially update that card by specifying their own
deck. Now the query joins with decks table to verify the existing card
belongs to the current user.
🤖 Generated with [Claude Code](https://claude.ai/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/repositories/sync.ts | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/server/repositories/sync.ts b/src/server/repositories/sync.ts index a1b6648..3e9f8ed 100644 --- a/src/server/repositories/sync.ts +++ b/src/server/repositories/sync.ts @@ -171,18 +171,18 @@ export const syncRepository: SyncRepository = { for (const cardData of data.cards) { const clientUpdatedAt = new Date(cardData.updatedAt); - // Verify deck belongs to user + // Verify target deck belongs to user const deckCheck = await db .select({ id: decks.id }) .from(decks) .where(and(eq(decks.id, cardData.deckId), eq(decks.userId, userId))); if (deckCheck.length === 0) { - // Deck doesn't belong to user, skip + // Target deck doesn't belong to user, skip continue; } - // Check if card exists + // Check if card exists AND belongs to user (via deck ownership) const existing = await db .select({ id: cards.id, @@ -190,7 +190,8 @@ export const syncRepository: SyncRepository = { syncVersion: cards.syncVersion, }) .from(cards) - .where(eq(cards.id, cardData.id)); + .innerJoin(decks, eq(cards.deckId, decks.id)) + .where(and(eq(cards.id, cardData.id), eq(decks.userId, userId))); if (existing.length === 0) { // New card - insert |
