@studious-lms/server 1.4.2 → 1.4.4
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/.coderabbit.yaml +4 -1
- package/.vscode/settings.json +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +68 -29
- package/dist/index.js.map +1 -1
- package/dist/lib/fileUpload.d.ts +10 -2
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +38 -6
- package/dist/lib/fileUpload.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +18 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/models/auth.d.ts +19 -14
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/auth.js +53 -30
- package/dist/models/auth.js.map +1 -1
- package/dist/models/class.d.ts +3 -1
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/class.js +16 -4
- package/dist/models/class.js.map +1 -1
- package/dist/models/notification.d.ts +11 -10
- package/dist/models/notification.d.ts.map +1 -1
- package/dist/models/notification.js +13 -9
- package/dist/models/notification.js.map +1 -1
- package/dist/models/worksheet.d.ts +379 -7
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/models/worksheet.js +168 -2
- package/dist/models/worksheet.js.map +1 -1
- package/dist/pipelines/aiLabChat.d.ts.map +1 -1
- package/dist/pipelines/aiLabChat.js +11 -3
- package/dist/pipelines/aiLabChat.js.map +1 -1
- package/dist/pipelines/aiLabChatContract.d.ts +3 -3
- package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
- package/dist/pipelines/aiNewtonChat.js +25 -14
- package/dist/pipelines/aiNewtonChat.js.map +1 -1
- package/dist/pipelines/gradeWorksheet.d.ts.map +1 -1
- package/dist/pipelines/gradeWorksheet.js +10 -3
- package/dist/pipelines/gradeWorksheet.js.map +1 -1
- package/dist/pipelines/pdfToWorksheet.d.ts +12 -0
- package/dist/pipelines/pdfToWorksheet.d.ts.map +1 -0
- package/dist/pipelines/pdfToWorksheet.js +155 -0
- package/dist/pipelines/pdfToWorksheet.js.map +1 -0
- package/dist/routers/_app.d.ts +264 -16
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/class.d.ts +2 -1
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +3 -3
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/labChat.d.ts +6 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/labChat.js +5 -3
- package/dist/routers/labChat.js.map +1 -1
- package/dist/routers/message.d.ts +31 -0
- package/dist/routers/message.d.ts.map +1 -1
- package/dist/routers/message.js +27 -4
- package/dist/routers/message.js.map +1 -1
- package/dist/routers/newtonChat.d.ts +6 -0
- package/dist/routers/newtonChat.d.ts.map +1 -1
- package/dist/routers/newtonChat.js +5 -4
- package/dist/routers/newtonChat.js.map +1 -1
- package/dist/routers/notifications.d.ts +9 -2
- package/dist/routers/notifications.d.ts.map +1 -1
- package/dist/routers/notifications.js +4 -4
- package/dist/routers/notifications.js.map +1 -1
- package/dist/routers/worksheet.d.ts +78 -5
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +126 -17
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/services/auth.d.ts +1 -1
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +19 -12
- package/dist/services/auth.js.map +1 -1
- package/dist/services/class.d.ts +1 -1
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +6 -3
- package/dist/services/class.js.map +1 -1
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/file.js +7 -2
- package/dist/services/file.js.map +1 -1
- package/dist/services/labChat.d.ts +6 -0
- package/dist/services/labChat.d.ts.map +1 -1
- package/dist/services/labChat.js +30 -18
- package/dist/services/labChat.js.map +1 -1
- package/dist/services/message.d.ts +30 -0
- package/dist/services/message.d.ts.map +1 -1
- package/dist/services/message.js +97 -21
- package/dist/services/message.js.map +1 -1
- package/dist/services/newtonChat.d.ts +6 -1
- package/dist/services/newtonChat.d.ts.map +1 -1
- package/dist/services/newtonChat.js +36 -18
- package/dist/services/newtonChat.js.map +1 -1
- package/dist/services/notification.d.ts +12 -5
- package/dist/services/notification.d.ts.map +1 -1
- package/dist/services/notification.js +24 -9
- package/dist/services/notification.js.map +1 -1
- package/dist/services/studentProgress.d.ts.map +1 -1
- package/dist/services/studentProgress.js +6 -3
- package/dist/services/studentProgress.js.map +1 -1
- package/dist/services/worksheet.d.ts +36 -15
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +186 -54
- package/dist/services/worksheet.js.map +1 -1
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +11 -17
- package/dist/trpc.js.map +1 -1
- package/dist/utils/inference.d.ts +10 -1
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +186 -50
- package/dist/utils/inference.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260415103500_add_session_type/migration.sql +33 -0
- package/prisma/migrations/20260415133000_add_ai_usage_logs/migration.sql +19 -0
- package/prisma/schema.prisma +27 -1
- package/scripts/test-pre-push.ts +6 -2
- package/src/index.ts +83 -30
- package/src/lib/fileUpload.ts +55 -5
- package/src/middleware/auth.ts +19 -4
- package/src/models/auth.ts +59 -29
- package/src/models/class.ts +15 -4
- package/src/models/notification.ts +13 -7
- package/src/models/worksheet.ts +203 -0
- package/src/pipelines/aiLabChat.ts +9 -1
- package/src/pipelines/aiNewtonChat.ts +24 -14
- package/src/pipelines/gradeWorksheet.ts +8 -0
- package/src/pipelines/pdfToWorksheet.ts +177 -0
- package/src/routers/class.ts +2 -2
- package/src/routers/labChat.ts +3 -1
- package/src/routers/message.ts +38 -1
- package/src/routers/newtonChat.ts +4 -2
- package/src/routers/notifications.ts +2 -2
- package/src/routers/worksheet.ts +174 -19
- package/src/services/auth.ts +26 -12
- package/src/services/class.ts +4 -1
- package/src/services/file.ts +6 -0
- package/src/services/labChat.ts +42 -18
- package/src/services/message.ts +163 -18
- package/src/services/newtonChat.ts +49 -18
- package/src/services/notification.ts +27 -8
- package/src/services/studentProgress.ts +4 -1
- package/src/services/worksheet.ts +252 -51
- package/src/trpc.ts +12 -18
- package/src/utils/inference.ts +280 -56
- package/tests/globalSetup.ts +13 -4
- package/tests/pipelines/pdfToWorksheet.test.ts +176 -0
- package/tests/routers/auth.test.ts +120 -17
- package/tests/routers/class.test.ts +7 -1
- package/tests/routers/message.test.ts +236 -9
- package/tests/routers/newtonChat.test.ts +81 -0
- package/tests/routers/notification.test.ts +12 -0
- package/tests/routers/worksheet.test.ts +194 -0
- package/tests/setup.ts +22 -5
- package/tests/utils/inference.test.ts +255 -0
|
@@ -1,13 +1,43 @@
|
|
|
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]="31932b12-1093-5e0f-a21c-e9301dcb8c25")}catch(e){}}();
|
|
3
3
|
import { TRPCError } from "@trpc/server";
|
|
4
|
-
import {
|
|
4
|
+
import { prisma } from "../lib/prisma.js";
|
|
5
|
+
import { confirmDirectUpload, createDirectUploadFiles, updateUploadProgress, } from "../lib/fileUpload.js";
|
|
6
|
+
import { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure, protectedTeacherProcedure, } from "../trpc.js";
|
|
5
7
|
import { z } from "zod";
|
|
6
|
-
import { getWorksheet, worksheetExists, listWorksheets, updateWorksheetRecord, deleteWorksheetRecord, createWorksheetRecord, addQuestionToWorksheet, reorderWorksheetQuestions, updateWorksheetQuestionRecord, deleteWorksheetQuestionRecord, getWorksheetSubmission, answerWorksheetQuestion, cancelGrading, regradeQuestion, gradeAnswer, addCommentToResponse, } from "../services/worksheet.js";
|
|
8
|
+
import { getWorksheet, worksheetExists, listWorksheets, updateWorksheetRecord, deleteWorksheetRecord, createWorksheetRecord, createWorksheetFromPdf, createWorksheetFromUploadedPdf, addQuestionToWorksheet, reorderWorksheetQuestions, updateWorksheetQuestionRecord, deleteWorksheetQuestionRecord, getWorksheetSubmission, answerWorksheetQuestion, cancelGrading, regradeQuestion, gradeAnswer, addCommentToResponse, } from "../services/worksheet.js";
|
|
9
|
+
const directFileSchema = z.object({
|
|
10
|
+
name: z.string(),
|
|
11
|
+
type: z.string(),
|
|
12
|
+
size: z.number(),
|
|
13
|
+
});
|
|
14
|
+
const pdfFileSchema = directFileSchema.superRefine((file, ctx) => {
|
|
15
|
+
const isPdf = file.type === "application/pdf" && file.name.toLowerCase().endsWith(".pdf");
|
|
16
|
+
if (!isPdf) {
|
|
17
|
+
ctx.addIssue({
|
|
18
|
+
code: z.ZodIssueCode.custom,
|
|
19
|
+
message: "Only PDF files are supported",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const getWorksheetUploadUrlsSchema = z.object({
|
|
24
|
+
classId: z.string(),
|
|
25
|
+
files: z.array(pdfFileSchema),
|
|
26
|
+
});
|
|
27
|
+
const confirmWorksheetUploadSchema = z.object({
|
|
28
|
+
classId: z.string(),
|
|
29
|
+
fileId: z.string(),
|
|
30
|
+
uploadSuccess: z.boolean(),
|
|
31
|
+
errorMessage: z.string().optional(),
|
|
32
|
+
});
|
|
33
|
+
const updateUploadProgressSchema = z.object({
|
|
34
|
+
fileId: z.string(),
|
|
35
|
+
progress: z.number().min(0).max(100),
|
|
36
|
+
});
|
|
7
37
|
export const worksheetRouter = createTRPCRouter({
|
|
8
38
|
getWorksheet: protectedProcedure
|
|
9
39
|
.input(z.object({ worksheetId: z.string() }))
|
|
10
|
-
.query(({ input }) => getWorksheet(input.worksheetId)),
|
|
40
|
+
.query(({ ctx, input }) => getWorksheet(input.worksheetId, ctx.user.id)),
|
|
11
41
|
exists: protectedClassMemberProcedure
|
|
12
42
|
.input(z.object({ id: z.string() }))
|
|
13
43
|
.query(async ({ ctx, input }) => {
|
|
@@ -19,18 +49,70 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
19
49
|
}
|
|
20
50
|
return worksheetExists(input.id);
|
|
21
51
|
}),
|
|
22
|
-
listWorksheets:
|
|
52
|
+
listWorksheets: protectedClassMemberProcedure
|
|
23
53
|
.input(z.object({ classId: z.string() }))
|
|
24
54
|
.query(({ input }) => listWorksheets(input.classId)),
|
|
25
55
|
updateWorksheet: protectedProcedure
|
|
26
56
|
.input(z.object({ worksheetId: z.string(), name: z.string().optional() }))
|
|
27
|
-
.mutation(({ input }) => updateWorksheetRecord(input.worksheetId,
|
|
57
|
+
.mutation(({ ctx, input }) => updateWorksheetRecord(input.worksheetId, ctx.user.id, {
|
|
58
|
+
name: input.name,
|
|
59
|
+
})),
|
|
28
60
|
deleteWorksheet: protectedProcedure
|
|
29
61
|
.input(z.object({ worksheetId: z.string() }))
|
|
30
|
-
.mutation(({ input }) => deleteWorksheetRecord(input.worksheetId)),
|
|
31
|
-
create:
|
|
62
|
+
.mutation(({ ctx, input }) => deleteWorksheetRecord(input.worksheetId, ctx.user.id)),
|
|
63
|
+
create: protectedTeacherProcedure
|
|
32
64
|
.input(z.object({ classId: z.string(), name: z.string() }))
|
|
33
65
|
.mutation(({ input }) => createWorksheetRecord(input.classId, input.name)),
|
|
66
|
+
createFromPdf: protectedTeacherProcedure
|
|
67
|
+
.input(z.object({ classId: z.string(), url: z.string().url() }))
|
|
68
|
+
.mutation(({ input }) => createWorksheetFromPdf(input.classId, input.url)),
|
|
69
|
+
getWorksheetUploadUrls: protectedTeacherProcedure
|
|
70
|
+
.input(getWorksheetUploadUrlsSchema)
|
|
71
|
+
.mutation(async ({ ctx, input }) => {
|
|
72
|
+
if (!ctx.user) {
|
|
73
|
+
throw new TRPCError({
|
|
74
|
+
code: "UNAUTHORIZED",
|
|
75
|
+
message: "You must be logged in to upload files",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const uploadFiles = await createDirectUploadFiles(input.files, ctx.user.id);
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
uploadFiles,
|
|
82
|
+
};
|
|
83
|
+
}),
|
|
84
|
+
confirmWorksheetUpload: protectedTeacherProcedure
|
|
85
|
+
.input(confirmWorksheetUploadSchema)
|
|
86
|
+
.mutation(async ({ ctx, input }) => {
|
|
87
|
+
if (!ctx.user) {
|
|
88
|
+
throw new TRPCError({
|
|
89
|
+
code: "UNAUTHORIZED",
|
|
90
|
+
message: "You must be logged in",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const file = await prisma.file.findFirst({
|
|
94
|
+
where: {
|
|
95
|
+
id: input.fileId,
|
|
96
|
+
userId: ctx.user.id,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
if (!file) {
|
|
100
|
+
throw new TRPCError({
|
|
101
|
+
code: "NOT_FOUND",
|
|
102
|
+
message: "File not found or you don't have permission",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
await confirmDirectUpload(input.fileId, input.uploadSuccess, input.errorMessage);
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
message: input.uploadSuccess
|
|
109
|
+
? "Upload confirmed successfully"
|
|
110
|
+
: "Upload failed",
|
|
111
|
+
};
|
|
112
|
+
}),
|
|
113
|
+
createFromUploadedPdf: protectedTeacherProcedure
|
|
114
|
+
.input(z.object({ classId: z.string(), fileId: z.string() }))
|
|
115
|
+
.mutation(({ ctx, input }) => createWorksheetFromUploadedPdf(input.classId, input.fileId, ctx.user.id)),
|
|
34
116
|
addQuestion: protectedProcedure
|
|
35
117
|
.input(z.object({
|
|
36
118
|
worksheetId: z.string(),
|
|
@@ -48,7 +130,7 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
48
130
|
"ESSAY",
|
|
49
131
|
]),
|
|
50
132
|
}))
|
|
51
|
-
.mutation(({ input }) => addQuestionToWorksheet(input.worksheetId, {
|
|
133
|
+
.mutation(({ ctx, input }) => addQuestionToWorksheet(input.worksheetId, ctx.user.id, {
|
|
52
134
|
question: input.question,
|
|
53
135
|
answer: input.answer,
|
|
54
136
|
points: input.points,
|
|
@@ -63,7 +145,7 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
63
145
|
position: z.enum(["before", "after"]),
|
|
64
146
|
targetId: z.string(),
|
|
65
147
|
}))
|
|
66
|
-
.mutation(({ input }) => reorderWorksheetQuestions(input.worksheetId, input.movedId, input.position, input.targetId)),
|
|
148
|
+
.mutation(({ ctx, input }) => reorderWorksheetQuestions(input.worksheetId, ctx.user.id, input.movedId, input.position, input.targetId)),
|
|
67
149
|
updateQuestion: protectedProcedure
|
|
68
150
|
.input(z.object({
|
|
69
151
|
worksheetId: z.string(),
|
|
@@ -84,7 +166,7 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
84
166
|
])
|
|
85
167
|
.optional(),
|
|
86
168
|
}))
|
|
87
|
-
.mutation(({ input }) => updateWorksheetQuestionRecord(input.worksheetId, input.questionId, {
|
|
169
|
+
.mutation(({ ctx, input }) => updateWorksheetQuestionRecord(input.worksheetId, input.questionId, ctx.user.id, {
|
|
88
170
|
question: input.question,
|
|
89
171
|
answer: input.answer,
|
|
90
172
|
points: input.points,
|
|
@@ -97,13 +179,13 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
97
179
|
worksheetId: z.string(),
|
|
98
180
|
questionId: z.string(),
|
|
99
181
|
}))
|
|
100
|
-
.mutation(({ input }) => deleteWorksheetQuestionRecord(input.worksheetId, input.questionId)),
|
|
182
|
+
.mutation(({ ctx, input }) => deleteWorksheetQuestionRecord(input.worksheetId, input.questionId, ctx.user.id)),
|
|
101
183
|
getWorksheetSubmission: protectedProcedure
|
|
102
184
|
.input(z.object({
|
|
103
185
|
worksheetId: z.string(),
|
|
104
186
|
submissionId: z.string(),
|
|
105
187
|
}))
|
|
106
|
-
.query(({ input }) => getWorksheetSubmission(input.worksheetId, input.submissionId)),
|
|
188
|
+
.query(({ ctx, input }) => getWorksheetSubmission(input.worksheetId, input.submissionId, ctx.user.id)),
|
|
107
189
|
answerQuestion: protectedProcedure
|
|
108
190
|
.input(z.object({
|
|
109
191
|
worksheetResponseId: z.string(),
|
|
@@ -116,13 +198,13 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
116
198
|
worksheetResponseId: z.string(),
|
|
117
199
|
progressId: z.string(),
|
|
118
200
|
}))
|
|
119
|
-
.mutation(({ input }) => cancelGrading(input.worksheetResponseId, input.progressId)),
|
|
201
|
+
.mutation(({ ctx, input }) => cancelGrading(input.worksheetResponseId, input.progressId, ctx.user.id)),
|
|
120
202
|
regradeQuestion: protectedProcedure
|
|
121
203
|
.input(z.object({
|
|
122
204
|
worksheetResponseId: z.string(),
|
|
123
205
|
progressId: z.string(),
|
|
124
206
|
}))
|
|
125
|
-
.mutation(({ input }) => regradeQuestion(input.worksheetResponseId, input.progressId)),
|
|
207
|
+
.mutation(({ ctx, input }) => regradeQuestion(input.worksheetResponseId, input.progressId, ctx.user.id)),
|
|
126
208
|
gradeAnswer: protectedProcedure
|
|
127
209
|
.input(z.object({
|
|
128
210
|
questionId: z.string(),
|
|
@@ -134,7 +216,7 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
134
216
|
markschemeState: z.any().optional(),
|
|
135
217
|
points: z.number().optional(),
|
|
136
218
|
}))
|
|
137
|
-
.mutation(({ input }) => gradeAnswer(input.questionId, input.studentWorksheetResponseId, {
|
|
219
|
+
.mutation(({ ctx, input }) => gradeAnswer(input.questionId, input.studentWorksheetResponseId, ctx.user.id, {
|
|
138
220
|
responseId: input.responseId,
|
|
139
221
|
response: input.response,
|
|
140
222
|
isCorrect: input.isCorrect,
|
|
@@ -148,6 +230,33 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
148
230
|
comment: z.string(),
|
|
149
231
|
}))
|
|
150
232
|
.mutation(({ ctx, input }) => addCommentToResponse(input.responseId, input.comment, ctx.user.id)),
|
|
233
|
+
updateUploadProgress: protectedProcedure
|
|
234
|
+
.input(updateUploadProgressSchema)
|
|
235
|
+
.mutation(async ({ ctx, input }) => {
|
|
236
|
+
if (!ctx.user) {
|
|
237
|
+
throw new TRPCError({
|
|
238
|
+
code: "UNAUTHORIZED",
|
|
239
|
+
message: "You must be logged in",
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
const file = await prisma.file.findFirst({
|
|
243
|
+
where: {
|
|
244
|
+
id: input.fileId,
|
|
245
|
+
userId: ctx.user.id,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
if (!file) {
|
|
249
|
+
throw new TRPCError({
|
|
250
|
+
code: "NOT_FOUND",
|
|
251
|
+
message: "File not found or you don't have permission",
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
await updateUploadProgress(input.fileId, input.progress);
|
|
255
|
+
return {
|
|
256
|
+
success: true,
|
|
257
|
+
progress: input.progress,
|
|
258
|
+
};
|
|
259
|
+
}),
|
|
151
260
|
});
|
|
152
261
|
//# sourceMappingURL=worksheet.js.map
|
|
153
|
-
//# debugId=
|
|
262
|
+
//# debugId=31932b12-1093-5e0f-a21c-e9301dcb8c25
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedProcedure,\n} from \"../trpc.js\";\nimport { z } from \"zod\";\nimport {\n getWorksheet,\n worksheetExists,\n listWorksheets,\n updateWorksheetRecord,\n deleteWorksheetRecord,\n createWorksheetRecord,\n addQuestionToWorksheet,\n reorderWorksheetQuestions,\n updateWorksheetQuestionRecord,\n deleteWorksheetQuestionRecord,\n getWorksheetSubmission,\n answerWorksheetQuestion,\n cancelGrading,\n regradeQuestion,\n gradeAnswer,\n addCommentToResponse,\n} from \"../services/worksheet.js\";\n\nexport const worksheetRouter = createTRPCRouter({\n getWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .query(({ input }) => getWorksheet(input.worksheetId)),\n\n exists: protectedClassMemberProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n return worksheetExists(input.id);\n }),\n\n listWorksheets: protectedProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ input }) => listWorksheets(input.classId)),\n\n updateWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string(), name: z.string().optional() }))\n .mutation(({ input }) =>\n updateWorksheetRecord(input.worksheetId, { name: input.name })\n ),\n\n deleteWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .mutation(({ input }) => deleteWorksheetRecord(input.worksheetId)),\n\n create: protectedProcedure\n .input(z.object({ classId: z.string(), name: z.string() }))\n .mutation(({ input }) =>\n createWorksheetRecord(input.classId, input.name)\n ),\n\n addQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z.enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ]),\n })\n )\n .mutation(({ input }) =>\n addQuestionToWorksheet(input.worksheetId, {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n })\n ),\n\n reorderQuestions: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum([\"before\", \"after\"]),\n targetId: z.string(),\n })\n )\n .mutation(({ input }) =>\n reorderWorksheetQuestions(\n input.worksheetId,\n input.movedId,\n input.position,\n input.targetId\n )\n ),\n\n updateQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z\n .enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ])\n .optional(),\n })\n )\n .mutation(({ input }) =>\n updateWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n }\n )\n ),\n\n deleteQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n })\n )\n .mutation(({ input }) =>\n deleteWorksheetQuestionRecord(input.worksheetId, input.questionId)\n ),\n\n getWorksheetSubmission: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n })\n )\n .query(({ input }) =>\n getWorksheetSubmission(input.worksheetId, input.submissionId)\n ),\n\n answerQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n answerWorksheetQuestion(\n input.worksheetResponseId,\n input.questionId,\n input.response,\n ctx.user!.id\n )\n ),\n\n cancelGrading: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ input }) =>\n cancelGrading(input.worksheetResponseId, input.progressId)\n ),\n\n regradeQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ input }) =>\n regradeQuestion(input.worksheetResponseId, input.progressId)\n ),\n\n gradeAnswer: protectedProcedure\n .input(\n z.object({\n questionId: z.string(),\n responseId: z.string().optional(),\n studentWorksheetResponseId: z.string(),\n response: z.string().optional(),\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n })\n )\n .mutation(({ input }) =>\n gradeAnswer(\n input.questionId,\n input.studentWorksheetResponseId,\n {\n responseId: input.responseId,\n response: input.response,\n isCorrect: input.isCorrect,\n feedback: input.feedback,\n markschemeState: input.markschemeState,\n points: input.points,\n }\n )\n ),\n\n addComment: protectedProcedure\n .input(\n z.object({\n responseId: z.string(),\n comment: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n addCommentToResponse(\n input.responseId,\n input.comment,\n ctx.user!.id\n )\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"bb1aa1a6-e249-5dff-bc42-ce1e6f79f915"}
|
|
1
|
+
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport {\n confirmDirectUpload,\n createDirectUploadFiles,\n updateUploadProgress,\n} from \"../lib/fileUpload.js\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport { z } from \"zod\";\nimport {\n getWorksheet,\n worksheetExists,\n listWorksheets,\n updateWorksheetRecord,\n deleteWorksheetRecord,\n createWorksheetRecord,\n createWorksheetFromPdf,\n createWorksheetFromUploadedPdf,\n addQuestionToWorksheet,\n reorderWorksheetQuestions,\n updateWorksheetQuestionRecord,\n deleteWorksheetQuestionRecord,\n getWorksheetSubmission,\n answerWorksheetQuestion,\n cancelGrading,\n regradeQuestion,\n gradeAnswer,\n addCommentToResponse,\n} from \"../services/worksheet.js\";\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\nconst pdfFileSchema = directFileSchema.superRefine((file, ctx) => {\n const isPdf =\n file.type === \"application/pdf\" && file.name.toLowerCase().endsWith(\".pdf\");\n if (!isPdf) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Only PDF files are supported\",\n });\n }\n});\n\nconst getWorksheetUploadUrlsSchema = z.object({\n classId: z.string(),\n files: z.array(pdfFileSchema),\n});\n\nconst confirmWorksheetUploadSchema = z.object({\n classId: z.string(),\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n errorMessage: z.string().optional(),\n});\n\nconst updateUploadProgressSchema = z.object({\n fileId: z.string(),\n progress: z.number().min(0).max(100),\n});\n\nexport const worksheetRouter = createTRPCRouter({\n getWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .query(({ ctx, input }) => getWorksheet(input.worksheetId, ctx.user!.id)),\n\n exists: protectedClassMemberProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n return worksheetExists(input.id);\n }),\n\n listWorksheets: protectedClassMemberProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ input }) => listWorksheets(input.classId)),\n\n updateWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string(), name: z.string().optional() }))\n .mutation(({ ctx, input }) =>\n updateWorksheetRecord(input.worksheetId, ctx.user!.id, {\n name: input.name,\n })\n ),\n\n deleteWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .mutation(({ ctx, input }) =>\n deleteWorksheetRecord(input.worksheetId, ctx.user!.id)\n ),\n\n create: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), name: z.string() }))\n .mutation(({ input }) =>\n createWorksheetRecord(input.classId, input.name)\n ),\n\n createFromPdf: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), url: z.string().url() }))\n .mutation(({ input }) => createWorksheetFromPdf(input.classId, input.url)),\n\n getWorksheetUploadUrls: protectedTeacherProcedure\n .input(getWorksheetUploadUrlsSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in to upload files\",\n });\n }\n\n const uploadFiles = await createDirectUploadFiles(\n input.files,\n ctx.user.id\n );\n\n return {\n success: true,\n uploadFiles,\n };\n }),\n\n confirmWorksheetUpload: protectedTeacherProcedure\n .input(confirmWorksheetUploadSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in\",\n });\n }\n\n const file = await prisma.file.findFirst({\n where: {\n id: input.fileId,\n userId: ctx.user.id,\n },\n });\n\n if (!file) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"File not found or you don't have permission\",\n });\n }\n\n await confirmDirectUpload(\n input.fileId,\n input.uploadSuccess,\n input.errorMessage\n );\n\n return {\n success: true,\n message: input.uploadSuccess\n ? \"Upload confirmed successfully\"\n : \"Upload failed\",\n };\n }),\n\n createFromUploadedPdf: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), fileId: z.string() }))\n .mutation(({ ctx, input }) =>\n createWorksheetFromUploadedPdf(input.classId, input.fileId, ctx.user!.id)\n ),\n\n addQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z.enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ]),\n })\n )\n .mutation(({ ctx, input }) =>\n addQuestionToWorksheet(input.worksheetId, ctx.user!.id, {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n })\n ),\n\n reorderQuestions: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum([\"before\", \"after\"]),\n targetId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n reorderWorksheetQuestions(\n input.worksheetId,\n ctx.user!.id,\n input.movedId,\n input.position,\n input.targetId\n )\n ),\n\n updateQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z\n .enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ])\n .optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id,\n {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n }\n )\n ),\n\n deleteQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n deleteWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id\n )\n ),\n\n getWorksheetSubmission: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n })\n )\n .query(({ ctx, input }) =>\n getWorksheetSubmission(input.worksheetId, input.submissionId, ctx.user!.id)\n ),\n\n answerQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n answerWorksheetQuestion(\n input.worksheetResponseId,\n input.questionId,\n input.response,\n ctx.user!.id\n )\n ),\n\n cancelGrading: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n cancelGrading(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n regradeQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n regradeQuestion(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n gradeAnswer: protectedProcedure\n .input(\n z.object({\n questionId: z.string(),\n responseId: z.string().optional(),\n studentWorksheetResponseId: z.string(),\n response: z.string().optional(),\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n gradeAnswer(\n input.questionId,\n input.studentWorksheetResponseId,\n ctx.user!.id,\n {\n responseId: input.responseId,\n response: input.response,\n isCorrect: input.isCorrect,\n feedback: input.feedback,\n markschemeState: input.markschemeState,\n points: input.points,\n }\n )\n ),\n\n addComment: protectedProcedure\n .input(\n z.object({\n responseId: z.string(),\n comment: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n addCommentToResponse(\n input.responseId,\n input.comment,\n ctx.user!.id\n )\n ),\n\n updateUploadProgress: protectedProcedure\n .input(updateUploadProgressSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in\",\n });\n }\n\n const file = await prisma.file.findFirst({\n where: {\n id: input.fileId,\n userId: ctx.user.id,\n },\n });\n\n if (!file) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"File not found or you don't have permission\",\n });\n }\n\n await updateUploadProgress(input.fileId, input.progress);\n\n return {\n success: true,\n progress: input.progress,\n };\n }),\n});\n"],"names":[],"mappings":"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","debug_id":"31932b12-1093-5e0f-a21c-e9301dcb8c25"}
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare function register(input: {
|
|
|
9
9
|
username: string;
|
|
10
10
|
};
|
|
11
11
|
}>;
|
|
12
|
-
/** Authenticate user by username/password, create session
|
|
12
|
+
/** Authenticate user by username/password, create session. */
|
|
13
13
|
export declare function login(input: {
|
|
14
14
|
username: string;
|
|
15
15
|
password: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"AA6BA,qFAAqF;AACrF,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"AA6BA,qFAAqF;AACrF,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;GAqEA;AAED,8DAA8D;AAC9D,wBAAsB,KAAK,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;GAoCxE;AAED,iEAAiE;AACjE,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM;;GAG1C;AAED,0EAA0E;AAC1E,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;GASzC;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,MAAM;;GAiC1D;AAED,8EAA8E;AAC9E,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM;;GA+BzC;AAED,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM;;GA+BvD;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAuBlE"}
|
package/dist/services/auth.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Handles session creation, Redis caching, and email notifications.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
6
|
+
!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]="7c41f210-458c-593a-8fe2-a8ecbc675245")}catch(e){}}();
|
|
7
|
+
import { SessionType } from "@prisma/client";
|
|
7
8
|
import { TRPCError } from "@trpc/server";
|
|
8
9
|
import { v4 as uuidv4 } from "uuid";
|
|
9
10
|
import { compare, hash } from "bcryptjs";
|
|
@@ -11,8 +12,7 @@ import { sendMail } from "../utils/email.js";
|
|
|
11
12
|
import { prismaWrapper } from "../utils/prismaWrapper.js";
|
|
12
13
|
import { env } from "../lib/config/env.js";
|
|
13
14
|
import { logger } from "../utils/logger.js";
|
|
14
|
-
import { findUserByUsername, findUserByUsernameOrEmail, findUserByEmail, findUserById, createUser, createSession, deleteSessionsByUserId, deleteShortLivedSessionsByUserId, deleteUserById,
|
|
15
|
-
import { getRedis } from "../lib/redis.js";
|
|
15
|
+
import { findUserByUsername, findUserByUsernameOrEmail, findUserByEmail, findUserById, createUser, createSession, deleteSessionsByUserId, deleteShortLivedSessionsByUserId, deleteUserById, findSessionByIdAndType, findSessionByIdWithUserAndType, updateUserVerified, updateUserPassword, deleteSessionById, } from "../models/auth.js";
|
|
16
16
|
/** Register a new user, create verification session, and send verification email. */
|
|
17
17
|
export async function register(input) {
|
|
18
18
|
const { username, email, password } = input;
|
|
@@ -43,6 +43,7 @@ export async function register(input) {
|
|
|
43
43
|
}), "creating new user during registration");
|
|
44
44
|
const verificationToken = await prismaWrapper.create(() => createSession({
|
|
45
45
|
id: uuidv4(),
|
|
46
|
+
type: SessionType.EMAIL_VERIFICATION,
|
|
46
47
|
userId: user.id,
|
|
47
48
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
|
|
48
49
|
}), "creating verification token");
|
|
@@ -62,7 +63,7 @@ export async function register(input) {
|
|
|
62
63
|
}
|
|
63
64
|
return { user: { id: user.id, username: user.username } };
|
|
64
65
|
}
|
|
65
|
-
/** Authenticate user by username/password, create session
|
|
66
|
+
/** Authenticate user by username/password, create session. */
|
|
66
67
|
export async function login(input) {
|
|
67
68
|
const { username, password } = input;
|
|
68
69
|
const user = await findUserByUsername(username);
|
|
@@ -86,14 +87,10 @@ export async function login(input) {
|
|
|
86
87
|
}
|
|
87
88
|
const session = await createSession({
|
|
88
89
|
id: uuidv4(),
|
|
90
|
+
type: SessionType.AUTH,
|
|
89
91
|
userId: user.id,
|
|
90
92
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
|
|
91
93
|
});
|
|
92
|
-
const cachePayload = JSON.stringify({ id: user.id, username: user.username });
|
|
93
|
-
const ttlSeconds = 30 * 24 * 60 * 60; // 30 days, match session expiry
|
|
94
|
-
const r = getRedis();
|
|
95
|
-
if (r)
|
|
96
|
-
await r.setex(`session:${session.id}`, ttlSeconds, cachePayload);
|
|
97
94
|
return {
|
|
98
95
|
token: session.id,
|
|
99
96
|
user: { id: user.id, username: user.username },
|
|
@@ -127,6 +124,7 @@ export async function resendVerificationEmail(email) {
|
|
|
127
124
|
await deleteSessionsByUserId(user.id);
|
|
128
125
|
const verificationToken = await createSession({
|
|
129
126
|
id: uuidv4(),
|
|
127
|
+
type: SessionType.EMAIL_VERIFICATION,
|
|
130
128
|
userId: user.id,
|
|
131
129
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
|
|
132
130
|
});
|
|
@@ -148,7 +146,7 @@ export async function resendVerificationEmail(email) {
|
|
|
148
146
|
}
|
|
149
147
|
/** Verify email via token. Marks user as verified and deletes the session. */
|
|
150
148
|
export async function verify(token) {
|
|
151
|
-
const session = await
|
|
149
|
+
const session = await findSessionByIdAndType(token, SessionType.EMAIL_VERIFICATION);
|
|
152
150
|
if (!session) {
|
|
153
151
|
throw new TRPCError({
|
|
154
152
|
code: "NOT_FOUND",
|
|
@@ -156,11 +154,19 @@ export async function verify(token) {
|
|
|
156
154
|
});
|
|
157
155
|
}
|
|
158
156
|
if (session.expiresAt && session.expiresAt < new Date()) {
|
|
157
|
+
await deleteSessionById(token);
|
|
159
158
|
throw new TRPCError({
|
|
160
159
|
code: "UNAUTHORIZED",
|
|
161
160
|
message: "Session expired",
|
|
162
161
|
});
|
|
163
162
|
}
|
|
163
|
+
if (!session.userId) {
|
|
164
|
+
await deleteSessionById(token);
|
|
165
|
+
throw new TRPCError({
|
|
166
|
+
code: "BAD_REQUEST",
|
|
167
|
+
message: "Invalid session state",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
164
170
|
await updateUserVerified(session.userId, true);
|
|
165
171
|
await deleteSessionById(token);
|
|
166
172
|
return { success: true };
|
|
@@ -175,6 +181,7 @@ export async function requestPasswordReset(email) {
|
|
|
175
181
|
await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);
|
|
176
182
|
const resetToken = await createSession({
|
|
177
183
|
id: uuidv4(),
|
|
184
|
+
type: SessionType.PASSWORD_RESET,
|
|
178
185
|
userId: user.id,
|
|
179
186
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60),
|
|
180
187
|
});
|
|
@@ -196,7 +203,7 @@ export async function requestPasswordReset(email) {
|
|
|
196
203
|
}
|
|
197
204
|
/** Reset password using token from email. Validates token and updates password. */
|
|
198
205
|
export async function resetPassword(token, password) {
|
|
199
|
-
const session = await
|
|
206
|
+
const session = await findSessionByIdWithUserAndType(token, SessionType.PASSWORD_RESET);
|
|
200
207
|
if (!session || !session.userId) {
|
|
201
208
|
throw new TRPCError({
|
|
202
209
|
code: "NOT_FOUND",
|
|
@@ -215,4 +222,4 @@ export async function resetPassword(token, password) {
|
|
|
215
222
|
return { success: true };
|
|
216
223
|
}
|
|
217
224
|
//# sourceMappingURL=auth.js.map
|
|
218
|
-
//# debugId=
|
|
225
|
+
//# debugId=7c41f210-458c-593a-8fe2-a8ecbc675245
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionById,\n findSessionByIdWithUser,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\nimport { getRedis } from \"../lib/redis.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n}) {\n const { username, email, password } = input;\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: true,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session, and cache in Redis. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n const cachePayload = JSON.stringify({ id: user.id, username: user.username });\n const ttlSeconds = 30 * 24 * 60 * 60; // 30 days, match session expiry\n const r = getRedis();\n if (r) await r.setex(`session:${session.id}`, ttlSeconds, cachePayload);\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionById(token);\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n await updateUserVerified(session.userId!, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUser(token);\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"AAAA;;;GAGG;;;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,UAAU,EACV,aAAa,EACb,sBAAsB,EACtB,gCAAgC,EAChC,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAI9B;IACC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAE5C,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,SAAS,CAChD,GAAG,EAAE,CAAC,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAChD,gDAAgD,CACjD,CAAC;IAEF,IAAI,YAAY,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC1C,IAAI,YAAY,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,SAAS,CAAC;gBAClB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,yBAAyB;aACnC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CAAC;gBAClB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,sBAAsB;aAChC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;SAAM,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAClD,MAAM,aAAa,CAAC,UAAU,CAC5B,GAAG,EAAE,CAAC,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC,EAC7C,gDAAgD,CACjD,CAAC;QACF,MAAM,aAAa,CAAC,MAAM,CACxB,GAAG,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC,EACrC,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,MAAM,CACrC,KAAK,IAAI,EAAE,CACT,UAAU,CAAC;QACT,QAAQ;QACR,KAAK;QACL,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QAClC,QAAQ,EAAE,IAAI;KACf,CAAC,EACJ,uCAAuC,CACxC,CAAC;IAEF,MAAM,iBAAiB,GAAG,MAAM,aAAa,CAAC,MAAM,CAClD,GAAG,EAAE,CACH,aAAa,CAAC;QACZ,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAC,EACJ,6BAA6B,CAC9B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC;YACb,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,IAAI,CAAC,KAAK;YACd,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE,wCAAwC,GAAG,CAAC,mBAAmB,WAAW,iBAAiB,CAAC,EAAE,EAAE;SACvG,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;YAChD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5D,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,KAA6C;IACvE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAErC,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,8BAA8B;SACxC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,8BAA8B;SACxC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC;QAClC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,gCAAgC;IACtE,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,IAAI,CAAC;QAAE,MAAM,CAAC,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAExE,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,EAAE;QACjB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;KAC/C,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc;IACzC,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,MAAc;IACxC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,gBAAgB;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAAa;IACzD,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,gBAAgB;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEtC,MAAM,iBAAiB,GAAG,MAAM,aAAa,CAAC;QAC5C,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC;YACb,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,IAAI,CAAC,KAAK;YACd,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE,wCAAwC,GAAG,CAAC,mBAAmB,WAAW,iBAAiB,CAAC,EAAE,EAAE;SACvG,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;YAChD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAa;IACxC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,mBAAmB;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,kBAAkB,CAAC,OAAO,CAAC,MAAO,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAa;IACtD,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,gCAAgC,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;IAEjE,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC;QACrC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;KACjD,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC;YACb,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,IAAI,CAAC,KAAK;YACd,OAAO,EAAE,qBAAqB;YAC9B,IAAI,EAAE,0CAA0C,GAAG,CAAC,mBAAmB,mBAAmB,UAAU,CAAC,EAAE,EAAE;SAC1G,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,QAAgB;IACjE,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,gCAAgC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QACxD,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,yBAAyB;SACnC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC","debug_id":"18f3fceb-a95b-5d3c-b80c-c8f5a01da04e"}
|
|
1
|
+
{"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionByIdAndType,\n findSessionByIdWithUserAndType,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n}) {\n const { username, email, password } = input;\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: true,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n type: SessionType.AUTH,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionByIdAndType(\n token,\n SessionType.EMAIL_VERIFICATION\n );\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n if (!session.userId) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid session state\",\n });\n }\n\n await updateUserVerified(session.userId, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n type: SessionType.PASSWORD_RESET,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUserAndType(\n token,\n SessionType.PASSWORD_RESET\n );\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"7c41f210-458c-593a-8fe2-a8ecbc675245"}
|
package/dist/services/class.d.ts
CHANGED
|
@@ -615,8 +615,8 @@ export declare function exportClass(classId: string, userId: string): Promise<{
|
|
|
615
615
|
id: string;
|
|
616
616
|
classId: string;
|
|
617
617
|
questions: {
|
|
618
|
-
options: import("@prisma/client/runtime/library.js").JsonValue;
|
|
619
618
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
619
|
+
options: import("@prisma/client/runtime/library.js").JsonValue;
|
|
620
620
|
order: number | null;
|
|
621
621
|
points: number;
|
|
622
622
|
worksheetId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
|
package/dist/services/class.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* syllabus, lab drafts, and invite codes.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
6
|
+
!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]="b0980742-2fbe-5c12-897f-ba5bf6ed98c4")}catch(e){}}();
|
|
7
|
+
import { SessionType } from "@prisma/client";
|
|
7
8
|
import { TRPCError } from "@trpc/server";
|
|
8
9
|
import { prisma } from "../lib/prisma.js";
|
|
9
10
|
import { generateInviteCode } from "../utils/generateInviteCode.js";
|
|
@@ -214,6 +215,7 @@ export async function getInviteCode(classId) {
|
|
|
214
215
|
data: {
|
|
215
216
|
id: generateInviteCode(),
|
|
216
217
|
classId,
|
|
218
|
+
type: SessionType.CLASS_INVITE,
|
|
217
219
|
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
218
220
|
},
|
|
219
221
|
});
|
|
@@ -223,12 +225,13 @@ export async function getInviteCode(classId) {
|
|
|
223
225
|
}
|
|
224
226
|
export async function createInviteCode(classId) {
|
|
225
227
|
await prisma.session.deleteMany({
|
|
226
|
-
where: { classId },
|
|
228
|
+
where: { classId, type: SessionType.CLASS_INVITE },
|
|
227
229
|
});
|
|
228
230
|
const session = await prisma.session.create({
|
|
229
231
|
data: {
|
|
230
232
|
id: generateInviteCode(),
|
|
231
233
|
classId,
|
|
234
|
+
type: SessionType.CLASS_INVITE,
|
|
232
235
|
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
233
236
|
},
|
|
234
237
|
});
|
|
@@ -483,4 +486,4 @@ export async function importClass(classId, userId, year, classData) {
|
|
|
483
486
|
}
|
|
484
487
|
}
|
|
485
488
|
//# sourceMappingURL=class.js.map
|
|
486
|
-
//# debugId=
|
|
489
|
+
//# debugId=b0980742-2fbe-5c12-897f-ba5bf6ed98c4
|