aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-12-30 22:12:04 +0900
committernsfisis <nsfisis@gmail.com>2025-12-30 22:12:04 +0900
commit953e6aeca4a1cf5dcba2148ab638a357cd6e60a0 (patch)
tree8bd3f373640eb18eb497d05caac958edce286d9e /src
parentc2eb7513834eeb5adfa53fff897f585de87e4821 (diff)
downloadkioku-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.ts9
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