@goscribe/server 1.0.7 → 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.
package/dist/context.d.ts CHANGED
@@ -4,6 +4,6 @@ export declare function createContext({ req, res }: CreateExpressContextOptions)
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  }>;
9
9
  export type Context = Awaited<ReturnType<typeof createContext>>;
package/dist/lib/auth.js CHANGED
@@ -2,28 +2,32 @@
2
2
  import crypto from "node:crypto";
3
3
  // Custom HMAC cookie: auth_token = base64(userId).hex(hmacSHA256(base64(userId), secret))
4
4
  export function verifyCustomAuthCookie(cookieValue) {
5
- if (!cookieValue)
5
+ if (!cookieValue) {
6
6
  return null;
7
- const secret = process.env.CUSTOM_AUTH_SECRET;
8
- if (!secret)
7
+ }
8
+ const secret = process.env.AUTH_SECRET;
9
+ if (!secret) {
9
10
  return null;
11
+ }
10
12
  const parts = cookieValue.split(".");
11
- if (parts.length !== 2)
13
+ if (parts.length !== 2) {
12
14
  return null;
15
+ }
13
16
  const [base64UserId, signatureHex] = parts;
14
17
  let userId;
15
18
  try {
16
19
  const buf = Buffer.from(base64UserId, "base64url");
17
20
  userId = buf.toString("utf8");
18
21
  }
19
- catch {
22
+ catch (error) {
20
23
  return null;
21
24
  }
22
25
  const hmac = crypto.createHmac("sha256", secret);
23
26
  hmac.update(base64UserId);
24
27
  const expected = hmac.digest("hex");
25
- if (!timingSafeEqualHex(signatureHex, expected))
28
+ if (!timingSafeEqualHex(signatureHex, expected)) {
26
29
  return null;
30
+ }
27
31
  return { userId };
28
32
  }
29
33
  function timingSafeEqualHex(a, b) {
@@ -5,7 +5,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
5
5
  session: any;
6
6
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
7
7
  res: import("express").Response<any, Record<string, any>>;
8
- cookies: any;
8
+ cookies: Record<string, string | undefined>;
9
9
  };
10
10
  meta: object;
11
11
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -17,7 +17,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
17
17
  session: any;
18
18
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
19
19
  res: import("express").Response<any, Record<string, any>>;
20
- cookies: any;
20
+ cookies: Record<string, string | undefined>;
21
21
  };
22
22
  meta: object;
23
23
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -42,22 +42,16 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
42
42
  password: string;
43
43
  };
44
44
  output: {
45
- id: any;
46
- session: any;
47
- user: {
48
- id: string;
49
- email: string | null;
50
- name: string | null;
51
- image: string | null;
52
- };
45
+ id: string;
46
+ email: string | null;
47
+ name: string | null;
48
+ image: string | null;
53
49
  };
54
50
  meta: object;
55
51
  }>;
56
52
  getSession: import("@trpc/server").TRPCQueryProcedure<{
57
53
  input: void;
58
54
  output: {
59
- id: any;
60
- userId: any;
61
55
  user: {
62
56
  id: string;
63
57
  email: string | null;
@@ -67,6 +61,13 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
67
61
  };
68
62
  meta: object;
69
63
  }>;
64
+ logout: import("@trpc/server").TRPCMutationProcedure<{
65
+ input: void;
66
+ output: {
67
+ success: boolean;
68
+ };
69
+ meta: object;
70
+ }>;
70
71
  }>>;
71
72
  workspace: import("@trpc/server").TRPCBuiltRouter<{
72
73
  ctx: {
@@ -74,7 +75,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
74
75
  session: any;
75
76
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
76
77
  res: import("express").Response<any, Record<string, any>>;
77
- cookies: any;
78
+ cookies: Record<string, string | undefined>;
78
79
  };
79
80
  meta: object;
80
81
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -178,7 +179,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
178
179
  session: any;
179
180
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
180
181
  res: import("express").Response<any, Record<string, any>>;
181
- cookies: any;
182
+ cookies: Record<string, string | undefined>;
182
183
  };
183
184
  meta: object;
184
185
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -188,7 +189,17 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
188
189
  input: {
189
190
  workspaceId: string;
190
191
  };
191
- output: {
192
+ output: ({
193
+ versions: {
194
+ id: string;
195
+ createdAt: Date;
196
+ createdById: string | null;
197
+ artifactId: string;
198
+ content: string;
199
+ data: import("@prisma/client/runtime/library").JsonValue | null;
200
+ version: number;
201
+ }[];
202
+ } & {
192
203
  id: string;
193
204
  createdAt: Date;
194
205
  updatedAt: Date;
@@ -197,55 +208,27 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
197
208
  type: import("@prisma/client").$Enums.ArtifactType;
198
209
  isArchived: boolean;
199
210
  createdById: string | null;
200
- }[];
211
+ })[];
201
212
  meta: object;
202
213
  }>;
203
- createSet: import("@trpc/server").TRPCMutationProcedure<{
214
+ listCards: import("@trpc/server").TRPCQueryProcedure<{
204
215
  input: {
205
216
  workspaceId: string;
206
- title: string;
207
217
  };
208
218
  output: {
209
219
  id: string;
210
220
  createdAt: Date;
211
- updatedAt: Date;
212
- title: string;
213
- workspaceId: string;
214
- type: import("@prisma/client").$Enums.ArtifactType;
215
- isArchived: boolean;
216
- createdById: string | null;
217
- };
218
- meta: object;
219
- }>;
220
- getSet: import("@trpc/server").TRPCQueryProcedure<{
221
- input: {
222
- setId: string;
223
- };
224
- output: {
225
- flashcards: {
226
- id: string;
227
- createdAt: Date;
228
- artifactId: string;
229
- front: string;
230
- back: string;
231
- tags: string[];
232
- order: number;
233
- }[];
234
- } & {
235
- id: string;
236
- createdAt: Date;
237
- updatedAt: Date;
238
- title: string;
239
- workspaceId: string;
240
- type: import("@prisma/client").$Enums.ArtifactType;
241
- isArchived: boolean;
242
- createdById: string | null;
243
- };
221
+ artifactId: string;
222
+ front: string;
223
+ back: string;
224
+ tags: string[];
225
+ order: number;
226
+ }[];
244
227
  meta: object;
245
228
  }>;
246
229
  createCard: import("@trpc/server").TRPCMutationProcedure<{
247
230
  input: {
248
- setId: string;
231
+ workspaceId: string;
249
232
  front: string;
250
233
  back: string;
251
234
  tags?: string[] | undefined;
@@ -288,13 +271,6 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
288
271
  output: boolean;
289
272
  meta: object;
290
273
  }>;
291
- deleteSet: import("@trpc/server").TRPCMutationProcedure<{
292
- input: {
293
- setId: string;
294
- };
295
- output: boolean;
296
- meta: object;
297
- }>;
298
274
  }>>;
299
275
  worksheets: import("@trpc/server").TRPCBuiltRouter<{
300
276
  ctx: {
@@ -302,17 +278,37 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
302
278
  session: any;
303
279
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
304
280
  res: import("express").Response<any, Record<string, any>>;
305
- cookies: any;
281
+ cookies: Record<string, string | undefined>;
306
282
  };
307
283
  meta: object;
308
284
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
309
285
  transformer: true;
310
286
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
311
- listSets: import("@trpc/server").TRPCQueryProcedure<{
287
+ list: import("@trpc/server").TRPCQueryProcedure<{
312
288
  input: {
313
289
  workspaceId: string;
314
290
  };
315
- output: {
291
+ output: ({
292
+ versions: {
293
+ id: string;
294
+ createdAt: Date;
295
+ createdById: string | null;
296
+ artifactId: string;
297
+ content: string;
298
+ data: import("@prisma/client/runtime/library").JsonValue | null;
299
+ version: number;
300
+ }[];
301
+ questions: {
302
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
303
+ id: string;
304
+ createdAt: Date;
305
+ artifactId: string;
306
+ order: number;
307
+ prompt: string;
308
+ answer: string | null;
309
+ difficulty: import("@prisma/client").$Enums.Difficulty;
310
+ }[];
311
+ } & {
316
312
  id: string;
317
313
  createdAt: Date;
318
314
  updatedAt: Date;
@@ -321,10 +317,10 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
321
317
  type: import("@prisma/client").$Enums.ArtifactType;
322
318
  isArchived: boolean;
323
319
  createdById: string | null;
324
- }[];
320
+ })[];
325
321
  meta: object;
326
322
  }>;
327
- createSet: import("@trpc/server").TRPCMutationProcedure<{
323
+ createWorksheet: import("@trpc/server").TRPCMutationProcedure<{
328
324
  input: {
329
325
  workspaceId: string;
330
326
  title: string;
@@ -341,9 +337,9 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
341
337
  };
342
338
  meta: object;
343
339
  }>;
344
- getSet: import("@trpc/server").TRPCQueryProcedure<{
340
+ get: import("@trpc/server").TRPCQueryProcedure<{
345
341
  input: {
346
- setId: string;
342
+ worksheetId: string;
347
343
  };
348
344
  output: {
349
345
  questions: {
@@ -368,9 +364,9 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
368
364
  };
369
365
  meta: object;
370
366
  }>;
371
- createQuestion: import("@trpc/server").TRPCMutationProcedure<{
367
+ createWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
372
368
  input: {
373
- setId: string;
369
+ worksheetId: string;
374
370
  prompt: string;
375
371
  answer?: string | undefined;
376
372
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
@@ -389,9 +385,9 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
389
385
  };
390
386
  meta: object;
391
387
  }>;
392
- updateQuestion: import("@trpc/server").TRPCMutationProcedure<{
388
+ updateWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
393
389
  input: {
394
- questionId: string;
390
+ worksheetQuestionId: string;
395
391
  prompt?: string | undefined;
396
392
  answer?: string | undefined;
397
393
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
@@ -410,16 +406,16 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
410
406
  };
411
407
  meta: object;
412
408
  }>;
413
- deleteQuestion: import("@trpc/server").TRPCMutationProcedure<{
409
+ deleteWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
414
410
  input: {
415
- questionId: string;
411
+ worksheetQuestionId: string;
416
412
  };
417
413
  output: boolean;
418
414
  meta: object;
419
415
  }>;
420
- deleteSet: import("@trpc/server").TRPCMutationProcedure<{
416
+ deleteWorksheet: import("@trpc/server").TRPCMutationProcedure<{
421
417
  input: {
422
- setId: string;
418
+ worksheetId: string;
423
419
  };
424
420
  output: boolean;
425
421
  meta: object;
@@ -1,8 +1,8 @@
1
1
  import { router } from '../trpc.js';
2
2
  import { auth } from './auth.js';
3
3
  import { workspace } from './workspace.js';
4
- import { flashcards } from './flashcards';
5
- import { worksheets } from './worksheets';
4
+ import { flashcards } from './flashcards.js';
5
+ import { worksheets } from './worksheets.js';
6
6
  export const appRouter = router({
7
7
  auth,
8
8
  workspace,
@@ -4,7 +4,7 @@ export declare const auth: import("@trpc/server").TRPCBuiltRouter<{
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  };
9
9
  meta: object;
10
10
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -29,22 +29,16 @@ export declare const auth: import("@trpc/server").TRPCBuiltRouter<{
29
29
  password: string;
30
30
  };
31
31
  output: {
32
- id: any;
33
- session: any;
34
- user: {
35
- id: string;
36
- email: string | null;
37
- name: string | null;
38
- image: string | null;
39
- };
32
+ id: string;
33
+ email: string | null;
34
+ name: string | null;
35
+ image: string | null;
40
36
  };
41
37
  meta: object;
42
38
  }>;
43
39
  getSession: import("@trpc/server").TRPCQueryProcedure<{
44
40
  input: void;
45
41
  output: {
46
- id: any;
47
- userId: any;
48
42
  user: {
49
43
  id: string;
50
44
  email: string | null;
@@ -54,4 +48,11 @@ export declare const auth: import("@trpc/server").TRPCBuiltRouter<{
54
48
  };
55
49
  meta: object;
56
50
  }>;
51
+ logout: import("@trpc/server").TRPCMutationProcedure<{
52
+ input: void;
53
+ output: {
54
+ success: boolean;
55
+ };
56
+ meta: object;
57
+ }>;
57
58
  }>>;
@@ -2,6 +2,19 @@ import { z } from 'zod';
2
2
  import { router, publicProcedure } from '../trpc.js';
3
3
  import bcrypt from 'bcryptjs';
4
4
  import { serialize } from 'cookie';
5
+ import crypto from 'node:crypto';
6
+ // Helper to create custom auth token
7
+ function createCustomAuthToken(userId) {
8
+ const secret = process.env.AUTH_SECRET;
9
+ if (!secret) {
10
+ throw new Error("AUTH_SECRET is not set");
11
+ }
12
+ const base64UserId = Buffer.from(userId, 'utf8').toString('base64url');
13
+ const hmac = crypto.createHmac('sha256', secret);
14
+ hmac.update(base64UserId);
15
+ const signature = hmac.digest('hex');
16
+ return `${base64UserId}.${signature}`;
17
+ }
5
18
  export const auth = router({
6
19
  signup: publicProcedure
7
20
  .input(z.object({
@@ -43,39 +56,53 @@ export const auth = router({
43
56
  if (!valid) {
44
57
  throw new Error("Invalid credentials");
45
58
  }
46
- const session = await ctx.db.session.create({
47
- data: {
48
- userId: user.id,
49
- expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
50
- },
59
+ // Create custom auth token
60
+ const authToken = createCustomAuthToken(user.id);
61
+ // Set the cookie immediately after successful login
62
+ const cookieValue = serialize("auth_token", authToken, {
63
+ httpOnly: true,
64
+ secure: process.env.NODE_ENV === "production",
65
+ sameSite: "lax",
66
+ path: "/",
67
+ maxAge: 60 * 60 * 24 * 30, // 30 days
51
68
  });
52
- return { id: session.id, session: session.id, user: { id: user.id, email: user.email, name: user.name, image: user.image } };
69
+ ctx.res.setHeader("Set-Cookie", cookieValue);
70
+ return {
71
+ id: user.id,
72
+ email: user.email,
73
+ name: user.name,
74
+ image: user.image
75
+ };
53
76
  }),
54
77
  getSession: publicProcedure.query(async ({ ctx }) => {
55
- const session = await ctx.db.session.findUnique({
56
- where: {
57
- id: ctx.session?.id,
58
- },
59
- });
60
- if (!session) {
61
- throw new Error("Session not found");
62
- }
63
- if (session.expires < new Date()) {
64
- throw new Error("Session expired");
78
+ // Just return the current session from context
79
+ if (!ctx.session) {
80
+ throw new Error("No session found");
65
81
  }
66
82
  const user = await ctx.db.user.findUnique({
67
- where: { id: session.userId },
83
+ where: { id: ctx.session.user.id },
68
84
  });
69
85
  if (!user) {
70
86
  throw new Error("User not found");
71
87
  }
72
- ctx.res.setHeader("Set-Cookie", serialize("auth_token", session.id, {
88
+ return {
89
+ user: {
90
+ id: user.id,
91
+ email: user.email,
92
+ name: user.name,
93
+ image: user.image
94
+ }
95
+ };
96
+ }),
97
+ logout: publicProcedure.mutation(async ({ ctx }) => {
98
+ // Clear the auth cookie
99
+ ctx.res.setHeader("Set-Cookie", serialize("auth_token", "", {
73
100
  httpOnly: true,
74
101
  secure: process.env.NODE_ENV === "production",
75
- sameSite: "none", // cross-origin XHR needs None
102
+ sameSite: "lax",
76
103
  path: "/",
77
- maxAge: 60 * 60 * 24 * 7,
104
+ maxAge: 0, // Expire immediately
78
105
  }));
79
- return { id: session.id, userId: session.userId, user: { id: user.id, email: user.email, name: user.name, image: user.image } };
106
+ return { success: true };
80
107
  }),
81
108
  });
@@ -4,7 +4,7 @@ export declare const flashcards: import("@trpc/server").TRPCBuiltRouter<{
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  };
9
9
  meta: object;
10
10
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -14,7 +14,17 @@ export declare const flashcards: import("@trpc/server").TRPCBuiltRouter<{
14
14
  input: {
15
15
  workspaceId: string;
16
16
  };
17
- output: {
17
+ output: ({
18
+ versions: {
19
+ id: string;
20
+ createdAt: Date;
21
+ createdById: string | null;
22
+ artifactId: string;
23
+ content: string;
24
+ data: import("@prisma/client/runtime/library").JsonValue | null;
25
+ version: number;
26
+ }[];
27
+ } & {
18
28
  id: string;
19
29
  createdAt: Date;
20
30
  updatedAt: Date;
@@ -23,55 +33,27 @@ export declare const flashcards: import("@trpc/server").TRPCBuiltRouter<{
23
33
  type: import("@prisma/client").$Enums.ArtifactType;
24
34
  isArchived: boolean;
25
35
  createdById: string | null;
26
- }[];
36
+ })[];
27
37
  meta: object;
28
38
  }>;
29
- createSet: import("@trpc/server").TRPCMutationProcedure<{
39
+ listCards: import("@trpc/server").TRPCQueryProcedure<{
30
40
  input: {
31
41
  workspaceId: string;
32
- title: string;
33
42
  };
34
43
  output: {
35
44
  id: string;
36
45
  createdAt: Date;
37
- updatedAt: Date;
38
- title: string;
39
- workspaceId: string;
40
- type: import("@prisma/client").$Enums.ArtifactType;
41
- isArchived: boolean;
42
- createdById: string | null;
43
- };
44
- meta: object;
45
- }>;
46
- getSet: import("@trpc/server").TRPCQueryProcedure<{
47
- input: {
48
- setId: string;
49
- };
50
- output: {
51
- flashcards: {
52
- id: string;
53
- createdAt: Date;
54
- artifactId: string;
55
- front: string;
56
- back: string;
57
- tags: string[];
58
- order: number;
59
- }[];
60
- } & {
61
- id: string;
62
- createdAt: Date;
63
- updatedAt: Date;
64
- title: string;
65
- workspaceId: string;
66
- type: import("@prisma/client").$Enums.ArtifactType;
67
- isArchived: boolean;
68
- createdById: string | null;
69
- };
46
+ artifactId: string;
47
+ front: string;
48
+ back: string;
49
+ tags: string[];
50
+ order: number;
51
+ }[];
70
52
  meta: object;
71
53
  }>;
72
54
  createCard: import("@trpc/server").TRPCMutationProcedure<{
73
55
  input: {
74
- setId: string;
56
+ workspaceId: string;
75
57
  front: string;
76
58
  back: string;
77
59
  tags?: string[] | undefined;
@@ -114,11 +96,4 @@ export declare const flashcards: import("@trpc/server").TRPCBuiltRouter<{
114
96
  output: boolean;
115
97
  meta: object;
116
98
  }>;
117
- deleteSet: import("@trpc/server").TRPCMutationProcedure<{
118
- input: {
119
- setId: string;
120
- };
121
- output: boolean;
122
- meta: object;
123
- }>;
124
99
  }>>;