Merge branch 'develop' (squash) – Statut refusé #105, script Gitea fallback ~/.bashrc
Made-with: Cursor
This commit is contained in:
parent
af489f39b4
commit
94c8a0d97a
@ -29,6 +29,7 @@ export enum StatutUtilisateurType {
|
|||||||
EN_ATTENTE = 'en_attente',
|
EN_ATTENTE = 'en_attente',
|
||||||
ACTIF = 'actif',
|
ACTIF = 'actif',
|
||||||
SUSPENDU = 'suspendu',
|
SUSPENDU = 'suspendu',
|
||||||
|
REFUSE = 'refuse',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SituationFamilialeType {
|
export enum SituationFamilialeType {
|
||||||
|
|||||||
@ -96,6 +96,12 @@ export class AuthService {
|
|||||||
throw new UnauthorizedException('Votre compte a été suspendu. Contactez un administrateur.');
|
throw new UnauthorizedException('Votre compte a été suspendu. Contactez un administrateur.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.statut === StatutUtilisateurType.REFUSE) {
|
||||||
|
throw new UnauthorizedException(
|
||||||
|
'Votre compte a été refusé. Vous pouvez corriger votre dossier et le soumettre à nouveau ; un gestionnaire pourra le réexaminer.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return this.generateTokens(user.id, user.email, user.role);
|
return this.generateTokens(user.id, user.email, user.role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,16 @@ export class UserController {
|
|||||||
return this.userService.findPendingUsers(role);
|
return this.userService.findPendingUsers(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lister les comptes refusés (à corriger / reprise)
|
||||||
|
@Get('reprise')
|
||||||
|
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE)
|
||||||
|
@ApiOperation({ summary: 'Lister les comptes refusés (reprise)' })
|
||||||
|
findRefusedUsers(
|
||||||
|
@Query('role') role?: RoleType
|
||||||
|
) {
|
||||||
|
return this.userService.findRefusedUsers(role);
|
||||||
|
}
|
||||||
|
|
||||||
// Lister tous les utilisateurs (super_admin uniquement)
|
// Lister tous les utilisateurs (super_admin uniquement)
|
||||||
@Get()
|
@Get()
|
||||||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
|
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
|
||||||
@ -112,6 +122,18 @@ export class UserController {
|
|||||||
return this.userService.validateUser(id, currentUser, comment);
|
return this.userService.validateUser(id, currentUser, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Patch(':id/refuser')
|
||||||
|
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||||||
|
@ApiOperation({ summary: 'Refuser un compte (à corriger)' })
|
||||||
|
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||||||
|
refuse(
|
||||||
|
@Param('id') id: string,
|
||||||
|
@User() currentUser: Users,
|
||||||
|
@Body('comment') comment?: string,
|
||||||
|
) {
|
||||||
|
return this.userService.refuseUser(id, currentUser, comment);
|
||||||
|
}
|
||||||
|
|
||||||
@Patch(':id/suspendre')
|
@Patch(':id/suspendre')
|
||||||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||||||
@ApiOperation({ summary: 'Suspendre un compte utilisateur' })
|
@ApiOperation({ summary: 'Suspendre un compte utilisateur' })
|
||||||
|
|||||||
@ -140,6 +140,15 @@ export class UserService {
|
|||||||
return this.usersRepository.find({ where });
|
return this.usersRepository.find({ where });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Comptes refusés (à corriger) : liste pour reprise par le gestionnaire */
|
||||||
|
async findRefusedUsers(role?: RoleType): Promise<Users[]> {
|
||||||
|
const where: any = { statut: StatutUtilisateurType.REFUSE };
|
||||||
|
if (role) {
|
||||||
|
where.role = role;
|
||||||
|
}
|
||||||
|
return this.usersRepository.find({ where });
|
||||||
|
}
|
||||||
|
|
||||||
async findAll(): Promise<Users[]> {
|
async findAll(): Promise<Users[]> {
|
||||||
return this.usersRepository.find();
|
return this.usersRepository.find();
|
||||||
}
|
}
|
||||||
@ -214,7 +223,7 @@ export class UserService {
|
|||||||
return this.usersRepository.save(user);
|
return this.usersRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valider un compte utilisateur
|
// Valider un compte utilisateur (en_attente ou refuse -> actif)
|
||||||
async validateUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
|
async validateUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
|
||||||
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
|
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
|
||||||
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');
|
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');
|
||||||
@ -222,7 +231,11 @@ export class UserService {
|
|||||||
|
|
||||||
const user = await this.usersRepository.findOne({ where: { id: user_id } });
|
const user = await this.usersRepository.findOne({ where: { id: user_id } });
|
||||||
if (!user) throw new NotFoundException('Utilisateur introuvable');
|
if (!user) throw new NotFoundException('Utilisateur introuvable');
|
||||||
|
|
||||||
|
if (user.statut !== StatutUtilisateurType.EN_ATTENTE && user.statut !== StatutUtilisateurType.REFUSE) {
|
||||||
|
throw new BadRequestException('Seuls les comptes en attente ou refusés (à corriger) peuvent être validés.');
|
||||||
|
}
|
||||||
|
|
||||||
user.statut = StatutUtilisateurType.ACTIF;
|
user.statut = StatutUtilisateurType.ACTIF;
|
||||||
const savedUser = await this.usersRepository.save(user);
|
const savedUser = await this.usersRepository.save(user);
|
||||||
if (user.role === RoleType.PARENT) {
|
if (user.role === RoleType.PARENT) {
|
||||||
@ -270,6 +283,30 @@ export class UserService {
|
|||||||
await this.validationRepository.save(suspend);
|
await this.validationRepository.save(suspend);
|
||||||
return savedUser;
|
return savedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Refuser un compte (en_attente -> refuse) ; tracé dans validations */
|
||||||
|
async refuseUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
|
||||||
|
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
|
||||||
|
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');
|
||||||
|
}
|
||||||
|
const user = await this.usersRepository.findOne({ where: { id: user_id } });
|
||||||
|
if (!user) throw new NotFoundException('Utilisateur introuvable');
|
||||||
|
if (user.statut !== StatutUtilisateurType.EN_ATTENTE) {
|
||||||
|
throw new BadRequestException('Seul un compte en attente peut être refusé.');
|
||||||
|
}
|
||||||
|
user.statut = StatutUtilisateurType.REFUSE;
|
||||||
|
const savedUser = await this.usersRepository.save(user);
|
||||||
|
const validation = this.validationRepository.create({
|
||||||
|
user: savedUser,
|
||||||
|
type: 'refus_compte',
|
||||||
|
status: StatutValidationType.REFUSE,
|
||||||
|
validated_by: currentUser,
|
||||||
|
comment,
|
||||||
|
});
|
||||||
|
await this.validationRepository.save(validation);
|
||||||
|
return savedUser;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affecter ou modifier le numéro de dossier d'un utilisateur (parent ou AM).
|
* Affecter ou modifier le numéro de dossier d'un utilisateur (parent ou AM).
|
||||||
* Permet au gestionnaire/admin de rapprocher deux dossiers (même numéro pour plusieurs personnes).
|
* Permet au gestionnaire/admin de rapprocher deux dossiers (même numéro pour plusieurs personnes).
|
||||||
|
|||||||
@ -11,7 +11,7 @@ DO $$ BEGIN
|
|||||||
CREATE TYPE genre_type AS ENUM ('H', 'F');
|
CREATE TYPE genre_type AS ENUM ('H', 'F');
|
||||||
END IF;
|
END IF;
|
||||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_utilisateur_type') THEN
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_utilisateur_type') THEN
|
||||||
CREATE TYPE statut_utilisateur_type AS ENUM ('en_attente','actif','suspendu');
|
CREATE TYPE statut_utilisateur_type AS ENUM ('en_attente','actif','suspendu','refuse');
|
||||||
END IF;
|
END IF;
|
||||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_enfant_type') THEN
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_enfant_type') THEN
|
||||||
CREATE TYPE statut_enfant_type AS ENUM ('a_naitre','actif','scolarise');
|
CREATE TYPE statut_enfant_type AS ENUM ('a_naitre','actif','scolarise');
|
||||||
|
|||||||
4
database/migrations/2026_statut_utilisateur_refuse.sql
Normal file
4
database/migrations/2026_statut_utilisateur_refuse.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
-- Migration #105 : Statut utilisateur « refusé » (à corriger)
|
||||||
|
-- Ajout de la valeur 'refuse' à l'enum statut_utilisateur_type.
|
||||||
|
|
||||||
|
ALTER TYPE statut_utilisateur_type ADD VALUE IF NOT EXISTS 'refuse';
|
||||||
@ -15,9 +15,18 @@ if [ -z "$GITEA_TOKEN" ]; then
|
|||||||
GITEA_TOKEN=$(cat .gitea-token)
|
GITEA_TOKEN=$(cat .gitea-token)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [ -z "$GITEA_TOKEN" ] && [ -f ~/.bashrc ]; then
|
||||||
|
eval "$(grep '^export GITEA_TOKEN=' ~/.bashrc 2>/dev/null)" || true
|
||||||
|
fi
|
||||||
|
if [ -z "$GITEA_TOKEN" ] && [ -f docs/BRIEFING-FRONTEND.md ]; then
|
||||||
|
token_from_briefing=$(sed -n 's/.*Token: *\(giteabu_[a-f0-9]*\).*/\1/p' docs/BRIEFING-FRONTEND.md 2>/dev/null | head -1)
|
||||||
|
if [ -n "$token_from_briefing" ]; then
|
||||||
|
GITEA_TOKEN="$token_from_briefing"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$GITEA_TOKEN" ]; then
|
if [ -z "$GITEA_TOKEN" ]; then
|
||||||
echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea."
|
echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea (voir docs/PROCEDURE-API-GITEA.md)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user