@studious-lms/server 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/middleware/security.d.ts.map +1 -1
- package/dist/middleware/security.js +3 -3
- package/dist/middleware/security.js.map +1 -1
- package/dist/models/access.d.ts +21 -66
- package/dist/models/access.d.ts.map +1 -1
- package/dist/models/access.js +10 -26
- package/dist/models/access.js.map +1 -1
- package/dist/models/agenda.d.ts +4 -2
- package/dist/models/agenda.d.ts.map +1 -1
- package/dist/models/announcement.d.ts +4 -3
- package/dist/models/announcement.d.ts.map +1 -1
- package/dist/models/announcement.js +2 -3
- package/dist/models/announcement.js.map +1 -1
- package/dist/models/assignment.d.ts +40 -33
- package/dist/models/assignment.d.ts.map +1 -1
- package/dist/models/auth.d.ts +2 -4
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/auth.js +2 -3
- package/dist/models/auth.js.map +1 -1
- package/dist/models/class.d.ts +34 -6
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/class.js +15 -2
- package/dist/models/class.js.map +1 -1
- package/dist/models/cloudStorage.d.ts +153 -0
- package/dist/models/cloudStorage.d.ts.map +1 -0
- package/dist/models/cloudStorage.js +295 -0
- package/dist/models/cloudStorage.js.map +1 -0
- package/dist/models/comment.d.ts +0 -24
- package/dist/models/comment.d.ts.map +1 -1
- package/dist/models/comment.js +2 -6
- package/dist/models/comment.js.map +1 -1
- package/dist/models/conversation.d.ts +22 -22
- package/dist/models/department.d.ts +154 -0
- package/dist/models/department.d.ts.map +1 -0
- package/dist/models/department.js +135 -0
- package/dist/models/department.js.map +1 -0
- package/dist/models/event.d.ts +10 -4
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/event.js +2 -5
- package/dist/models/event.js.map +1 -1
- package/dist/models/file.d.ts +52 -36
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +4 -42
- package/dist/models/file.js.map +1 -1
- package/dist/models/folder.d.ts +47 -0
- package/dist/models/folder.d.ts.map +1 -1
- package/dist/models/labChat.d.ts +11 -9
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/message.d.ts +46 -12
- package/dist/models/message.d.ts.map +1 -1
- package/dist/models/message.js +19 -10
- package/dist/models/message.js.map +1 -1
- package/dist/models/newtonChat.d.ts +2 -1
- package/dist/models/newtonChat.d.ts.map +1 -1
- package/dist/models/school.d.ts +45 -12
- package/dist/models/school.d.ts.map +1 -1
- package/dist/models/school.js +19 -2
- package/dist/models/school.js.map +1 -1
- package/dist/models/section.d.ts +2 -1
- package/dist/models/section.d.ts.map +1 -1
- package/dist/models/tag.d.ts +117 -0
- package/dist/models/tag.d.ts.map +1 -0
- package/dist/models/tag.js +113 -0
- package/dist/models/tag.js.map +1 -0
- package/dist/models/worksheet.d.ts +3 -0
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/pipelines/aiLabChatContract.d.ts +8 -8
- package/dist/routers/_app.d.ts +6704 -5222
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +8 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/agenda.d.ts +4 -2
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +3 -5
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +49 -40
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +2 -3
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/class.d.ts +92 -19
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +5 -2
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/conversation.d.ts +5 -5
- package/dist/routers/department.d.ts +293 -0
- package/dist/routers/department.d.ts.map +1 -0
- package/dist/routers/department.js +93 -0
- package/dist/routers/department.js.map +1 -0
- package/dist/routers/event.d.ts +4 -3
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/file.d.ts +10 -8
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +26 -17
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/folder.d.ts +163 -186
- package/dist/routers/folder.d.ts.map +1 -1
- package/dist/routers/folder.js +102 -88
- package/dist/routers/folder.js.map +1 -1
- package/dist/routers/labChat.d.ts +13 -4
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/message.d.ts +20 -2
- package/dist/routers/message.d.ts.map +1 -1
- package/dist/routers/newtonChat.d.ts +10 -1
- package/dist/routers/newtonChat.d.ts.map +1 -1
- package/dist/routers/permissions.d.ts +120 -0
- package/dist/routers/permissions.d.ts.map +1 -0
- package/dist/routers/permissions.js +50 -0
- package/dist/routers/permissions.js.map +1 -0
- package/dist/routers/school.d.ts +160 -17
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/school.js +46 -3
- package/dist/routers/school.js.map +1 -1
- package/dist/routers/tag.d.ts +119 -0
- package/dist/routers/tag.d.ts.map +1 -0
- package/dist/routers/tag.js +52 -0
- package/dist/routers/tag.js.map +1 -0
- package/dist/routers/worksheet.d.ts +1 -0
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/seedDatabase.d.ts +0 -1
- package/dist/seedDatabase.d.ts.map +1 -1
- package/dist/services/agenda.d.ts +4 -2
- package/dist/services/agenda.d.ts.map +1 -1
- package/dist/services/assignment.d.ts +49 -40
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/class.d.ts +92 -19
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +92 -5
- package/dist/services/class.js.map +1 -1
- package/dist/services/conversation.d.ts +5 -5
- package/dist/services/department.d.ts +200 -0
- package/dist/services/department.d.ts.map +1 -0
- package/dist/services/department.js +368 -0
- package/dist/services/department.js.map +1 -0
- package/dist/services/event.d.ts +4 -3
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/file.d.ts +105 -3
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/file.js +167 -41
- package/dist/services/file.js.map +1 -1
- package/dist/services/folder.d.ts +220 -149
- package/dist/services/folder.d.ts.map +1 -1
- package/dist/services/folder.js +326 -196
- package/dist/services/folder.js.map +1 -1
- package/dist/services/labChat.d.ts +13 -4
- package/dist/services/labChat.d.ts.map +1 -1
- package/dist/services/labChat.js +4 -3
- package/dist/services/labChat.js.map +1 -1
- package/dist/services/message.d.ts +20 -2
- package/dist/services/message.d.ts.map +1 -1
- package/dist/services/message.js +7 -23
- package/dist/services/message.js.map +1 -1
- package/dist/services/newtonChat.d.ts +9 -0
- package/dist/services/newtonChat.d.ts.map +1 -1
- package/dist/services/newtonChat.js +4 -3
- package/dist/services/newtonChat.js.map +1 -1
- package/dist/services/permissions.d.ts +188 -0
- package/dist/services/permissions.d.ts.map +1 -0
- package/dist/services/permissions.js +661 -0
- package/dist/services/permissions.js.map +1 -0
- package/dist/services/school.d.ts +142 -15
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/school.js +308 -54
- package/dist/services/school.js.map +1 -1
- package/dist/services/tag.d.ts +71 -0
- package/dist/services/tag.d.ts.map +1 -0
- package/dist/services/tag.js +178 -0
- package/dist/services/tag.js.map +1 -0
- package/dist/services/worksheet.d.ts +1 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/utils/aiUser.d.ts.map +1 -1
- package/dist/utils/aiUser.js +2 -3
- package/dist/utils/aiUser.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260509220000_institution_overhaul/migration.sql +184 -0
- package/prisma/migrations/20260510170000_add_folder_permissions/migration.sql +93 -0
- package/prisma/schema.prisma +193 -35
- package/src/middleware/security.ts +1 -1
- package/src/models/access.ts +8 -24
- package/src/models/announcement.ts +0 -1
- package/src/models/auth.ts +0 -1
- package/src/models/class.ts +13 -0
- package/src/models/cloudStorage.ts +327 -0
- package/src/models/comment.ts +0 -4
- package/src/models/department.ts +159 -0
- package/src/models/event.ts +0 -3
- package/src/models/file.ts +2 -40
- package/src/models/message.ts +19 -5
- package/src/models/school.ts +26 -0
- package/src/models/tag.ts +140 -0
- package/src/routers/_app.ts +6 -0
- package/src/routers/announcement.ts +1 -3
- package/src/routers/assignment.ts +0 -1
- package/src/routers/class.ts +3 -0
- package/src/routers/department.ts +174 -0
- package/src/routers/file.ts +29 -26
- package/src/routers/folder.ts +127 -118
- package/src/routers/permissions.ts +71 -0
- package/src/routers/school.ts +83 -0
- package/src/routers/tag.ts +78 -0
- package/src/services/class.ts +109 -4
- package/src/services/department.ts +478 -0
- package/src/services/file.ts +172 -43
- package/src/services/folder.ts +399 -237
- package/src/services/labChat.ts +2 -1
- package/src/services/message.ts +5 -21
- package/src/services/newtonChat.ts +2 -1
- package/src/services/permissions.ts +778 -0
- package/src/services/school.ts +369 -57
- package/src/services/tag.ts +229 -0
- package/src/utils/aiUser.ts +0 -1
- package/tests/unit/services/permissions.test.ts +463 -0
package/dist/routers/folder.js
CHANGED
|
@@ -1,115 +1,129 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f76c8e6f-19ba-5dd6-9a07-530a455a8b5f")}catch(e){}}();
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import { createTRPCRouter, protectedProcedure,
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
name: z.string(),
|
|
8
|
-
parentFolderId: z.string().optional(),
|
|
9
|
-
color: z.string().optional(),
|
|
10
|
-
});
|
|
4
|
+
import { createTRPCRouter, protectedProcedure, } from "../trpc.js";
|
|
5
|
+
import { browseFolder, browseSharedWithMe, confirmFolderUpload, createFolderRecord, deleteFolder, getFolder, getFolderParents, getFolderUploadUrls, getRootFolder, listUserScopes, moveFolder, updateFolderRecord, } from "../services/folder.js";
|
|
6
|
+
import { listSharedWithMe } from "../services/permissions.js";
|
|
11
7
|
const directFileSchema = z.object({
|
|
12
8
|
name: z.string(),
|
|
13
9
|
type: z.string(),
|
|
14
10
|
size: z.number(),
|
|
15
11
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Cloud scope discriminator. Folders live under one of:
|
|
14
|
+
* - CLASS: a class shared-files area
|
|
15
|
+
* - SCHOOL_STORAGE: institution-wide files
|
|
16
|
+
* - PERSONAL: a single user's storage
|
|
17
|
+
*
|
|
18
|
+
* All folder operations identify the location they apply to with either a
|
|
19
|
+
* `folderId` (for an existing folder) or a `scope` (when no folder exists yet,
|
|
20
|
+
* e.g. browsing a scope root). There is no `classId` shorthand — use
|
|
21
|
+
* `{ scope: { kind: "CLASS", classId } }` instead.
|
|
22
|
+
*/
|
|
23
|
+
const cloudScopeSchema = z.discriminatedUnion("kind", [
|
|
24
|
+
z.object({ kind: z.literal("CLASS"), classId: z.string() }),
|
|
25
|
+
z.object({ kind: z.literal("SCHOOL_STORAGE"), schoolId: z.string() }),
|
|
26
|
+
z.object({ kind: z.literal("PERSONAL"), userId: z.string() }),
|
|
27
|
+
]);
|
|
28
|
+
/**
|
|
29
|
+
* Extended scope schema for `browse` only. SHARED_WITH_ME is a *virtual*
|
|
30
|
+
* scope — it has no root row in the `Folder` table and you can't create
|
|
31
|
+
* folders inside it directly. It just collects every top-most explicit grant
|
|
32
|
+
* the user holds for "Shared with me"-style display.
|
|
33
|
+
*/
|
|
34
|
+
const browseScopeSchema = z.discriminatedUnion("kind", [
|
|
35
|
+
z.object({ kind: z.literal("CLASS"), classId: z.string() }),
|
|
36
|
+
z.object({ kind: z.literal("SCHOOL_STORAGE"), schoolId: z.string() }),
|
|
37
|
+
z.object({ kind: z.literal("PERSONAL"), userId: z.string() }),
|
|
38
|
+
z.object({ kind: z.literal("SHARED_WITH_ME") }),
|
|
39
|
+
]);
|
|
23
40
|
export const folderRouter = createTRPCRouter({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
/** Browse a folder (or scope root) with breadcrumbs and access flag. */
|
|
42
|
+
browse: protectedProcedure
|
|
43
|
+
.input(z.union([
|
|
44
|
+
z.object({ folderId: z.string() }),
|
|
45
|
+
z.object({ scope: browseScopeSchema }),
|
|
46
|
+
]))
|
|
47
|
+
.query(({ ctx, input }) => {
|
|
48
|
+
if ("scope" in input && input.scope.kind === "SHARED_WITH_ME") {
|
|
49
|
+
return browseSharedWithMe(ctx.user.id);
|
|
29
50
|
}
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
parentFolderId: input.parentFolderId,
|
|
34
|
-
color: input.color,
|
|
35
|
-
});
|
|
51
|
+
return browseFolder(ctx.user.id, "scope" in input
|
|
52
|
+
? { scope: input.scope }
|
|
53
|
+
: input);
|
|
36
54
|
}),
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.input(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.input(
|
|
51
|
-
|
|
52
|
-
if (!ctx.user) {
|
|
53
|
-
throw new Error("You must be logged in to upload files");
|
|
54
|
-
}
|
|
55
|
-
return uploadFilesToFolder(ctx.user.id, input.classId, input.folderId, input.files);
|
|
56
|
-
}),
|
|
57
|
-
delete: protectedTeacherProcedure
|
|
58
|
-
.input(z.object({ classId: z.string(), folderId: z.string() }))
|
|
59
|
-
.mutation(async ({ ctx, input }) => {
|
|
60
|
-
if (!ctx.user) {
|
|
61
|
-
throw new Error("You must be logged in to delete folders");
|
|
62
|
-
}
|
|
63
|
-
return deleteFolderRecord(ctx.user.id, input.classId, input.folderId);
|
|
64
|
-
}),
|
|
65
|
-
move: protectedTeacherProcedure
|
|
55
|
+
/** Top-most folders/files explicitly shared with the caller (Drive-style). */
|
|
56
|
+
listSharedWithMe: protectedProcedure.query(({ ctx }) => listSharedWithMe(ctx.user.id)),
|
|
57
|
+
/** What scopes can this user pick from in the cloud-storage UI? */
|
|
58
|
+
listScopes: protectedProcedure.query(({ ctx }) => listUserScopes(ctx.user.id)),
|
|
59
|
+
/** Root folder for any scope (no folderId). */
|
|
60
|
+
getRootFolder: protectedProcedure
|
|
61
|
+
.input(z.object({ scope: cloudScopeSchema }))
|
|
62
|
+
.query(({ ctx, input }) => getRootFolder(ctx.user.id, input.scope)),
|
|
63
|
+
get: protectedProcedure
|
|
64
|
+
.input(z.object({ folderId: z.string() }))
|
|
65
|
+
.query(({ ctx, input }) => getFolder(ctx.user.id, input.folderId)),
|
|
66
|
+
getParents: protectedProcedure
|
|
67
|
+
.input(z.object({ folderId: z.string() }))
|
|
68
|
+
.query(({ ctx, input }) => getFolderParents(ctx.user.id, input.folderId)),
|
|
69
|
+
create: protectedProcedure
|
|
66
70
|
.input(z.object({
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
name: z.string().min(1),
|
|
72
|
+
parentFolderId: z.string().nullable().optional(),
|
|
73
|
+
color: z.string().optional(),
|
|
74
|
+
scope: cloudScopeSchema.optional(),
|
|
70
75
|
}))
|
|
71
|
-
.mutation(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}),
|
|
77
|
-
update:
|
|
76
|
+
.mutation(({ ctx, input }) => createFolderRecord(ctx.user.id, {
|
|
77
|
+
name: input.name,
|
|
78
|
+
parentFolderId: input.parentFolderId ?? undefined,
|
|
79
|
+
color: input.color,
|
|
80
|
+
scope: input.scope,
|
|
81
|
+
})),
|
|
82
|
+
update: protectedProcedure
|
|
78
83
|
.input(z.object({
|
|
79
84
|
folderId: z.string(),
|
|
80
|
-
name: z.string(),
|
|
85
|
+
name: z.string().optional(),
|
|
81
86
|
color: z.string().optional(),
|
|
82
|
-
classId: z.string(),
|
|
83
87
|
}))
|
|
84
|
-
.mutation(({ input }) => updateFolderRecord(
|
|
85
|
-
|
|
88
|
+
.mutation(({ ctx, input }) => updateFolderRecord(ctx.user.id, {
|
|
89
|
+
folderId: input.folderId,
|
|
90
|
+
name: input.name,
|
|
91
|
+
color: input.color,
|
|
92
|
+
})),
|
|
93
|
+
delete: protectedProcedure
|
|
86
94
|
.input(z.object({ folderId: z.string() }))
|
|
87
|
-
.
|
|
88
|
-
|
|
95
|
+
.mutation(({ ctx, input }) => deleteFolder(ctx.user.id, input.folderId)),
|
|
96
|
+
move: protectedProcedure
|
|
97
|
+
.input(z.object({
|
|
98
|
+
folderId: z.string(),
|
|
99
|
+
targetParentFolderId: z.string(),
|
|
100
|
+
}))
|
|
101
|
+
.mutation(({ ctx, input }) => moveFolder(ctx.user.id, {
|
|
102
|
+
folderId: input.folderId,
|
|
103
|
+
targetParentFolderId: input.targetParentFolderId,
|
|
104
|
+
})),
|
|
105
|
+
/** Get signed upload URLs for direct-to-GCS upload. */
|
|
106
|
+
getFolderUploadUrls: protectedProcedure
|
|
89
107
|
.input(z.object({
|
|
90
|
-
classId: z.string(),
|
|
91
108
|
folderId: z.string(),
|
|
92
109
|
files: z.array(directFileSchema),
|
|
93
110
|
}))
|
|
94
|
-
.mutation(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
confirmFolderUpload: protectedTeacherProcedure
|
|
111
|
+
.mutation(({ ctx, input }) => getFolderUploadUrls(ctx.user.id, {
|
|
112
|
+
folderId: input.folderId,
|
|
113
|
+
files: input.files,
|
|
114
|
+
})),
|
|
115
|
+
/** Acknowledge a direct upload completed (or failed). */
|
|
116
|
+
confirmFolderUpload: protectedProcedure
|
|
101
117
|
.input(z.object({
|
|
102
118
|
fileId: z.string(),
|
|
103
119
|
uploadSuccess: z.boolean(),
|
|
120
|
+
errorMessage: z.string().optional(),
|
|
104
121
|
}))
|
|
105
|
-
.mutation(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await confirmDirectUpload(input.fileId, input.uploadSuccess);
|
|
111
|
-
return { success: true };
|
|
112
|
-
}),
|
|
122
|
+
.mutation(({ ctx, input }) => confirmFolderUpload(ctx.user.id, {
|
|
123
|
+
fileId: input.fileId,
|
|
124
|
+
uploadSuccess: input.uploadSuccess,
|
|
125
|
+
errorMessage: input.errorMessage,
|
|
126
|
+
})),
|
|
113
127
|
});
|
|
114
128
|
//# sourceMappingURL=folder.js.map
|
|
115
|
-
//# debugId=
|
|
129
|
+
//# debugId=f76c8e6f-19ba-5dd6-9a07-530a455a8b5f
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.js","sources":["routers/folder.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedProcedure,\n protectedClassMemberProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport {\n createFolderRecord,\n getFolder,\n getChildFolders,\n getFolderChildren,\n getRootFolder,\n uploadFilesToFolder,\n deleteFolderRecord,\n moveFolder,\n updateFolderRecord,\n getFolderParents,\n getFolderUploadUrls,\n} from \"../services/folder.js\";\n\nconst createFolderSchema = z.object({\n name: z.string(),\n parentFolderId: z.string().optional(),\n color: z.string().optional(),\n});\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\nconst uploadFilesToFolderSchema = z.object({\n folderId: z.string(),\n files: z.array(directFileSchema),\n});\n\nconst getRootFolderSchema = z.object({\n classId: z.string(),\n});\n\nexport const folderRouter = createTRPCRouter({\n create: protectedTeacherProcedure\n .input(createFolderSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to create a folder\");\n }\n return createFolderRecord(ctx.user.id, {\n classId: input.classId,\n name: input.name,\n parentFolderId: input.parentFolderId,\n color: input.color,\n });\n }),\n\n get: protectedClassMemberProcedure\n .input(z.object({ folderId: z.string(), classId: z.string() }))\n .query(({ input }) => getFolder(input.folderId)),\n\n getChildFolders: protectedClassMemberProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ input }) => getChildFolders(input.classId)),\n\n getFolderChildren: protectedClassMemberProcedure\n .input(z.object({ folderId: z.string(), classId: z.string() }))\n .query(({ input }) =>\n getFolderChildren(input.folderId, input.classId)\n ),\n\n getRootFolder: protectedClassMemberProcedure\n .input(getRootFolderSchema)\n .query(({ input }) => getRootFolder(input.classId)),\n\n uploadFiles: protectedTeacherProcedure\n .input(uploadFilesToFolderSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to upload files\");\n }\n return uploadFilesToFolder(\n ctx.user.id,\n input.classId,\n input.folderId,\n input.files\n );\n }),\n\n delete: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), folderId: z.string() }))\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to delete folders\");\n }\n return deleteFolderRecord(ctx.user.id, input.classId, input.folderId);\n }),\n\n move: protectedTeacherProcedure\n .input(\n z.object({\n folderId: z.string(),\n targetParentFolderId: z.string(),\n classId: z.string(),\n })\n )\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to move folders\");\n }\n return moveFolder(\n ctx.user.id,\n input.folderId,\n input.targetParentFolderId,\n input.classId\n );\n }),\n\n update: protectedTeacherProcedure\n .input(\n z.object({\n folderId: z.string(),\n name: z.string(),\n color: z.string().optional(),\n classId: z.string(),\n })\n )\n .mutation(({ input }) =>\n updateFolderRecord(\n input.folderId,\n input.name,\n input.color,\n input.classId\n )\n ),\n\n getParents: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ input }) => getFolderParents(input.folderId)),\n\n getFolderUploadUrls: protectedTeacherProcedure\n .input(\n z.object({\n classId: z.string(),\n folderId: z.string(),\n files: z.array(directFileSchema),\n })\n )\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to upload files\");\n }\n return getFolderUploadUrls(\n ctx.user.id,\n input.classId,\n input.folderId,\n input.files\n );\n }),\n\n confirmFolderUpload: protectedTeacherProcedure\n .input(\n z.object({\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n })\n )\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new Error(\"You must be logged in to confirm uploads\");\n }\n const { confirmDirectUpload } = await import(\"../lib/fileUpload.js\");\n await confirmDirectUpload(input.fileId, input.uploadSuccess);\n return { success: true };\n }),\n});\n"],"names":[],"mappings":"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","debug_id":"2a91768b-a0eb-5556-9154-f76d73b01c49"}
|
|
1
|
+
{"version":3,"file":"folder.js","sources":["routers/folder.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedProcedure,\n} from \"../trpc.js\";\nimport {\n browseFolder,\n browseSharedWithMe,\n confirmFolderUpload,\n createFolderRecord,\n deleteFolder,\n getFolder,\n getFolderParents,\n getFolderUploadUrls,\n getRootFolder,\n listUserScopes,\n moveFolder,\n updateFolderRecord,\n} from \"../services/folder.js\";\nimport { listSharedWithMe } from \"../services/permissions.js\";\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\n/**\n * Cloud scope discriminator. Folders live under one of:\n * - CLASS: a class shared-files area\n * - SCHOOL_STORAGE: institution-wide files\n * - PERSONAL: a single user's storage\n *\n * All folder operations identify the location they apply to with either a\n * `folderId` (for an existing folder) or a `scope` (when no folder exists yet,\n * e.g. browsing a scope root). There is no `classId` shorthand — use\n * `{ scope: { kind: \"CLASS\", classId } }` instead.\n */\nconst cloudScopeSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL_STORAGE\"), schoolId: z.string() }),\n z.object({ kind: z.literal(\"PERSONAL\"), userId: z.string() }),\n]);\n\n/**\n * Extended scope schema for `browse` only. SHARED_WITH_ME is a *virtual*\n * scope — it has no root row in the `Folder` table and you can't create\n * folders inside it directly. It just collects every top-most explicit grant\n * the user holds for \"Shared with me\"-style display.\n */\nconst browseScopeSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL_STORAGE\"), schoolId: z.string() }),\n z.object({ kind: z.literal(\"PERSONAL\"), userId: z.string() }),\n z.object({ kind: z.literal(\"SHARED_WITH_ME\") }),\n]);\n\nexport const folderRouter = createTRPCRouter({\n /** Browse a folder (or scope root) with breadcrumbs and access flag. */\n browse: protectedProcedure\n .input(\n z.union([\n z.object({ folderId: z.string() }),\n z.object({ scope: browseScopeSchema }),\n ])\n )\n .query(({ ctx, input }) => {\n if (\"scope\" in input && input.scope.kind === \"SHARED_WITH_ME\") {\n return browseSharedWithMe(ctx.user!.id);\n }\n return browseFolder(\n ctx.user!.id,\n \"scope\" in input\n ? { scope: input.scope as Exclude<typeof input.scope, { kind: \"SHARED_WITH_ME\" }> }\n : input\n );\n }),\n\n /** Top-most folders/files explicitly shared with the caller (Drive-style). */\n listSharedWithMe: protectedProcedure.query(({ ctx }) =>\n listSharedWithMe(ctx.user!.id)\n ),\n\n /** What scopes can this user pick from in the cloud-storage UI? */\n listScopes: protectedProcedure.query(({ ctx }) =>\n listUserScopes(ctx.user!.id)\n ),\n\n /** Root folder for any scope (no folderId). */\n getRootFolder: protectedProcedure\n .input(z.object({ scope: cloudScopeSchema }))\n .query(({ ctx, input }) => getRootFolder(ctx.user!.id, input.scope)),\n\n get: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolder(ctx.user!.id, input.folderId)),\n\n getParents: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolderParents(ctx.user!.id, input.folderId)),\n\n create: protectedProcedure\n .input(\n z.object({\n name: z.string().min(1),\n parentFolderId: z.string().nullable().optional(),\n color: z.string().optional(),\n scope: cloudScopeSchema.optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n createFolderRecord(ctx.user!.id, {\n name: input.name,\n parentFolderId: input.parentFolderId ?? undefined,\n color: input.color,\n scope: input.scope,\n })\n ),\n\n update: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n name: z.string().optional(),\n color: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateFolderRecord(ctx.user!.id, {\n folderId: input.folderId,\n name: input.name,\n color: input.color,\n })\n ),\n\n delete: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .mutation(({ ctx, input }) => deleteFolder(ctx.user!.id, input.folderId)),\n\n move: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n targetParentFolderId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n moveFolder(ctx.user!.id, {\n folderId: input.folderId,\n targetParentFolderId: input.targetParentFolderId,\n })\n ),\n\n /** Get signed upload URLs for direct-to-GCS upload. */\n getFolderUploadUrls: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n files: z.array(directFileSchema),\n })\n )\n .mutation(({ ctx, input }) =>\n getFolderUploadUrls(ctx.user!.id, {\n folderId: input.folderId,\n files: input.files,\n })\n ),\n\n /** Acknowledge a direct upload completed (or failed). */\n confirmFolderUpload: protectedProcedure\n .input(\n z.object({\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n errorMessage: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n confirmFolderUpload(ctx.user!.id, {\n fileId: input.fileId,\n uploadSuccess: input.uploadSuccess,\n errorMessage: input.errorMessage,\n })\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"f76c8e6f-19ba-5dd6-9a07-530a455a8b5f"}
|
|
@@ -41,8 +41,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
41
41
|
};
|
|
42
42
|
} & {
|
|
43
43
|
id: string;
|
|
44
|
-
role: import(".prisma/client").$Enums.ConversationRole;
|
|
45
44
|
userId: string;
|
|
45
|
+
role: import(".prisma/client").$Enums.ConversationRole;
|
|
46
46
|
conversationId: string;
|
|
47
47
|
joinedAt: Date;
|
|
48
48
|
hiddenAt: Date | null;
|
|
@@ -69,8 +69,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
69
69
|
id: string;
|
|
70
70
|
createdAt: Date;
|
|
71
71
|
updatedAt: Date;
|
|
72
|
-
conversationId: string;
|
|
73
72
|
classId: string;
|
|
73
|
+
conversationId: string;
|
|
74
74
|
title: string;
|
|
75
75
|
createdById: string;
|
|
76
76
|
};
|
|
@@ -100,8 +100,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
100
100
|
};
|
|
101
101
|
} & {
|
|
102
102
|
id: string;
|
|
103
|
-
role: import(".prisma/client").$Enums.ConversationRole;
|
|
104
103
|
userId: string;
|
|
104
|
+
role: import(".prisma/client").$Enums.ConversationRole;
|
|
105
105
|
conversationId: string;
|
|
106
106
|
joinedAt: Date;
|
|
107
107
|
hiddenAt: Date | null;
|
|
@@ -128,8 +128,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
128
128
|
id: string;
|
|
129
129
|
createdAt: Date;
|
|
130
130
|
updatedAt: Date;
|
|
131
|
-
conversationId: string;
|
|
132
131
|
classId: string;
|
|
132
|
+
conversationId: string;
|
|
133
133
|
title: string;
|
|
134
134
|
createdById: string;
|
|
135
135
|
};
|
|
@@ -198,9 +198,18 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
198
198
|
} | null;
|
|
199
199
|
};
|
|
200
200
|
attachments: {
|
|
201
|
+
path: string;
|
|
201
202
|
type: string;
|
|
202
203
|
name: string;
|
|
203
204
|
id: string;
|
|
205
|
+
size: number | null;
|
|
206
|
+
uploadedAt: Date | null;
|
|
207
|
+
uploadStatus: import(".prisma/client").$Enums.UploadStatus;
|
|
208
|
+
thumbnailId: string | null;
|
|
209
|
+
thumbnail: {
|
|
210
|
+
path: string;
|
|
211
|
+
id: string;
|
|
212
|
+
} | null;
|
|
204
213
|
}[];
|
|
205
214
|
mentionedUserIds: string[];
|
|
206
215
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["routers/labChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["routers/labChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDxB,CAAC"}
|
|
@@ -39,9 +39,18 @@ export declare const messageRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
39
39
|
};
|
|
40
40
|
status: import(".prisma/client").$Enums.JobStatus | null;
|
|
41
41
|
attachments: {
|
|
42
|
-
|
|
43
|
-
name: string;
|
|
42
|
+
path: string;
|
|
44
43
|
type: string;
|
|
44
|
+
name: string;
|
|
45
|
+
id: string;
|
|
46
|
+
size: number | null;
|
|
47
|
+
uploadedAt: Date | null;
|
|
48
|
+
uploadStatus: import(".prisma/client").$Enums.UploadStatus;
|
|
49
|
+
thumbnailId: string | null;
|
|
50
|
+
thumbnail: {
|
|
51
|
+
path: string;
|
|
52
|
+
id: string;
|
|
53
|
+
} | null;
|
|
45
54
|
}[];
|
|
46
55
|
meta: Record<string, unknown>;
|
|
47
56
|
mentions: {
|
|
@@ -82,9 +91,18 @@ export declare const messageRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
82
91
|
} | null;
|
|
83
92
|
};
|
|
84
93
|
attachments: {
|
|
94
|
+
path: string;
|
|
85
95
|
type: string;
|
|
86
96
|
name: string;
|
|
87
97
|
id: string;
|
|
98
|
+
size: number | null;
|
|
99
|
+
uploadedAt: Date | null;
|
|
100
|
+
uploadStatus: import(".prisma/client").$Enums.UploadStatus;
|
|
101
|
+
thumbnailId: string | null;
|
|
102
|
+
thumbnail: {
|
|
103
|
+
path: string;
|
|
104
|
+
id: string;
|
|
105
|
+
} | null;
|
|
88
106
|
}[];
|
|
89
107
|
mentionedUserIds: string[];
|
|
90
108
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"/","sources":["routers/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"/","sources":["routers/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqHxB,CAAC"}
|
|
@@ -18,8 +18,8 @@ export declare const newtonChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
18
18
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
19
19
|
getTutorConversation: import("@trpc/server").TRPCQueryProcedure<{
|
|
20
20
|
input: {
|
|
21
|
-
assignmentId: string;
|
|
22
21
|
classId: string;
|
|
22
|
+
assignmentId: string;
|
|
23
23
|
};
|
|
24
24
|
output: {
|
|
25
25
|
conversationId: string;
|
|
@@ -50,9 +50,18 @@ export declare const newtonChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
50
50
|
} | null;
|
|
51
51
|
};
|
|
52
52
|
attachments: {
|
|
53
|
+
path: string;
|
|
53
54
|
type: string;
|
|
54
55
|
name: string;
|
|
55
56
|
id: string;
|
|
57
|
+
size: number | null;
|
|
58
|
+
uploadedAt: Date | null;
|
|
59
|
+
uploadStatus: import(".prisma/client").$Enums.UploadStatus;
|
|
60
|
+
thumbnailId: string | null;
|
|
61
|
+
thumbnail: {
|
|
62
|
+
path: string;
|
|
63
|
+
id: string;
|
|
64
|
+
} | null;
|
|
56
65
|
}[];
|
|
57
66
|
mentionedUserIds: string[];
|
|
58
67
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["routers/newtonChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["routers/newtonChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8B3B,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions router. Backs the "Share" dialog and the "Shared with me" view.
|
|
3
|
+
*
|
|
4
|
+
* Permission semantics live in `services/permissions.ts`; this router is just
|
|
5
|
+
* a thin Zod-validated tRPC surface over those helpers.
|
|
6
|
+
*
|
|
7
|
+
* v1 grants only on folders. Files inherit from their parent folder. Adding
|
|
8
|
+
* file-level grants later is a non-breaking, additive change.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { type PermissionPrincipalInput } from "../services/permissions.js";
|
|
12
|
+
export declare const permissionsRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
13
|
+
ctx: import("../trpc.js").Context;
|
|
14
|
+
meta: object;
|
|
15
|
+
errorShape: {
|
|
16
|
+
data: {
|
|
17
|
+
zodError: z.typeToFlattenedError<any, string> | null;
|
|
18
|
+
prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
|
|
19
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
20
|
+
httpStatus: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
};
|
|
24
|
+
message: string;
|
|
25
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
26
|
+
};
|
|
27
|
+
transformer: false;
|
|
28
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
29
|
+
/** List all explicit grants on a folder. Caller must have WRITE. */
|
|
30
|
+
list: import("@trpc/server").TRPCQueryProcedure<{
|
|
31
|
+
input: {
|
|
32
|
+
folderId: string;
|
|
33
|
+
};
|
|
34
|
+
output: ({
|
|
35
|
+
school: {
|
|
36
|
+
name: string;
|
|
37
|
+
id: string;
|
|
38
|
+
} | null;
|
|
39
|
+
user: {
|
|
40
|
+
id: string;
|
|
41
|
+
username: string;
|
|
42
|
+
email: string;
|
|
43
|
+
} | null;
|
|
44
|
+
class: {
|
|
45
|
+
name: string;
|
|
46
|
+
id: string;
|
|
47
|
+
section: string;
|
|
48
|
+
} | null;
|
|
49
|
+
department: {
|
|
50
|
+
name: string;
|
|
51
|
+
id: string;
|
|
52
|
+
color: string | null;
|
|
53
|
+
} | null;
|
|
54
|
+
tag: {
|
|
55
|
+
name: string;
|
|
56
|
+
id: string;
|
|
57
|
+
color: string;
|
|
58
|
+
} | null;
|
|
59
|
+
} & {
|
|
60
|
+
level: import(".prisma/client").$Enums.PermissionLevel;
|
|
61
|
+
id: string;
|
|
62
|
+
createdAt: Date;
|
|
63
|
+
schoolId: string | null;
|
|
64
|
+
userId: string | null;
|
|
65
|
+
departmentId: string | null;
|
|
66
|
+
folderId: string;
|
|
67
|
+
principalType: import(".prisma/client").$Enums.PermissionPrincipalType;
|
|
68
|
+
tagId: string | null;
|
|
69
|
+
classId: string | null;
|
|
70
|
+
grantedById: string;
|
|
71
|
+
})[];
|
|
72
|
+
meta: object;
|
|
73
|
+
}>;
|
|
74
|
+
/** Create a new explicit grant on a folder. */
|
|
75
|
+
grant: import("@trpc/server").TRPCMutationProcedure<{
|
|
76
|
+
input: {
|
|
77
|
+
level: "READ" | "WRITE";
|
|
78
|
+
folderId: string;
|
|
79
|
+
principal: PermissionPrincipalInput;
|
|
80
|
+
};
|
|
81
|
+
output: {
|
|
82
|
+
level: import(".prisma/client").$Enums.PermissionLevel;
|
|
83
|
+
id: string;
|
|
84
|
+
createdAt: Date;
|
|
85
|
+
schoolId: string | null;
|
|
86
|
+
userId: string | null;
|
|
87
|
+
departmentId: string | null;
|
|
88
|
+
folderId: string;
|
|
89
|
+
principalType: import(".prisma/client").$Enums.PermissionPrincipalType;
|
|
90
|
+
tagId: string | null;
|
|
91
|
+
classId: string | null;
|
|
92
|
+
grantedById: string;
|
|
93
|
+
};
|
|
94
|
+
meta: object;
|
|
95
|
+
}>;
|
|
96
|
+
/** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */
|
|
97
|
+
revoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
98
|
+
input: {
|
|
99
|
+
permissionId: string;
|
|
100
|
+
};
|
|
101
|
+
output: {
|
|
102
|
+
success: boolean;
|
|
103
|
+
};
|
|
104
|
+
meta: object;
|
|
105
|
+
}>;
|
|
106
|
+
/** Drive-style "Shared with me" — top-most folders explicitly granted to the caller. */
|
|
107
|
+
listSharedWithMe: import("@trpc/server").TRPCQueryProcedure<{
|
|
108
|
+
input: void;
|
|
109
|
+
output: {
|
|
110
|
+
folders: {
|
|
111
|
+
id: string;
|
|
112
|
+
name: string;
|
|
113
|
+
color: string | null;
|
|
114
|
+
}[];
|
|
115
|
+
files: never[];
|
|
116
|
+
};
|
|
117
|
+
meta: object;
|
|
118
|
+
}>;
|
|
119
|
+
}>>;
|
|
120
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"/","sources":["routers/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAKL,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAiBpC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;IAC5B,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOpE,+CAA+C;;;;;;;;;;;;;;;;;;;;;;IAiB/C,4FAA4F;;;;;;;;;;IAO5F,wFAAwF;;;;;;;;;;;;;GAIxF,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions router. Backs the "Share" dialog and the "Shared with me" view.
|
|
3
|
+
*
|
|
4
|
+
* Permission semantics live in `services/permissions.ts`; this router is just
|
|
5
|
+
* a thin Zod-validated tRPC surface over those helpers.
|
|
6
|
+
*
|
|
7
|
+
* v1 grants only on folders. Files inherit from their parent folder. Adding
|
|
8
|
+
* file-level grants later is a non-breaking, additive change.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="dccc1159-4761-5abc-bf19-947124f66887")}catch(e){}}();
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
|
14
|
+
import { grantPermission, listPermissions, listSharedWithMe, revokePermission, } from "../services/permissions.js";
|
|
15
|
+
const principalSchema = z.discriminatedUnion("kind", [
|
|
16
|
+
z.object({ kind: z.literal("USER"), userId: z.string() }),
|
|
17
|
+
z.object({ kind: z.literal("TAG"), tagId: z.string() }),
|
|
18
|
+
z.object({ kind: z.literal("CLASS"), classId: z.string() }),
|
|
19
|
+
z.object({ kind: z.literal("CLASS_TEACHERS"), classId: z.string() }),
|
|
20
|
+
z.object({ kind: z.literal("CLASS_STUDENTS"), classId: z.string() }),
|
|
21
|
+
z.object({ kind: z.literal("DEPARTMENT"), departmentId: z.string() }),
|
|
22
|
+
z.object({ kind: z.literal("SCHOOL"), schoolId: z.string() }),
|
|
23
|
+
]);
|
|
24
|
+
const levelSchema = z.enum(["READ", "WRITE"]);
|
|
25
|
+
export const permissionsRouter = createTRPCRouter({
|
|
26
|
+
/** List all explicit grants on a folder. Caller must have WRITE. */
|
|
27
|
+
list: protectedProcedure
|
|
28
|
+
.input(z.object({ folderId: z.string() }))
|
|
29
|
+
.query(({ ctx, input }) => listPermissions(ctx.user.id, input.folderId)),
|
|
30
|
+
/** Create a new explicit grant on a folder. */
|
|
31
|
+
grant: protectedProcedure
|
|
32
|
+
.input(z.object({
|
|
33
|
+
folderId: z.string(),
|
|
34
|
+
principal: principalSchema,
|
|
35
|
+
level: levelSchema,
|
|
36
|
+
}))
|
|
37
|
+
.mutation(({ ctx, input }) => grantPermission(ctx.user.id, {
|
|
38
|
+
folderId: input.folderId,
|
|
39
|
+
principal: input.principal,
|
|
40
|
+
level: input.level,
|
|
41
|
+
})),
|
|
42
|
+
/** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */
|
|
43
|
+
revoke: protectedProcedure
|
|
44
|
+
.input(z.object({ permissionId: z.string() }))
|
|
45
|
+
.mutation(({ ctx, input }) => revokePermission(ctx.user.id, input.permissionId)),
|
|
46
|
+
/** Drive-style "Shared with me" — top-most folders explicitly granted to the caller. */
|
|
47
|
+
listSharedWithMe: protectedProcedure.query(({ ctx }) => listSharedWithMe(ctx.user.id)),
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=permissions.js.map
|
|
50
|
+
//# debugId=dccc1159-4761-5abc-bf19-947124f66887
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sources":["routers/permissions.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Permissions router. Backs the \"Share\" dialog and the \"Shared with me\" view.\n *\n * Permission semantics live in `services/permissions.ts`; this router is just\n * a thin Zod-validated tRPC surface over those helpers.\n *\n * v1 grants only on folders. Files inherit from their parent folder. Adding\n * file-level grants later is a non-breaking, additive change.\n */\nimport { z } from \"zod\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport {\n grantPermission,\n listPermissions,\n listSharedWithMe,\n revokePermission,\n type PermissionPrincipalInput,\n} from \"../services/permissions.js\";\n\nconst principalSchema: z.ZodType<PermissionPrincipalInput> = z.discriminatedUnion(\n \"kind\",\n [\n z.object({ kind: z.literal(\"USER\"), userId: z.string() }),\n z.object({ kind: z.literal(\"TAG\"), tagId: z.string() }),\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"CLASS_TEACHERS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"CLASS_STUDENTS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"DEPARTMENT\"), departmentId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL\"), schoolId: z.string() }),\n ]\n);\n\nconst levelSchema = z.enum([\"READ\", \"WRITE\"]);\n\nexport const permissionsRouter = createTRPCRouter({\n /** List all explicit grants on a folder. Caller must have WRITE. */\n list: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) =>\n listPermissions(ctx.user!.id, input.folderId)\n ),\n\n /** Create a new explicit grant on a folder. */\n grant: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n principal: principalSchema,\n level: levelSchema,\n })\n )\n .mutation(({ ctx, input }) =>\n grantPermission(ctx.user!.id, {\n folderId: input.folderId,\n principal: input.principal,\n level: input.level,\n })\n ),\n\n /** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */\n revoke: protectedProcedure\n .input(z.object({ permissionId: z.string() }))\n .mutation(({ ctx, input }) =>\n revokePermission(ctx.user!.id, input.permissionId)\n ),\n\n /** Drive-style \"Shared with me\" — top-most folders explicitly granted to the caller. */\n listSharedWithMe: protectedProcedure.query(({ ctx }) =>\n listSharedWithMe(ctx.user!.id)\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"dccc1159-4761-5abc-bf19-947124f66887"}
|