Browse Source

feat(auth): add user ownership to file uploads with kinde integration

- Integrate Kinde auth client to retrieve authenticated user ID
- Update uploadFile calls to include userId parameter for ownership tracking
- Replace generic "unknown-user-id" fallback for unauthenticated uploads
- Update CreateImportDialog and UploadForm components to pass user context
vidane 6 tháng trước cách đây
mục cha
commit
10b5ac1046
2 tập tin đã thay đổi với 11 bổ sung13 xóa
  1. 7 12
      app/components/imports/CreateImportDialog.tsx
  2. 4 1
      app/components/uploadForm.tsx

+ 7 - 12
app/components/imports/CreateImportDialog.tsx

@@ -1,5 +1,6 @@
 'use client';
 
+import { useKindeBrowserClient } from "@kinde-oss/kinde-auth-nextjs";
 import { useState, useEffect } from 'react';
 import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
 import { Button } from '@/components/ui/button';
@@ -29,6 +30,7 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
   const [layouts, setLayouts] = useState<LayoutConfiguration[]>([]);
   const [loadingLayouts, setLoadingLayouts] = useState(true);
   const { toast } = useToast();
+  const { user } = useKindeBrowserClient();
 
   useEffect(() => {
     async function loadLayouts() {
@@ -98,21 +100,14 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
 
     try {
       // First, upload the file
-      const uploadResult = await uploadFile(selectedFile);
-      if (!uploadResult.success) {
-        toast({
-          title: 'Error',
-          description: uploadResult.error || 'Failed to upload file',
-          variant: 'destructive',
-        });
-        return;
-      }
+      const userId = user?.id ? user.id : "unknown-user-id";
+      const uploadResult = await uploadFile(selectedFile, userId);
 
       // Then create the import with the file reference
       const result = await createImport({
         name: name.trim(),
         layoutId: parseInt(layoutId),
-        fileId: uploadResult.data?.id,
+        fileId: uploadResult.id,
       });
 
       if (result.success) {
@@ -199,8 +194,8 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
             <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
               Cancel
             </Button>
-            <Button 
-              type="submit" 
+            <Button
+              type="submit"
               disabled={loading || !selectedFile || !name || !layoutId}
             >
               {loading ? 'Creating...' : 'Create Import'}

+ 4 - 1
app/components/uploadForm.tsx

@@ -1,5 +1,6 @@
 "use client";
 
+import { useKindeBrowserClient } from "@kinde-oss/kinde-auth-nextjs";
 import { useState } from "react";
 import { useQueryClient } from "@tanstack/react-query";
 
@@ -15,6 +16,7 @@ interface FileData {
 export const UploadForm = ({ onFileUploaded }: { onFileUploaded?: (file: FileData) => void }) => {
   const [isUploading, setIsUploading] = useState(false);
   const queryClient = useQueryClient();
+  const { user } = useKindeBrowserClient();
 
   const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
     if (e.target.files && e.target.files[0]) {
@@ -25,7 +27,8 @@ export const UploadForm = ({ onFileUploaded }: { onFileUploaded?: (file: FileDat
         // Import the server action
         const { uploadFile } = await import('../actions/file-upload');
 
-        const uploadedFile = await uploadFile(file);
+        const userId = user?.id ? user.id : "unknown-user-id";
+        const uploadedFile = await uploadFile(file, userId);
 
         // Invalidate the files query to trigger a refresh
         await queryClient.invalidateQueries({ queryKey: ["files"] });