@studious-lms/server 1.0.6 → 1.0.8

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.
Files changed (115) hide show
  1. package/API_SPECIFICATION.md +1461 -0
  2. package/dist/exportType.d.ts +3 -3
  3. package/dist/exportType.d.ts.map +1 -1
  4. package/dist/exportType.js +1 -2
  5. package/dist/index.js +25 -30
  6. package/dist/lib/fileUpload.d.ts.map +1 -1
  7. package/dist/lib/fileUpload.js +31 -29
  8. package/dist/lib/googleCloudStorage.js +9 -14
  9. package/dist/lib/prisma.js +4 -7
  10. package/dist/lib/thumbnailGenerator.js +12 -20
  11. package/dist/middleware/auth.d.ts.map +1 -1
  12. package/dist/middleware/auth.js +17 -22
  13. package/dist/middleware/logging.js +5 -9
  14. package/dist/routers/_app.d.ts +3619 -1937
  15. package/dist/routers/_app.d.ts.map +1 -1
  16. package/dist/routers/_app.js +28 -27
  17. package/dist/routers/agenda.d.ts +14 -9
  18. package/dist/routers/agenda.d.ts.map +1 -1
  19. package/dist/routers/agenda.js +14 -17
  20. package/dist/routers/announcement.d.ts +5 -4
  21. package/dist/routers/announcement.d.ts.map +1 -1
  22. package/dist/routers/announcement.js +28 -31
  23. package/dist/routers/assignment.d.ts +283 -197
  24. package/dist/routers/assignment.d.ts.map +1 -1
  25. package/dist/routers/assignment.js +256 -202
  26. package/dist/routers/attendance.d.ts +6 -5
  27. package/dist/routers/attendance.d.ts.map +1 -1
  28. package/dist/routers/attendance.js +31 -34
  29. package/dist/routers/auth.d.ts +2 -1
  30. package/dist/routers/auth.d.ts.map +1 -1
  31. package/dist/routers/auth.js +80 -75
  32. package/dist/routers/class.d.ts +285 -15
  33. package/dist/routers/class.d.ts.map +1 -1
  34. package/dist/routers/class.js +440 -164
  35. package/dist/routers/event.d.ts +48 -39
  36. package/dist/routers/event.d.ts.map +1 -1
  37. package/dist/routers/event.js +76 -79
  38. package/dist/routers/file.d.ts +72 -2
  39. package/dist/routers/file.d.ts.map +1 -1
  40. package/dist/routers/file.js +260 -32
  41. package/dist/routers/folder.d.ts +296 -0
  42. package/dist/routers/folder.d.ts.map +1 -0
  43. package/dist/routers/folder.js +693 -0
  44. package/dist/routers/notifications.d.ts +103 -0
  45. package/dist/routers/notifications.d.ts.map +1 -0
  46. package/dist/routers/notifications.js +91 -0
  47. package/dist/routers/school.d.ts +208 -0
  48. package/dist/routers/school.d.ts.map +1 -0
  49. package/dist/routers/school.js +481 -0
  50. package/dist/routers/section.d.ts +2 -1
  51. package/dist/routers/section.d.ts.map +1 -1
  52. package/dist/routers/section.js +30 -33
  53. package/dist/routers/user.d.ts +3 -2
  54. package/dist/routers/user.d.ts.map +1 -1
  55. package/dist/routers/user.js +21 -24
  56. package/dist/seedDatabase.d.ts +22 -0
  57. package/dist/seedDatabase.d.ts.map +1 -0
  58. package/dist/seedDatabase.js +75 -0
  59. package/dist/socket/handlers.js +26 -30
  60. package/dist/trpc.d.ts +5 -0
  61. package/dist/trpc.d.ts.map +1 -1
  62. package/dist/trpc.js +35 -26
  63. package/dist/types/trpc.d.ts +1 -1
  64. package/dist/types/trpc.d.ts.map +1 -1
  65. package/dist/types/trpc.js +1 -2
  66. package/dist/utils/email.js +2 -8
  67. package/dist/utils/generateInviteCode.js +1 -5
  68. package/dist/utils/logger.d.ts.map +1 -1
  69. package/dist/utils/logger.js +13 -9
  70. package/dist/utils/prismaErrorHandler.d.ts +9 -0
  71. package/dist/utils/prismaErrorHandler.d.ts.map +1 -0
  72. package/dist/utils/prismaErrorHandler.js +234 -0
  73. package/dist/utils/prismaWrapper.d.ts +14 -0
  74. package/dist/utils/prismaWrapper.d.ts.map +1 -0
  75. package/dist/utils/prismaWrapper.js +64 -0
  76. package/package.json +12 -4
  77. package/prisma/migrations/20250807062924_init/migration.sql +436 -0
  78. package/prisma/migrations/migration_lock.toml +3 -0
  79. package/prisma/schema.prisma +68 -1
  80. package/src/exportType.ts +3 -3
  81. package/src/index.ts +6 -6
  82. package/src/lib/fileUpload.ts +19 -10
  83. package/src/lib/thumbnailGenerator.ts +2 -2
  84. package/src/middleware/auth.ts +2 -4
  85. package/src/middleware/logging.ts +2 -2
  86. package/src/routers/_app.ts +17 -13
  87. package/src/routers/agenda.ts +2 -2
  88. package/src/routers/announcement.ts +2 -2
  89. package/src/routers/assignment.ts +86 -26
  90. package/src/routers/attendance.ts +2 -2
  91. package/src/routers/auth.ts +83 -57
  92. package/src/routers/class.ts +339 -39
  93. package/src/routers/event.ts +2 -2
  94. package/src/routers/file.ts +276 -21
  95. package/src/routers/folder.ts +755 -0
  96. package/src/routers/notifications.ts +93 -0
  97. package/src/routers/section.ts +2 -2
  98. package/src/routers/user.ts +3 -3
  99. package/src/seedDatabase.ts +88 -0
  100. package/src/socket/handlers.ts +5 -5
  101. package/src/trpc.ts +17 -4
  102. package/src/types/trpc.ts +1 -1
  103. package/src/utils/logger.ts +14 -4
  104. package/src/utils/prismaErrorHandler.ts +275 -0
  105. package/src/utils/prismaWrapper.ts +91 -0
  106. package/tests/auth.test.ts +25 -0
  107. package/tests/class.test.ts +281 -0
  108. package/tests/setup.ts +98 -0
  109. package/tests/startup.test.ts +5 -0
  110. package/tsconfig.json +2 -1
  111. package/vitest.config.ts +11 -0
  112. package/dist/logger.d.ts +0 -26
  113. package/dist/logger.d.ts.map +0 -1
  114. package/dist/logger.js +0 -135
  115. package/src/logger.ts +0 -163
@@ -1,10 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const attendanceRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
8
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
9
10
  httpStatus: number;
10
11
  path?: string;
@@ -25,9 +26,9 @@ export declare const attendanceRouter: import("@trpc/server").TRPCBuiltRouter<{
25
26
  id: string;
26
27
  name: string | null;
27
28
  color: string | null;
29
+ location: string | null;
28
30
  startTime: Date;
29
31
  endTime: Date;
30
- location: string | null;
31
32
  } | null;
32
33
  late: {
33
34
  id: string;
@@ -44,8 +45,8 @@ export declare const attendanceRouter: import("@trpc/server").TRPCBuiltRouter<{
44
45
  } & {
45
46
  id: string;
46
47
  classId: string;
47
- date: Date;
48
48
  eventId: string | null;
49
+ date: Date;
49
50
  })[];
50
51
  meta: object;
51
52
  }>;
@@ -73,9 +74,9 @@ export declare const attendanceRouter: import("@trpc/server").TRPCBuiltRouter<{
73
74
  event: {
74
75
  id: string;
75
76
  name: string | null;
77
+ location: string | null;
76
78
  startTime: Date;
77
79
  endTime: Date;
78
- location: string | null;
79
80
  } | null;
80
81
  late: {
81
82
  id: string;
@@ -92,8 +93,8 @@ export declare const attendanceRouter: import("@trpc/server").TRPCBuiltRouter<{
92
93
  } & {
93
94
  id: string;
94
95
  classId: string;
95
- date: Date;
96
96
  eventId: string | null;
97
+ date: Date;
97
98
  };
98
99
  meta: object;
99
100
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../src/routers/attendance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+Q3B,CAAC"}
1
+ {"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../src/routers/attendance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+Q3B,CAAC"}
@@ -1,31 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.attendanceRouter = void 0;
4
- const zod_1 = require("zod");
5
- const trpc_1 = require("../trpc");
6
- const server_1 = require("@trpc/server");
7
- const prisma_1 = require("../lib/prisma");
8
- const attendanceSchema = zod_1.z.object({
9
- eventId: zod_1.z.string().optional(),
10
- present: zod_1.z.array(zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string() })),
11
- late: zod_1.z.array(zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string() })),
12
- absent: zod_1.z.array(zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string() })),
1
+ import { z } from "zod";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
+ import { TRPCError } from "@trpc/server";
4
+ import { prisma } from "../lib/prisma.js";
5
+ const attendanceSchema = z.object({
6
+ eventId: z.string().optional(),
7
+ present: z.array(z.object({ id: z.string(), username: z.string() })),
8
+ late: z.array(z.object({ id: z.string(), username: z.string() })),
9
+ absent: z.array(z.object({ id: z.string(), username: z.string() })),
13
10
  });
14
- exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
15
- get: trpc_1.protectedProcedure
16
- .input(zod_1.z.object({
17
- classId: zod_1.z.string(),
18
- eventId: zod_1.z.string().optional(),
11
+ export const attendanceRouter = createTRPCRouter({
12
+ get: protectedProcedure
13
+ .input(z.object({
14
+ classId: z.string(),
15
+ eventId: z.string().optional(),
19
16
  }))
20
17
  .query(async ({ ctx, input }) => {
21
18
  if (!ctx.user) {
22
- throw new server_1.TRPCError({
19
+ throw new TRPCError({
23
20
  code: "UNAUTHORIZED",
24
21
  message: "You must be logged in to view attendance",
25
22
  });
26
23
  }
27
24
  // Check if user is a teacher or student of the class
28
- const classData = await prisma_1.prisma.class.findUnique({
25
+ const classData = await prisma.class.findUnique({
29
26
  where: {
30
27
  id: input.classId,
31
28
  OR: [
@@ -54,25 +51,25 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
54
51
  },
55
52
  });
56
53
  if (!classData) {
57
- throw new server_1.TRPCError({
54
+ throw new TRPCError({
58
55
  code: "UNAUTHORIZED",
59
56
  message: "You are not authorized to view this class's attendance",
60
57
  });
61
58
  }
62
59
  // check each event has an attendance, if not create one
63
- const events = await prisma_1.prisma.event.findMany({
60
+ const events = await prisma.event.findMany({
64
61
  where: {
65
62
  classId: input.classId,
66
63
  },
67
64
  });
68
65
  for (const event of events) {
69
- const attendance = await prisma_1.prisma.attendance.findFirst({
66
+ const attendance = await prisma.attendance.findFirst({
70
67
  where: {
71
68
  eventId: event.id,
72
69
  },
73
70
  });
74
71
  if (!attendance) {
75
- await prisma_1.prisma.attendance.create({
72
+ await prisma.attendance.create({
76
73
  data: {
77
74
  event: {
78
75
  connect: {
@@ -91,7 +88,7 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
91
88
  });
92
89
  }
93
90
  }
94
- const attendance = await prisma_1.prisma.attendance.findMany({
91
+ const attendance = await prisma.attendance.findMany({
95
92
  where: {
96
93
  classId: input.classId,
97
94
  ...(input.eventId ? { eventId: input.eventId } : {}),
@@ -132,21 +129,21 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
132
129
  });
133
130
  return attendance;
134
131
  }),
135
- update: trpc_1.protectedProcedure
136
- .input(zod_1.z.object({
137
- classId: zod_1.z.string(),
138
- eventId: zod_1.z.string().optional(),
132
+ update: protectedProcedure
133
+ .input(z.object({
134
+ classId: z.string(),
135
+ eventId: z.string().optional(),
139
136
  attendance: attendanceSchema,
140
137
  }))
141
138
  .mutation(async ({ ctx, input }) => {
142
139
  if (!ctx.user) {
143
- throw new server_1.TRPCError({
140
+ throw new TRPCError({
144
141
  code: "UNAUTHORIZED",
145
142
  message: "You must be logged in to update attendance",
146
143
  });
147
144
  }
148
145
  // Check if user is a teacher of the class
149
- const classData = await prisma_1.prisma.class.findUnique({
146
+ const classData = await prisma.class.findUnique({
150
147
  where: {
151
148
  id: input.classId,
152
149
  teachers: {
@@ -157,13 +154,13 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
157
154
  },
158
155
  });
159
156
  if (!classData) {
160
- throw new server_1.TRPCError({
157
+ throw new TRPCError({
161
158
  code: "UNAUTHORIZED",
162
159
  message: "You are not authorized to update this class's attendance",
163
160
  });
164
161
  }
165
162
  // Check if attendance record exists
166
- const existingAttendance = await prisma_1.prisma.attendance.findFirst({
163
+ const existingAttendance = await prisma.attendance.findFirst({
167
164
  where: {
168
165
  classId: input.classId,
169
166
  eventId: input.eventId,
@@ -171,7 +168,7 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
171
168
  });
172
169
  if (!existingAttendance) {
173
170
  // Create new attendance record
174
- const attendance = await prisma_1.prisma.attendance.create({
171
+ const attendance = await prisma.attendance.create({
175
172
  data: {
176
173
  classId: input.classId,
177
174
  eventId: input.eventId,
@@ -219,7 +216,7 @@ exports.attendanceRouter = (0, trpc_1.createTRPCRouter)({
219
216
  return attendance;
220
217
  }
221
218
  // Update existing attendance record
222
- const attendance = await prisma_1.prisma.attendance.update({
219
+ const attendance = await prisma.attendance.update({
223
220
  where: {
224
221
  id: existingAttendance.id,
225
222
  },
@@ -1,10 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const authRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
8
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
9
10
  httpStatus: number;
10
11
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routers/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsQrB,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routers/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwBxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+RrB,CAAC"}
@@ -1,33 +1,30 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.authRouter = void 0;
4
- const zod_1 = require("zod");
5
- const trpc_1 = require("../trpc");
6
- const server_1 = require("@trpc/server");
7
- const prisma_1 = require("../lib/prisma");
8
- const uuid_1 = require("uuid");
9
- const bcryptjs_1 = require("bcryptjs");
10
- const email_1 = require("../utils/email");
11
- const loginSchema = zod_1.z.object({
12
- username: zod_1.z.string(),
13
- password: zod_1.z.string(),
1
+ import { z } from "zod";
2
+ import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc.js";
3
+ import { TRPCError } from "@trpc/server";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ import { compare, hash } from "bcryptjs";
7
+ import { prismaWrapper } from "../utils/prismaWrapper.js";
8
+ const loginSchema = z.object({
9
+ username: z.string(),
10
+ password: z.string(),
14
11
  });
15
- const registerSchema = zod_1.z.object({
16
- username: zod_1.z.string().min(3, "Username must be at least 3 characters"),
17
- email: zod_1.z.string().email("Invalid email address"),
18
- password: zod_1.z.string().min(6, "Password must be at least 6 characters"),
19
- confirmPassword: zod_1.z.string(),
12
+ const registerSchema = z.object({
13
+ username: z.string().min(3, "Username must be at least 3 characters"),
14
+ email: z.string().email("Invalid email address"),
15
+ password: z.string().min(6, "Password must be at least 6 characters"),
16
+ confirmPassword: z.string(),
20
17
  }).refine((data) => data.password === data.confirmPassword, {
21
18
  message: "Passwords don't match",
22
19
  path: ["confirmPassword"],
23
20
  });
24
- exports.authRouter = (0, trpc_1.createTRPCRouter)({
25
- register: trpc_1.publicProcedure
21
+ export const authRouter = createTRPCRouter({
22
+ register: publicProcedure
26
23
  .input(registerSchema)
27
24
  .mutation(async ({ input }) => {
28
25
  const { username, email, password } = input;
29
26
  // Check if username already exists
30
- const existingUser = await prisma_1.prisma.user.findFirst({
27
+ const existingUser = await prismaWrapper.findFirst(() => prisma.user.findFirst({
31
28
  where: {
32
29
  OR: [
33
30
  { username },
@@ -40,56 +37,58 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
40
37
  email: true,
41
38
  verified: true,
42
39
  }
43
- });
40
+ }), 'checking for existing user during registration');
44
41
  if (existingUser && existingUser.verified) {
45
42
  if (existingUser.username === username) {
46
- throw new server_1.TRPCError({
43
+ throw new TRPCError({
47
44
  code: "CONFLICT",
48
45
  message: "Username already exists",
49
46
  });
50
47
  }
51
48
  if (existingUser.email === email) {
52
- throw new server_1.TRPCError({
49
+ throw new TRPCError({
53
50
  code: "CONFLICT",
54
51
  message: "Email already exists",
55
52
  });
56
53
  }
57
54
  }
58
55
  else if (existingUser && !existingUser.verified) {
59
- await prisma_1.prisma.session.deleteMany({
56
+ await prismaWrapper.deleteMany(() => prisma.session.deleteMany({
60
57
  where: { userId: existingUser.id },
61
- });
62
- await prisma_1.prisma.user.delete({
58
+ }), 'deleting existing sessions for unverified user');
59
+ await prismaWrapper.delete(() => prisma.user.delete({
63
60
  where: { id: existingUser.id },
64
- });
61
+ }), 'deleting unverified user');
65
62
  }
66
63
  // Create new user
67
- const user = await prisma_1.prisma.user.create({
64
+ const user = await prismaWrapper.create(async () => await prisma.user.create({
68
65
  data: {
69
66
  username,
70
67
  email,
71
- password: await (0, bcryptjs_1.hash)(password, 10),
68
+ password: await hash(password, 10),
72
69
  profile: {},
70
+ verified: true, // temporary
73
71
  },
74
72
  select: {
75
73
  id: true,
76
74
  username: true,
77
75
  email: true,
78
76
  }
79
- });
80
- const verificationToken = await prisma_1.prisma.session.create({
77
+ }), 'creating new user during registration');
78
+ const verificationToken = await prismaWrapper.create(() => prisma.session.create({
81
79
  data: {
82
- id: (0, uuid_1.v4)(),
80
+ id: uuidv4(),
83
81
  userId: user.id,
84
82
  expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
85
83
  },
86
- });
87
- await email_1.transport.sendMail({
88
- from: 'noreply@studious.sh',
89
- to: user.email,
90
- subject: 'Verify your email',
91
- text: `Click the link to verify your email: ${process.env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,
92
- });
84
+ }), 'creating verification token');
85
+ // await transport.sendMail({
86
+ // from: 'noreply@studious.sh',
87
+ // to: user.email,
88
+ // subject: 'Verify your email',
89
+ // text: `Click the link to verify your email: ${process.env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,
90
+ // });
91
+ console.log(`${process.env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`);
93
92
  return {
94
93
  user: {
95
94
  id: user.id,
@@ -97,11 +96,11 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
97
96
  },
98
97
  };
99
98
  }),
100
- login: trpc_1.publicProcedure
99
+ login: publicProcedure
101
100
  .input(loginSchema)
102
101
  .mutation(async ({ input }) => {
103
102
  const { username, password } = input;
104
- const user = await prisma_1.prisma.user.findFirst({
103
+ const user = await prisma.user.findFirst({
105
104
  where: { username },
106
105
  select: {
107
106
  id: true,
@@ -112,13 +111,13 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
112
111
  }
113
112
  });
114
113
  if (!user) {
115
- throw new server_1.TRPCError({
114
+ throw new TRPCError({
116
115
  code: "UNAUTHORIZED",
117
116
  message: "Invalid username or password",
118
117
  });
119
118
  }
120
- if (await (0, bcryptjs_1.compare)(password, user.password)) {
121
- throw new server_1.TRPCError({
119
+ if (!(await compare(password, user.password))) {
120
+ throw new TRPCError({
122
121
  code: "UNAUTHORIZED",
123
122
  message: "Invalid username or password",
124
123
  });
@@ -132,9 +131,9 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
132
131
  };
133
132
  }
134
133
  // Create a new session
135
- const session = await prisma_1.prisma.session.create({
134
+ const session = await prisma.session.create({
136
135
  data: {
137
- id: (0, uuid_1.v4)(),
136
+ id: uuidv4(),
138
137
  userId: user.id,
139
138
  expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
140
139
  },
@@ -147,29 +146,29 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
147
146
  },
148
147
  };
149
148
  }),
150
- logout: trpc_1.publicProcedure
149
+ logout: publicProcedure
151
150
  .mutation(async ({ ctx }) => {
152
151
  if (!ctx.user) {
153
- throw new server_1.TRPCError({
152
+ throw new TRPCError({
154
153
  code: "UNAUTHORIZED",
155
154
  message: "Not authenticated",
156
155
  });
157
156
  }
158
157
  // Delete the current session
159
- await prisma_1.prisma.session.deleteMany({
158
+ await prisma.session.deleteMany({
160
159
  where: { userId: ctx.user.id },
161
160
  });
162
161
  return { success: true };
163
162
  }),
164
- check: trpc_1.protectedProcedure
163
+ check: protectedProcedure
165
164
  .query(async ({ ctx }) => {
166
165
  if (!ctx.user) {
167
- throw new server_1.TRPCError({
166
+ throw new TRPCError({
168
167
  code: "UNAUTHORIZED",
169
168
  message: "Not authenticated",
170
169
  });
171
170
  }
172
- const user = await prisma_1.prisma.user.findUnique({
171
+ const user = await prisma.user.findUnique({
173
172
  where: { id: ctx.user.id },
174
173
  select: {
175
174
  id: true,
@@ -177,79 +176,85 @@ exports.authRouter = (0, trpc_1.createTRPCRouter)({
177
176
  }
178
177
  });
179
178
  if (!user) {
180
- throw new server_1.TRPCError({
179
+ throw new TRPCError({
181
180
  code: "NOT_FOUND",
182
181
  message: "User not found",
183
182
  });
184
183
  }
185
184
  return { user };
186
185
  }),
187
- resendVerificationEmail: trpc_1.publicProcedure
188
- .input(zod_1.z.object({
189
- email: zod_1.z.string().email(),
186
+ resendVerificationEmail: publicProcedure
187
+ .input(z.object({
188
+ email: z.string().email(),
190
189
  }))
191
190
  .mutation(async ({ input }) => {
192
191
  const { email } = input;
193
- const user = await prisma_1.prisma.user.findFirst({
192
+ const user = await prisma.user.findFirst({
194
193
  where: {
195
194
  email,
196
195
  },
197
196
  select: {
198
197
  id: true,
199
198
  email: true,
199
+ role: true,
200
+ schoolId: true,
200
201
  },
201
202
  });
202
203
  if (!user) {
203
- throw new server_1.TRPCError({
204
+ throw new TRPCError({
204
205
  code: "NOT_FOUND",
205
206
  message: "User not found",
206
207
  });
207
208
  }
208
- await prisma_1.prisma.session.deleteMany({
209
+ await prisma.session.deleteMany({
209
210
  where: { userId: user?.id },
210
211
  });
211
- const verificationToken = await prisma_1.prisma.session.create({
212
+ const verificationToken = await prisma.session.create({
212
213
  data: {
213
- id: (0, uuid_1.v4)(),
214
+ id: uuidv4(),
214
215
  userId: user.id,
215
216
  expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
216
217
  },
217
218
  });
218
- await email_1.transport.sendMail({
219
- from: 'noreply@studious.sh',
220
- to: user.email,
221
- subject: 'Verify your email',
222
- text: `Click the link to verify your email: ${process.env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,
223
- });
219
+ // await transport.sendMail({
220
+ // from: 'noreply@studious.sh',
221
+ // to: user.email,
222
+ // subject: 'Verify your email',
223
+ // text: `Click the link to verify your email: ${process.env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,
224
+ // });
224
225
  return { success: true };
225
226
  }),
226
- verify: trpc_1.publicProcedure
227
- .input(zod_1.z.object({
228
- token: zod_1.z.string(),
227
+ verify: publicProcedure
228
+ .input(z.object({
229
+ token: z.string(),
229
230
  }))
230
231
  .mutation(async ({ input }) => {
231
232
  const { token } = input;
232
- const session = await prisma_1.prisma.session.findUnique({
233
+ const session = await prisma.session.findUnique({
233
234
  where: { id: token },
234
235
  });
235
236
  if (!session) {
236
- throw new server_1.TRPCError({
237
+ throw new TRPCError({
237
238
  code: "NOT_FOUND",
238
239
  message: "Session not found",
239
240
  });
240
241
  }
241
242
  if (session.expiresAt && session.expiresAt < new Date()) {
242
- throw new server_1.TRPCError({
243
+ throw new TRPCError({
243
244
  code: "UNAUTHORIZED",
244
245
  message: "Session expired",
245
246
  });
246
247
  }
247
- await prisma_1.prisma.user.update({
248
+ await prisma.user.update({
248
249
  where: { id: session.userId },
249
250
  data: {
250
251
  verified: true,
251
252
  },
252
253
  });
254
+ // Clean up the verification token
255
+ await prisma.session.delete({
256
+ where: { id: token },
257
+ });
253
258
  return { success: true };
254
259
  }),
255
260
  });