feat: person @mentions edit-mode infrastructure (PR-B1, #362) #369
@@ -88,11 +88,20 @@ async function loadTranscriptionBlocks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||||
|
|
||||||
async function saveBlock(
|
async function saveBlock(
|
||||||
blockId: string,
|
blockId: string,
|
||||||
text: string,
|
text: string,
|
||||||
mentionedPersons: import('$lib/types').PersonMention[]
|
mentionedPersons: import('$lib/types').PersonMention[]
|
||||||
) {
|
) {
|
||||||
|
// Path-injection defence in depth (Sina #5505): both ids are server-controlled
|
||||||
|
// today, but reject anything that isn't a UUID before interpolating it into
|
||||||
|
// the URL — a future feature accepting user-supplied ids must not silently
|
||||||
|
// bypass this check.
|
||||||
|
if (!UUID_RE.test(doc.id) || !UUID_RE.test(blockId)) {
|
||||||
|
throw new Error(`Invalid id for save: doc=${doc.id} block=${blockId}`);
|
||||||
|
}
|
||||||
const res = await fetch(`/api/documents/${doc.id}/transcription-blocks/${blockId}`, {
|
const res = await fetch(`/api/documents/${doc.id}/transcription-blocks/${blockId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|||||||
Reference in New Issue
Block a user