fix(page-templates): defense-in-depth workspace checks (#36)
Consistency hardening from #17 review (not currently exploitable): - toggleTemplate now explicitly rejects a page outside the caller's workspace (page.workspaceId !== user.workspaceId -> NotFound, avoiding existence leak) instead of relying solely on the space-membership model. - PageTemplateReferencesRepo.deleteByReferenceAndSources is now workspace-scoped (adds a workspaceId filter + param), matching the 'scope by workspaceId everywhere' invariant; the sole caller threads its workspaceId. The PAGE_TEMPLATE_THROTTLER limit is intentionally left as-is (the issue's throttle item was 'consider only'; no change without usage data). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -38,12 +38,15 @@ export class PageTemplateReferencesRepo {
|
||||
|
||||
async deleteByReferenceAndSources(
|
||||
referencePageId: string,
|
||||
workspaceId: string,
|
||||
sourcePageIds: string[],
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<void> {
|
||||
if (sourcePageIds.length === 0) return;
|
||||
await dbOrTx(this.db, trx)
|
||||
.deleteFrom('pageTemplateReferences')
|
||||
// Defense-in-depth: scope deletes to the caller's workspace.
|
||||
.where('workspaceId', '=', workspaceId)
|
||||
.where('referencePageId', '=', referencePageId)
|
||||
.where('sourcePageId', 'in', sourcePageIds)
|
||||
.execute();
|
||||
|
||||
Reference in New Issue
Block a user