Fixed users not being able to view their files

This commit is contained in:
2026-06-19 09:50:42 +03:30
parent 0c5756d325
commit 3c863bb90c
12 changed files with 745 additions and 222 deletions

View File

@@ -97,7 +97,11 @@ import {
normalizeIranMobile,
partyPersonMatchesUser,
} from "src/helpers/iran-mobile";
import { buildBlamePartyAccessOrConditions } from "src/helpers/party-access-queries";
import {
buildBlamePartyAccessOrConditions,
collectUserIdVariants,
} from "src/helpers/party-access-queries";
import { resolveLinkedUserIdStrings } from "src/helpers/user-access-resolver";
@Injectable()
export class RequestManagementService {
@@ -4562,9 +4566,9 @@ export class RequestManagementService {
phone: string,
otp: string,
): Promise<Types.ObjectId> => {
const user = await this.userDbService.findOne({
$or: [{ username: phone }, { mobile: phone }],
});
const user = await this.userDbService.findOne(
buildUserLookupByPhone(phone),
);
if (!user)
throw new BadRequestException(`User not found for phone: ${phone}`);
const u = user as any;
@@ -4783,9 +4787,9 @@ export class RequestManagementService {
// Verify the OTP and resolve the user id.
const now = Date.now();
const user = await this.userDbService.findOne({
$or: [{ username: phone }, { mobile: phone }],
});
const user = await this.userDbService.findOne(
buildUserLookupByPhone(phone),
);
if (!user)
throw new BadRequestException(`User not found for phone: ${phone}`);
const u = user as any;
@@ -5029,7 +5033,14 @@ export class RequestManagementService {
query: ListQueryV2Dto = {},
): Promise<GetUserBlameListV2ResponseDto> {
try {
const orConditions = buildBlamePartyAccessOrConditions(user);
const linkedUserIds =
user?.role === RoleEnum.USER || !user?.role
? await resolveLinkedUserIdStrings(this.userDbService, user)
: [];
const orConditions = buildBlamePartyAccessOrConditions(
user,
linkedUserIds,
);
if (user?.role === RoleEnum.FIELD_EXPERT && user?.sub) {
orConditions.push({
@@ -5043,6 +5054,34 @@ export class RequestManagementService {
});
}
// Snapshot-party fallback: find blames via claims where this user appears
// in claim.snapshot.parties (the most reliable path for IN_PERSON flows).
const idVariants = collectUserIdVariants(
...(linkedUserIds.length > 0 ? linkedUserIds : [user?.sub].filter(Boolean)),
);
if (idVariants.length > 0) {
const snapshotFilter =
idVariants.length === 1
? { "snapshot.parties.person.userId": idVariants[0] }
: { "snapshot.parties.person.userId": { $in: idVariants } };
const linkedClaims = (await this.claimCaseDbService.find(
snapshotFilter as any,
{ lean: true, select: "blameRequestId owner.userId" },
)) as any[];
for (const c of linkedClaims) {
if (!c.blameRequestId) continue;
// Exclude if this user IS the owner (guilty party) — they already show
// up via the claim-owner route; we only want the damaged party here.
const ownerStr = c.owner?.userId ? String(c.owner.userId) : null;
const isOwner = ownerStr
? idVariants.some((id) => String(id) === ownerStr)
: false;
if (isOwner) continue;
orConditions.push({ _id: c.blameRequestId });
}
}
if (orConditions.length === 0) {
return { list: [], total: 0 };
}
@@ -5067,7 +5106,7 @@ export class RequestManagementService {
String(req.initiatedByRegistrarId) === String(user.sub));
const party = req.parties?.find((p: any) =>
partyPersonMatchesUser(p?.person, user),
partyPersonMatchesUser(p?.person, user, linkedUserIds),
);
const obj = req.toObject();
@@ -5332,6 +5371,10 @@ export class RequestManagementService {
if (!req) {
throw new NotFoundException("Request not found");
}
const linkedUserIds =
user?.role === RoleEnum.USER || !user?.role
? await resolveLinkedUserIdStrings(this.userDbService, user)
: [];
const isFieldExpertOwner =
req.expertInitiated &&
req.initiatedByFieldExpertId &&
@@ -5342,7 +5385,9 @@ export class RequestManagementService {
String(req.initiatedByRegistrarId) === String(user?.sub);
const isParty =
Array.isArray(req.parties) &&
req.parties.some((p: any) => partyPersonMatchesUser(p?.person, user));
req.parties.some((p: any) =>
partyPersonMatchesUser(p?.person, user, linkedUserIds),
);
if (!isFieldExpertOwner && !isRegistrarOwner && !isParty) {
throw new ForbiddenException("You do not have access to this request");
}
@@ -5392,7 +5437,7 @@ export class RequestManagementService {
isFieldExpertOwner || isRegistrarOwner
? allParties
: allParties.filter((p: any) =>
partyPersonMatchesUser(p?.person, user),
partyPersonMatchesUser(p?.person, user, linkedUserIds),
);
const parties = await Promise.all(
visibleParties.map((p: any) => this.sanitizePartyForBlameUserView(p)),
@@ -5586,7 +5631,8 @@ export class RequestManagementService {
role: PartyRole.FIRST,
person: {
userId: firstPartyUserId,
phoneNumber: formData.firstPartyPhoneNumber,
phoneNumber: normalizeIranMobile(formData.firstPartyPhoneNumber) ??
formData.firstPartyPhoneNumber,
nationalCodeOfInsurer: firstPartyPlate.nationalCodeOfInsurer,
nationalCodeOfDriver: firstPartyPlate.nationalCodeOfDriver,
insurerLicense: firstPartyPlate.insurerLicense,
@@ -5771,7 +5817,7 @@ export class RequestManagementService {
role,
person: {
userId,
phoneNumber,
phoneNumber: normalizeIranMobile(phoneNumber) ?? phoneNumber,
nationalCodeOfInsurer: plateDto.nationalCodeOfInsurer,
nationalCodeOfDriver: plateDto.nationalCodeOfDriver,
insurerLicense: plateDto.insurerLicense,