Skip to content

Commit

Permalink
fix(backend): add routes for admin
Browse files Browse the repository at this point in the history
  • Loading branch information
pYassine committed Dec 17, 2024
1 parent fe7e076 commit 51f83ed
Show file tree
Hide file tree
Showing 36 changed files with 552 additions and 366 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ async function createTables(queryRunner: QueryRunner) {
"timeZone" text NULL,
telephone jsonb DEFAULT '{"numero": "", "countryCode": "fr"}'::jsonb NOT NULL,
"acceptTerms" timestamptz NULL,
"filesUpdated" bool DEFAULT false NOT NULL,
latitude float8 NULL,
longitude float8 NULL,
"organismeType" text NULL,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
import { Structure } from "@domifa/common";

export const CurrentStructure = createParamDecorator(
(_data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.structure as Structure;
}
);
1 change: 1 addition & 0 deletions packages/backend/src/auth/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./AllowUserStructureRoles.decorator";
export * from "./current-chosen-user-structure.decorator";
export * from "./current-interaction.decorator";
export * from "./current-structure-information.decorator";
export * from "./current-structure.decorator";
export * from "./current-usager-doc.decorator";
export * from "./current-usager-note.decorator";
export * from "./current-usager.decorator";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function IsSocialGouvEmail(validationOptions?: ValidationOptions) {
registerDecorator({
name: "isValidPassword",
target: object.constructor,
propertyName: propertyName,
propertyName,
options: validationOptions,
constraints: [propertyName],
validator: {
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/auth/guards/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from "./AppUserGuard.guard";
export * from "./CanGetUserStructure.guard";
export * from "./interactions.guard";
export * from "./structure-access.guard";
export * from "./structure-information-access.guard";
export * from "./usager-access.guard";
export * from "./usager-doc-access.guard";
Expand Down
56 changes: 56 additions & 0 deletions packages/backend/src/auth/guards/structure-access.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
CanActivate,
ExecutionContext,
HttpException,
HttpStatus,
Injectable,
} from "@nestjs/common";

import { appLogger } from "../../util";
import { structureRepository } from "../../database";

@Injectable()
export class StructureAccessGuard implements CanActivate {
public async canActivate(context: ExecutionContext) {
const r = context.switchToHttp().getRequest();

console.log(r?.params?.structureId);
console.log(r?.user?.isSuperAdminDomifa);
if (!r?.params?.structureId || !r?.user?.isSuperAdminDomifa) {
appLogger.error("[StructureAccessGuard] invalid structureId for admin", {
sentry: true,
context: {
usagerRef: r?.params?.uui,
structureId: r?.user?.structureId,
user: r?.user?._id,
},
});
throw new HttpException(
"STRUCTURE_INFORMATION_NOT_FOUND",
HttpStatus.BAD_REQUEST
);
}

const structureId = parseInt(r.params.structureId, 10);

try {
const structure = await structureRepository.findOneOrFail({
where: {
id: structureId,
},
});
r.structure = structure;
return r;
} catch (e) {
appLogger.error("[UsagerAccessGuard] Structure not found", {
sentry: true,
context: {
structureId,
user: r?.user?._id,
role: r?.user?.role,
},
});
throw new HttpException("USAGER_NOT_FOUND", HttpStatus.BAD_REQUEST);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ export class StructureTable
@Column({ type: "bool", default: false })
import: boolean;

@Column({ type: "bool", default: false })
filesUpdated: boolean;

@Column({ type: "timestamptz", nullable: false })
registrationDate: Date;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const structureRepository = myDataSource
}): Promise<Pick<Structure, "hardReset" | "id" | "uuid">> {
const select = ["hardReset", "id", "uuid"];

return this.createQueryBuilder()
return await this.createQueryBuilder()
.select(joinSelectFields(select))
.where(`"hardReset" @> :hardReset`, {
hardReset: JSON.stringify({ token, userId }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import {
Res,
UseGuards,
Param,
ParseIntPipe,
} from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";

import { AllowUserProfiles } from "../../../../auth/decorators";
import { AppUserGuard } from "../../../../auth/guards";
import {
AllowUserProfiles,
CurrentStructure,
} from "../../../../auth/decorators";
import { AppUserGuard, StructureAccessGuard } from "../../../../auth/guards";
import {
userStructureRepository,
structureRepository,
userStructureSecurityRepository,
} from "../../../../database";
import { statsDeploiementExporter } from "../../../../excel/export-stats-deploiement";

Expand Down Expand Up @@ -111,39 +116,48 @@ export class AdminStructuresController {
}

@Get("structure/:structureId")
@UseGuards(StructureAccessGuard)
@AllowUserProfiles("super-admin-domifa")
public async getStructure(
@CurrentUser() _user: UserAdminAuthenticated,
@Param("structureId") structureId: number
@CurrentStructure() structure: Structure,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Param("structureId") _structureId: number
): Promise<Structure> {
return await structureRepository.findOneOrFail({
where: { id: structureId },
where: { id: structure.id },
});
}

@Get("structure/:structureId/users")
@UseGuards(StructureAccessGuard)
@AllowUserProfiles("super-admin-domifa")
public async getUsers(
@CurrentUser() _user: UserAdminAuthenticated,
@Param("structureId") structureId: number
@CurrentStructure() structure: Structure,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Param("structureId", new ParseIntPipe()) _structureId: number
): Promise<Array<UserStructureWithSecurity>> {
return (await userStructureRepository
.createQueryBuilder("u")
.leftJoinAndSelect("user_structure_security", "uss", "u.id = uss.user_id")
.select([
"u.nom",
"u.prenom",
"u.mail",
"u.role",
"u.lastLogin",
"u.id",
"u.uuid",
"u.createdAt",
"uss.temporaryTokens",
"uss.eventsHistory",
])
.where({ structureId })
.getMany()) as unknown as UserStructureWithSecurity[];
return (await userStructureSecurityRepository.query(
`
SELECT
user_structure.nom,
user_structure.id,
user_structure.prenom,
user_structure.email,
user_structure.role,
user_structure."lastLogin",
user_structure."createdAt",
user_structure.uuid,
uss."temporaryTokens",
uss."eventsHistory"
FROM user_structure_security uss
INNER JOIN user_structure
ON user_structure.id = uss."userId"
WHERE uss."structureId" = $1
`,
[structure.id]
)) as unknown as UserStructureWithSecurity[];
}

@AllowUserProfiles("super-admin-domifa")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export interface Structure extends AppEntity {
verified: boolean;

timeZone: TimeZone;
filesUpdated: boolean;

sms: StructureSmsParams;
portailUsager: StructurePortailUsagerParams;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,6 @@ <h1 class="title">Questions / Réponses sur DomiFa</h1>
Les fonctionnalités
</a>
</li>
<li>
<a
class="btn btn-outline-primary"
routerLink="/faq"
fragment="faq-videos"
>
Les tutoriels vidéo
</a>
</li>
</ol>
</nav>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class ManageUsagersPageComponent
placeholder: "Recherche par ID, nom, prénom, ayant-droit ou mandataire",
},
DATE_NAISSANCE: {
label: "Date de naissance",
label: "Date de naissance (format attendu: JJ/MM/AAAA)",
placeholder: "Recherche par date de naissance JJ/MM/AAAA",
},
};
Expand Down
Loading

0 comments on commit 51f83ed

Please sign in to comment.