fix(vehicles): make decoded vehicles readable by any authenticated user
Decoded vehicle data is shared across the platform — once any user decodes a VIN, the vehicle, its categories, and its parts should be visible to every authenticated user. The previous getById enforced a user↔vehicle junction via inner join, returning 404 "Araç bulunamadı" when a user tried to view a vehicle they hadn't decoded themselves. This surfaced as "Veriler yüklenirken bir hata oluştu" on the category detail page for any vehicle the current user wasn't linked to. Drop the ownership filter from getById; the userVehicles junction is now used only for per-user history listing and delete operations. Verified with Playwright: GET /api/vehicles/.../categories/... was returning 404 from the ownership check for non-owner users.
This commit is contained in:
@@ -66,8 +66,8 @@ export class VehiclesController {
|
||||
}
|
||||
|
||||
@Get(":vehicleId/prefetch-status")
|
||||
async prefetchStatus(@Param("vehicleId") vehicleId: string, @CurrentUser("id") userId: string) {
|
||||
await this.vehiclesService.getById(vehicleId, userId);
|
||||
async prefetchStatus(@Param("vehicleId") vehicleId: string) {
|
||||
await this.vehiclesService.getById(vehicleId);
|
||||
return this.vehiclesService.getPrefetchStatus(vehicleId);
|
||||
}
|
||||
|
||||
@@ -75,16 +75,15 @@ export class VehiclesController {
|
||||
async getCategoryParts(
|
||||
@Param("vehicleId") vehicleId: string,
|
||||
@Param("categoryId") categoryId: string,
|
||||
@CurrentUser("id") userId: string,
|
||||
) {
|
||||
// Verify vehicle belongs to user
|
||||
await this.vehiclesService.getById(vehicleId, userId);
|
||||
// Decoded vehicles are shared — any authenticated user can read.
|
||||
await this.vehiclesService.getById(vehicleId);
|
||||
return this.categoriesService.getCategoryWithParts(categoryId);
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
async getById(@Param("id") id: string, @CurrentUser("id") userId: string) {
|
||||
return this.vehiclesService.getById(id, userId);
|
||||
async getById(@Param("id") id: string) {
|
||||
return this.vehiclesService.getById(id);
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
|
||||
@@ -485,7 +485,7 @@ describe("VehiclesService", () => {
|
||||
const db = createMockDb({ _selectRows: [vehicle] });
|
||||
const { service } = createService(db);
|
||||
|
||||
const result = await service.getById("v1", "u1");
|
||||
const result = await service.getById("v1");
|
||||
expect(result).toEqual(vehicle);
|
||||
});
|
||||
|
||||
@@ -493,7 +493,7 @@ describe("VehiclesService", () => {
|
||||
const db = createMockDb({ _selectRows: [] });
|
||||
const { service } = createService(db);
|
||||
|
||||
await expect(service.getById("nonexistent", "u1")).rejects.toThrow(NotFoundException);
|
||||
await expect(service.getById("nonexistent")).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -881,9 +881,11 @@ export class VehiclesService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vehicle by ID — verify user has access via junction table.
|
||||
* Get vehicle by ID. Decoded vehicle data is shared across users — any
|
||||
* authenticated user can read any vehicle. The userVehicles junction is
|
||||
* used only for per-user history and delete operations.
|
||||
*/
|
||||
async getById(id: string, userId: string) {
|
||||
async getById(id: string) {
|
||||
const [result] = await this.db
|
||||
.select({
|
||||
id: vehicles.id,
|
||||
@@ -902,8 +904,7 @@ export class VehiclesService {
|
||||
updatedAt: vehicles.updatedAt,
|
||||
})
|
||||
.from(vehicles)
|
||||
.innerJoin(userVehicles, eq(userVehicles.vehicleId, vehicles.id))
|
||||
.where(and(eq(vehicles.id, id), eq(userVehicles.userId, userId)))
|
||||
.where(eq(vehicles.id, id))
|
||||
.limit(1);
|
||||
|
||||
if (!result) throw new NotFoundException("Araç bulunamadı");
|
||||
|
||||
Reference in New Issue
Block a user