fix(security): apply two findings from sharing security review
- get_document: strip extracted_text for share recipients (T-04-04-03 consistency) - ShareModal: emit 'unshared' when last recipient is revoked; DocumentCard clears is_shared badge Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -545,6 +545,7 @@ async def get_document(
|
|||||||
if doc is None:
|
if doc is None:
|
||||||
raise HTTPException(404, "Document not found")
|
raise HTTPException(404, "Document not found")
|
||||||
|
|
||||||
|
is_recipient = False
|
||||||
if doc.user_id != current_user.id:
|
if doc.user_id != current_user.id:
|
||||||
# Allow recipients of an active share to view the document
|
# Allow recipients of an active share to view the document
|
||||||
share_result = await session.execute(
|
share_result = await session.execute(
|
||||||
@@ -555,10 +556,14 @@ async def get_document(
|
|||||||
)
|
)
|
||||||
if share_result.scalar_one_or_none() is None:
|
if share_result.scalar_one_or_none() is None:
|
||||||
raise HTTPException(404, "Document not found")
|
raise HTTPException(404, "Document not found")
|
||||||
|
is_recipient = True
|
||||||
|
|
||||||
meta = await storage.get_metadata(session, doc_id)
|
meta = await storage.get_metadata(session, doc_id)
|
||||||
if meta is None:
|
if meta is None:
|
||||||
raise HTTPException(404, "Document not found")
|
raise HTTPException(404, "Document not found")
|
||||||
|
# T-04-04-03: recipients get metadata only — extracted_text excluded (consistent with /shares/received)
|
||||||
|
if is_recipient:
|
||||||
|
meta.pop("extracted_text", None)
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
v-if="showShareModal"
|
v-if="showShareModal"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
@close="showShareModal = false"
|
@close="showShareModal = false"
|
||||||
|
@unshared="doc.is_shared = false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['close'])
|
const emit = defineEmits(['close', 'unshared'])
|
||||||
|
|
||||||
const docsStore = useDocumentsStore()
|
const docsStore = useDocumentsStore()
|
||||||
|
|
||||||
@@ -202,6 +202,7 @@ async function handleRevoke(shareId) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await docsStore.revokeShare(shareId)
|
await docsStore.revokeShare(shareId)
|
||||||
|
if (shares.value.length === 0) emit('unshared', props.doc.id)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Re-add on failure
|
// Re-add on failure
|
||||||
if (removed && removedIdx !== -1) {
|
if (removed && removedIdx !== -1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user