fix(materials): личная загрузка картинок без права library.upload
POST /api/files требует teacher/admin + library.upload — поэтому сохранение картинок в «Мои материалы» (вырезка области учебника, обрезка доски, рисунок, аннотация) падало с 403 у учеников и учителей без этого права. Добавлен auth-only эндпоинт POST /api/files/personal (только картинки, is_public=1) + LS.uploadMaterialFile. На него переключены board-clip, material-save, textbook-clip (вырезка области) и рисовалка в my-materials. Загрузка в учительскую библиотеку (library/lesson-editor) не тронута. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1029,7 +1029,7 @@ window.LS = {
|
||||
myAssignments, teacherAssignments, startAssignment, assignmentResults, assignmentSessionReview, assignmentQuestionStats,
|
||||
getTests, createTest, getTest, updateTest, deleteTest, addQuestionsToTest, removeQFromTest,
|
||||
getGamificationMe, getGamAchievements, getLeaderboard, getXPHistory, getChallenges, claimChallenge, setGoalTier, getFrames, setFrame, reportLabActivity,
|
||||
getFiles, uploadFile, downloadFileUrl, deleteFile, getFileAccess, assignFile, unassignFile,
|
||||
getFiles, uploadFile, uploadMaterialFile, downloadFileUrl, deleteFile, getFileAccess, assignFile, unassignFile,
|
||||
getFolders, createFolder, renameFolder, deleteFolder, moveFile,
|
||||
getFolderAccess, clearFolderAccess, assignFolder, unassignFolder, getStudentsList,
|
||||
submitWork, resubmitWork, getMySubmissions, getClassSubmissions, reviewSubmission, deleteSubmission, submissionDownloadUrl,
|
||||
@@ -1244,6 +1244,19 @@ async function uploadFile(formData) {
|
||||
if (!res.ok) throw Object.assign(new Error(data.error || 'Upload failed'), { status: res.status });
|
||||
return data;
|
||||
}
|
||||
/* Personal image upload for «Мои материалы» — any logged-in user (students too).
|
||||
* Separate from uploadFile() which is the teacher library (role + permission). */
|
||||
async function uploadMaterialFile(formData) {
|
||||
const token = getToken();
|
||||
const res = await fetch(API + '/files/personal', {
|
||||
method: 'POST',
|
||||
headers: token ? { 'Authorization': `Bearer ${token}` } : {},
|
||||
body: formData,
|
||||
});
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok) throw Object.assign(new Error(data.error || 'Upload failed'), { status: res.status });
|
||||
return data;
|
||||
}
|
||||
function downloadFileUrl(id) { return `${API}/files/${id}/download`; }
|
||||
async function listMaterials() { return req('GET', '/materials'); }
|
||||
async function saveMaterial(data) { return req('POST', '/materials', data); }
|
||||
|
||||
Reference in New Issue
Block a user