1
- import { getAuthUserId } from "@convex-dev/auth/server" ;
2
1
import { R2 , type R2Callbacks } from "@convex-dev/r2" ;
3
2
import { ConvexError , v } from "convex/values" ;
4
3
import { UPLOAD_ALLOWED_MIME , UPLOAD_MAX_BYTES } from "@/lib/config/upload" ;
@@ -7,6 +6,7 @@ import { ERROR_CODES } from "../lib/error-codes";
7
6
import { api , components , internal } from "./_generated/api" ;
8
7
import type { Id } from "./_generated/dataModel" ;
9
8
import { action , internalMutation , mutation , query } from "./_generated/server" ;
9
+ import { authComponent } from "./auth" ;
10
10
11
11
// R2 client and client API exports (used by React upload hook and server routes)
12
12
const r2 = new R2 ( components . r2 ) ;
@@ -19,17 +19,18 @@ export const { generateUploadUrl, syncMetadata, onSyncMetadata } = r2.clientApi(
19
19
// Provide callbacks reference so the component can invoke onSyncMetadata
20
20
callbacks,
21
21
checkUpload : async ( ctx ) => {
22
- const userId = await getAuthUserId ( ctx ) ;
23
- if ( ! userId ) {
22
+ const authUser = await ctx . auth . getUserIdentity ( ) ;
23
+ if ( authUser === null ) {
24
24
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
25
25
}
26
26
} ,
27
27
// Create a pending attachment row on upload start
28
28
onUpload : async ( ctx , _bucket , key ) => {
29
- const userId = await getAuthUserId ( ctx ) ;
30
- if ( ! userId ) {
29
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
30
+ if ( ! authUser ?. userId ) {
31
31
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
32
32
}
33
+ const userId = authUser . userId as Id < "users" > ;
33
34
34
35
// If a row for this key already exists for this user, skip insert
35
36
const existing = await ctx . db
@@ -146,10 +147,11 @@ export const saveFileAttachment = action({
146
147
fileName : v . string ( ) ,
147
148
} ,
148
149
handler : async ( ctx , args ) : Promise < SavedAttachment > => {
149
- const userId = await getAuthUserId ( ctx ) ;
150
- if ( ! userId ) {
150
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
151
+ if ( ! authUser ?. userId ) {
151
152
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
152
153
}
154
+ const userId = authUser . userId as Id < "users" > ;
153
155
// Ensure we have fresh metadata from R2
154
156
// await ctx.runMutation(api.files.syncMetadata, { key: args.key });
155
157
@@ -216,8 +218,8 @@ export const saveGeneratedImage = action({
216
218
fileName : v . optional ( v . string ( ) ) ,
217
219
} ,
218
220
handler : async ( ctx , args ) : Promise < SavedAttachment > => {
219
- const userId = await getAuthUserId ( ctx ) ;
220
- if ( ! userId ) {
221
+ const authUser = await ctx . auth . getUserIdentity ( ) ;
222
+ if ( authUser === null ) {
221
223
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
222
224
}
223
225
@@ -270,10 +272,11 @@ export const internalSave = internalMutation({
270
272
url : v . optional ( v . string ( ) ) ,
271
273
} ,
272
274
handler : async ( ctx , args ) => {
273
- const userId = await getAuthUserId ( ctx ) ;
274
- if ( ! userId ) {
275
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
276
+ if ( ! authUser ?. userId ) {
275
277
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
276
278
}
279
+ const userId = authUser . userId as Id < "users" > ;
277
280
278
281
// Verify that the key belongs to the current user via the pending row.
279
282
const existing = await ctx . db
@@ -343,10 +346,11 @@ export const internalSaveGenerated = internalMutation({
343
346
url : v . optional ( v . string ( ) ) ,
344
347
} ,
345
348
handler : async ( ctx , args ) => {
346
- const userId = await getAuthUserId ( ctx ) ;
347
- if ( ! userId ) {
349
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
350
+ if ( ! authUser ?. userId ) {
348
351
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
349
352
}
353
+ const userId = authUser . userId as Id < "users" > ;
350
354
351
355
// Verify ownership of the key to this user
352
356
const existing = await ctx . db
@@ -389,10 +393,11 @@ export const internalSaveGenerated = internalMutation({
389
393
export const getAttachment = query ( {
390
394
args : { attachmentId : v . id ( "chat_attachments" ) } ,
391
395
handler : async ( ctx , args ) => {
392
- const userId = await getAuthUserId ( ctx ) ;
393
- if ( ! userId ) {
396
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
397
+ if ( ! authUser ?. userId ) {
394
398
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
395
399
}
400
+ const userId = authUser . userId as Id < "users" > ;
396
401
397
402
const attachment = await ctx . db . get ( args . attachmentId ) ;
398
403
if ( ! attachment || attachment . userId !== userId ) {
@@ -406,10 +411,11 @@ export const getAttachment = query({
406
411
export const findAttachmentByKey = query ( {
407
412
args : { key : v . string ( ) } ,
408
413
handler : async ( ctx , args ) => {
409
- const userId = await getAuthUserId ( ctx ) ;
410
- if ( ! userId ) {
414
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
415
+ if ( ! authUser ?. userId ) {
411
416
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
412
417
}
418
+ const userId = authUser . userId as Id < "users" > ;
413
419
const row = await ctx . db
414
420
. query ( "chat_attachments" )
415
421
. withIndex ( "by_key" , ( q ) => q . eq ( "key" , args . key ) )
@@ -428,8 +434,8 @@ export const getStorageUrl = query({
428
434
args : { key : v . string ( ) } ,
429
435
returns : v . union ( v . string ( ) , v . null ( ) ) ,
430
436
handler : async ( ctx , args ) => {
431
- const userId = await getAuthUserId ( ctx ) ;
432
- if ( ! userId ) {
437
+ const authUser = await ctx . auth . getUserIdentity ( ) ;
438
+ if ( authUser === null ) {
433
439
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
434
440
}
435
441
@@ -452,10 +458,11 @@ export const getStorageUrl = query({
452
458
export const getAttachmentsForUser = query ( {
453
459
args : { } ,
454
460
handler : async ( ctx ) => {
455
- const userId = await getAuthUserId ( ctx ) ;
456
- if ( ! userId ) {
457
- throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
461
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
462
+ if ( ! authUser ?. userId ) {
463
+ return [ ] ;
458
464
}
465
+ const userId = authUser . userId as Id < "users" > ;
459
466
460
467
const attachments = await ctx . db
461
468
. query ( "chat_attachments" )
@@ -475,10 +482,11 @@ export const getAttachmentsForUser = query({
475
482
export const deleteAttachments = mutation ( {
476
483
args : { attachmentIds : v . array ( v . id ( "chat_attachments" ) ) } ,
477
484
handler : async ( ctx , { attachmentIds } ) => {
478
- const userId = await getAuthUserId ( ctx ) ;
479
- if ( ! userId ) {
485
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
486
+ if ( ! authUser ?. userId ) {
480
487
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
481
488
}
489
+ const userId = authUser . userId as Id < "users" > ;
482
490
483
491
// Create a Set for O(1) lookup of attachment IDs to delete
484
492
const attachmentIdsToDelete = new Set ( attachmentIds ) ;
@@ -508,10 +516,11 @@ export const deleteAttachments = mutation({
508
516
export const getAttachmentsForChat = query ( {
509
517
args : { chatId : v . id ( "chats" ) } ,
510
518
handler : async ( ctx , args ) => {
511
- const userId = await getAuthUserId ( ctx ) ;
512
- if ( ! userId ) {
519
+ const authUser = await authComponent . safeGetAuthUser ( ctx ) ;
520
+ if ( ! authUser ?. userId ) {
513
521
throw new ConvexError ( ERROR_CODES . NOT_AUTHENTICATED ) ;
514
522
}
523
+ const userId = authUser . userId as Id < "users" > ;
515
524
516
525
// Verify ownership of the chat
517
526
const chat = await ctx . db . get ( args . chatId ) ;
0 commit comments