refactor(backend): harden type safety in notification, auth, and toke…#73
Conversation
| async (request, reply) => { | ||
| const { id } = request.params as { id: string }; | ||
| const { currentPassword, newPassword } = request.body as any; | ||
| const user = request.user; | ||
|
|
||
| if (id !== user.id) { | ||
| return reply.status(403).send({ | ||
| statusCode: 403, | ||
| error: "Forbidden", | ||
| message: "You can only change your own password", | ||
| }); | ||
| } | ||
|
|
||
| // Verify current password first | ||
| // We need to fetch the user with password hash to verify | ||
| // AuthService.authenticate expects email, but we have ID. | ||
| // We'll need to manually check here or add a method to AuthService. | ||
| // Let's do it manually here for now using AuthService.verifyPassword helper | ||
| const { db } = await import("../db"); | ||
| const { users } = await import("../db/schema"); | ||
| const { eq } = await import("drizzle-orm"); | ||
|
|
||
| const [dbUser] = await db | ||
| .select() | ||
| .from(users) | ||
| .where(eq(users.id, id)) | ||
| .limit(1); | ||
|
|
||
| if (!dbUser || !dbUser.passwordHash) { | ||
| return reply.status(404).send({ | ||
| statusCode: 404, | ||
| error: "Not Found", | ||
| message: "User not found", | ||
| }); | ||
| } | ||
|
|
||
| const isValid = await AuthService.verifyPassword( | ||
| currentPassword, | ||
| dbUser.passwordHash, | ||
| ); | ||
| if (!isValid) { | ||
| return reply.status(401).send({ | ||
| statusCode: 401, | ||
| error: "Unauthorized", | ||
| message: "Invalid current password", | ||
| }); | ||
| } | ||
|
|
||
| await UserService.changePassword(id, newPassword); | ||
|
|
||
| return { | ||
| message: "Password changed successfully", | ||
| }; | ||
| }, |
Check failure
Code scanning / CodeQL
Missing rate limiting High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
The best way to fix the problem is to apply per-route rate limiting middleware. For Fastify, the most common and well-supported module is @fastify/rate-limit. This allows you to limit how many requests each IP/user can make to sensitive endpoints (like password changes) within a given time window. You will need to:
- Import and register
@fastify/rate-limitat the server/plugin level if not already done. - Add a
configproperty on the route options with arateLimitvalue for the password change route (here,/api/v1/users/:id/password). - Set reasonable values, e.g., max 5 requests per minute for password change.
- No other code or logic of the handler needs to change.
This change is entirely within backend/src/routes/users.ts.
| @@ -291,6 +291,12 @@ | ||
| }, | ||
| }, | ||
| preHandler: server.authenticate, | ||
| config: { | ||
| rateLimit: { | ||
| max: 5, | ||
| timeWindow: '1 minute' | ||
| } | ||
| }, | ||
| }, | ||
| async (request, reply) => { | ||
| const { id } = request.params as { id: string }; |
| if ((prediction.failureProbability || 0) >= 0.9) { | ||
| priority = "critical"; | ||
| daysUntilFailure = 1; | ||
| _daysUntilFailure = 1; |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
The best way to fix this issue is to remove the variable declaration and all assignments to _daysUntilFailure, since it is not used after being set. Specifically, edit backend/src/services/predictive-wo.service.ts: remove line 148 where _daysUntilFailure is declared, along with all lines assigning to it (lines 151, 154, 157, and 160). Ensure you only remove these lines, leaving the rest of the logic (the priority assignment and the if/else structure) intact. No imports, definitions, or new methods are needed. The surrounding code should remain unchanged, keeping context and control flow intact.
| @@ -145,19 +145,14 @@ | ||
|
|
||
| // Determine priority based on probability | ||
| let priority: "low" | "medium" | "high" | "critical"; | ||
| let _daysUntilFailure: number; | ||
| if ((prediction.failureProbability || 0) >= 0.9) { | ||
| priority = "critical"; | ||
| _daysUntilFailure = 1; | ||
| } else if ((prediction.failureProbability || 0) >= 0.8) { | ||
| priority = "high"; | ||
| _daysUntilFailure = 3; | ||
| } else if ((prediction.failureProbability || 0) >= 0.7) { | ||
| priority = "medium"; | ||
| _daysUntilFailure = 7; | ||
| } else { | ||
| priority = "low"; // Default for probabilities below 0.7 | ||
| _daysUntilFailure = 30; // Default for lower risk | ||
| } | ||
|
|
||
| // Get explanation (already fetched above, but if we needed fresh one): |
| } else if ((prediction.failureProbability || 0) >= 0.8) { | ||
| priority = "high"; | ||
| daysUntilFailure = 3; | ||
| _daysUntilFailure = 3; |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix this problem, the best approach is to remove the assignments to _daysUntilFailure in all branches of the conditional statements and eliminate the variable declaration itself (let _daysUntilFailure: number;). All usages of _daysUntilFailure are confined to setting its value; it is not read subsequently, so it adds no value and can be safely deleted. Only edit within the provided code region: remove lines 148 and all assignment lines (151, 154, 157, 160).
| @@ -145,19 +145,14 @@ | ||
|
|
||
| // Determine priority based on probability | ||
| let priority: "low" | "medium" | "high" | "critical"; | ||
| let _daysUntilFailure: number; | ||
| if ((prediction.failureProbability || 0) >= 0.9) { | ||
| priority = "critical"; | ||
| _daysUntilFailure = 1; | ||
| } else if ((prediction.failureProbability || 0) >= 0.8) { | ||
| priority = "high"; | ||
| _daysUntilFailure = 3; | ||
| } else if ((prediction.failureProbability || 0) >= 0.7) { | ||
| priority = "medium"; | ||
| _daysUntilFailure = 7; | ||
| } else { | ||
| priority = "low"; // Default for probabilities below 0.7 | ||
| _daysUntilFailure = 30; // Default for lower risk | ||
| } | ||
|
|
||
| // Get explanation (already fetched above, but if we needed fresh one): |
| } else if ((prediction.failureProbability || 0) >= 0.7) { | ||
| priority = "medium"; | ||
| daysUntilFailure = 7; | ||
| _daysUntilFailure = 7; |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
The best fix is to completely remove the _daysUntilFailure variable and its associated assignments. This includes:
- Deleting the declaration
let _daysUntilFailure: number;on line 148. - Removing the assignments to
_daysUntilFailureinside each branch of the if/else that sets its value (lines 151, 154, 157, and 160). - The rest of the code is unaffected since the variable isn't used later.
No changes to imports, other methods, or additional definitions are needed. The change is entirely localized to this part of the file.
| @@ -145,19 +145,15 @@ | ||
|
|
||
| // Determine priority based on probability | ||
| let priority: "low" | "medium" | "high" | "critical"; | ||
| let _daysUntilFailure: number; | ||
|
|
||
| if ((prediction.failureProbability || 0) >= 0.9) { | ||
| priority = "critical"; | ||
| _daysUntilFailure = 1; | ||
| } else if ((prediction.failureProbability || 0) >= 0.8) { | ||
| priority = "high"; | ||
| _daysUntilFailure = 3; | ||
| } else if ((prediction.failureProbability || 0) >= 0.7) { | ||
| priority = "medium"; | ||
| _daysUntilFailure = 7; | ||
| } else { | ||
| priority = "low"; // Default for probabilities below 0.7 | ||
| _daysUntilFailure = 30; // Default for lower risk | ||
| } | ||
|
|
||
| // Get explanation (already fetched above, but if we needed fresh one): |
| } else { | ||
| priority = "low"; // Default for probabilities below 0.7 | ||
| daysUntilFailure = 30; // Default for lower risk | ||
| _daysUntilFailure = 30; // Default for lower risk |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix this problem, simply remove the assignment to the unused local variable _daysUntilFailure in each branch of the conditional on lines 151, 154, 157, and 160, and remove its declaration if it is not otherwise needed. Carefully ensure that no other code snippet uses or expects _daysUntilFailure after the block. If it is not used anywhere after, also remove its variable definition on line 148. The edits are all contained within the function/method presented and depend only on the shown lines.
| @@ -145,19 +145,14 @@ | ||
|
|
||
| // Determine priority based on probability | ||
| let priority: "low" | "medium" | "high" | "critical"; | ||
| let _daysUntilFailure: number; | ||
| if ((prediction.failureProbability || 0) >= 0.9) { | ||
| priority = "critical"; | ||
| _daysUntilFailure = 1; | ||
| } else if ((prediction.failureProbability || 0) >= 0.8) { | ||
| priority = "high"; | ||
| _daysUntilFailure = 3; | ||
| } else if ((prediction.failureProbability || 0) >= 0.7) { | ||
| priority = "medium"; | ||
| _daysUntilFailure = 7; | ||
| } else { | ||
| priority = "low"; // Default for probabilities below 0.7 | ||
| _daysUntilFailure = 30; // Default for lower risk | ||
| } | ||
|
|
||
| // Get explanation (already fetched above, but if we needed fresh one): |
| import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; | ||
| import { Switch } from '@/components/ui/switch'; | ||
| import { useAuthStore } from '@/store/auth-store'; | ||
| import { User, Bell, Moon, Sun, Shield, Loader2 } from 'lucide-react'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To resolve this issue, simply remove the unused imports Bell, Shield, and User from the import statement on line 13 in the file frontend/src/app/settings/page.tsx. Ensure that only unused symbols are removed, and do not affect the ones that may still be in use (Moon, Sun, Loader2). The modified import statement will import only the necessary icons from 'lucide-react'.
| @@ -10,7 +10,7 @@ | ||
| import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; | ||
| import { Switch } from '@/components/ui/switch'; | ||
| import { useAuthStore } from '@/store/auth-store'; | ||
| import { User, Bell, Moon, Sun, Shield, Loader2 } from 'lucide-react'; | ||
| import { Moon, Sun, Loader2 } from 'lucide-react'; | ||
| import { userService } from '@/services/user.service'; | ||
| import { notificationService } from '@/services/notification.service'; | ||
| import { UserProfile } from '@/types/user'; |
| import { | ||
| Form, | ||
| FormControl, | ||
| FormDescription, | ||
| FormField, | ||
| FormItem, | ||
| FormLabel, | ||
| FormMessage, | ||
| } from '@/components/ui/form'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the issue, simply remove the unused FormDescription symbol from the import list from '@/components/ui/form' (line 9). Do not alter the rest of the import statement or any other imports from the module. This minimizes changes and preserves all existing functionality.
| @@ -9,7 +9,6 @@ | ||
| import { | ||
| Form, | ||
| FormControl, | ||
| FormDescription, | ||
| FormField, | ||
| FormItem, | ||
| FormLabel, |
| import { useEffect, useState } from 'react'; | ||
| import { useRouter } from 'next/navigation'; | ||
| import { useAuthStore } from '@/store/auth-store'; | ||
| import { api } from '@/lib/api-client'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, remove the unused import statement for api from line 6 of frontend/src/components/auth/auth-guard.tsx. This will improve code readability and prevent confusion related to unused code elements. Check that removing this import does not affect any other code within the shown snippet, which it does not, as api is only present in a commented-out line. No additional methods, variable definitions, or imports are needed.
| @@ -3,7 +3,6 @@ | ||
| import { useEffect, useState } from 'react'; | ||
| import { useRouter } from 'next/navigation'; | ||
| import { useAuthStore } from '@/store/auth-store'; | ||
| import { api } from '@/lib/api-client'; | ||
|
|
||
| interface AuthGuardProps { | ||
| children: React.ReactNode; |
| import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; | ||
| import { Checkbox } from '@/components/ui/checkbox'; | ||
| import { Textarea } from '@/components/ui/textarea'; | ||
| import { ReportDefinition, CreateReportDTO, UpdateReportDTO } from '@/types/report'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, simply remove the unused UpdateReportDTO import from the import statement on line 10 in frontend/src/components/reports/report-form.tsx. Specifically, update the import statement to only bring in ReportDefinition and CreateReportDTO. This will improve code clarity, reduce confusion, and slightly optimize the build process by not including unused code. No other changes are needed.
| @@ -7,7 +7,7 @@ | ||
| import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; | ||
| import { Checkbox } from '@/components/ui/checkbox'; | ||
| import { Textarea } from '@/components/ui/textarea'; | ||
| import { ReportDefinition, CreateReportDTO, UpdateReportDTO } from '@/types/report'; | ||
| import { ReportDefinition, CreateReportDTO } from '@/types/report'; | ||
| import { reportService } from '@/services/report.service'; | ||
| import { Loader2 } from 'lucide-react'; | ||
|
|
| import { | ||
| Card, | ||
| CardContent, | ||
| CardDescription, | ||
| CardFooter, | ||
| CardHeader, | ||
| CardTitle, | ||
| } from "@/components/ui/card"; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
The correct way to address this warning is to remove the unused imports from the import statement on lines 7–14 for cleaner and more maintainable code. No functionality elsewhere in the file depends upon these imports. Therefore, the entire destructured import statement from "@/components/ui/card" can be safely deleted. This edit is strictly limited to the shown file (frontend/src/components/reports/report-list.tsx), and no further changes or replacements are needed.
| @@ -4,15 +4,8 @@ | ||
| import { ReportDefinition } from "@/types/report"; | ||
| import { reportService } from "@/services/report.service"; | ||
| import { Button } from "@/components/ui/button"; | ||
|
|
||
| import { | ||
| Card, | ||
| CardContent, | ||
| CardDescription, | ||
| CardFooter, | ||
| CardHeader, | ||
| CardTitle, | ||
| } from "@/components/ui/card"; | ||
| import { | ||
| Table, | ||
| TableBody, | ||
| TableCell, |
…n services