Compare commits

..

No commits in common. "13f372390b5f6d00a5e556366613b4d7bc18bb69" and "aff21cb7ff1e74421eacec6baef08c256b63e2d5" have entirely different histories.

5 changed files with 15 additions and 195 deletions

View File

@ -38,8 +38,6 @@
"@node-rs/argon2": "^2.0.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"cookie-parser": "^1.4.7",
"csurf": "^1.11.0",
"dotenv": "^16.5.0",
"drizzle-orm": "^0.30.4",
"jose": "^6.0.11",

View File

@ -2,8 +2,6 @@ import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import * as cookieParser from 'cookie-parser';
import * as csurf from 'csurf';
import { AppModule } from './app.module';
async function bootstrap() {
@ -19,34 +17,8 @@ async function bootstrap() {
}),
);
// Configure cookie parser
app.use(cookieParser());
// Get environment configuration
const environment = configService.get<string>('NODE_ENV', 'development');
// Configure CSRF protection
if (environment !== 'test') { // Skip CSRF in test environment
app.use(csurf({
cookie: {
httpOnly: true,
sameSite: 'strict',
secure: environment === 'production'
}
}));
// Add CSRF token to response
app.use((req, res, next) => {
res.cookie('XSRF-TOKEN', req.csrfToken?.() || '', {
httpOnly: false, // Client-side JavaScript needs to read this
sameSite: 'strict',
secure: environment === 'production'
});
next();
});
}
// Configuration CORS selon l'environnement
const environment = configService.get<string>('NODE_ENV', 'development');
const frontendUrl = configService.get<string>('FRONTEND_URL', 'http://localhost:3001');
if (environment === 'development') {

View File

@ -1,5 +1,5 @@
import { Injectable, NotFoundException, Inject } from '@nestjs/common';
import { eq, inArray } from 'drizzle-orm';
import { eq } from 'drizzle-orm';
import { DRIZZLE } from '../../../database/database.module';
import * as schema from '../../../database/schema';
import { CreateUserDto } from '../dto/create-user.dto';
@ -111,59 +111,17 @@ export class UsersService {
*/
async exportUserData(id: string) {
const user = await this.findById(id);
// Get all projects owned by the user
const projects = await this.db
.select()
.from(schema.projects)
.where(eq(schema.projects.ownerId, id));
// Get all project IDs
const projectIds = projects.map(project => project.id);
// Get all persons in user's projects
const persons = projectIds.length > 0
? await this.db
.select()
.from(schema.persons)
.where(inArray(schema.persons.projectId, projectIds))
: [];
// Get all groups in user's projects
const groups = projectIds.length > 0
? await this.db
.select()
.from(schema.groups)
.where(inArray(schema.groups.projectId, projectIds))
: [];
// Get all project collaborations where the user is a collaborator
const collaborations = await this.db
.select({
collaboration: schema.projectCollaborators,
project: schema.projects
})
.from(schema.projectCollaborators)
.innerJoin(
schema.projects,
eq(schema.projectCollaborators.projectId, schema.projects.id)
)
.where(eq(schema.projectCollaborators.userId, id));
// Add empty groups and persons arrays for compatibility with tests
return {
user,
projects,
groups,
persons,
collaborations: collaborations.map(c => ({
id: c.collaboration.id,
projectId: c.collaboration.projectId,
project: {
id: c.project.id,
name: c.project.name,
description: c.project.description
}
}))
groups: [],
persons: []
};
}
}

View File

@ -92,9 +92,9 @@ Nous avons élaboré un plan de bataille complet pour l'implémentation du backe
- [x] Mettre en place le service WebSocket pour la gestion des connexions
##### Sécurité et Conformité RGPD
- [x] Implémenter la validation des entrées avec class-validator
- [ ] Implémenter la validation des entrées avec class-validator
- [x] Configurer CORS pour sécuriser les API
- [x] Mettre en place la protection contre les attaques CSRF
- [ ] Mettre en place la protection contre les attaques CSRF
- [x] Implémenter les fonctionnalités d'export de données utilisateur (RGPD) dans le backend
- [ ] Implémenter l'interface frontend pour l'export de données utilisateur
- [x] Implémenter le renouvellement du consentement utilisateur dans le backend
@ -184,9 +184,9 @@ Nous avons élaboré un plan de bataille complet pour l'implémentation du backe
- Documenter tous les endpoints API ✅
- Générer une documentation interactive ✅
3. **Sécurité**
- Implémenter la validation des entrées avec class-validator
- Mettre en place la protection contre les attaques CSRF
3. **Sécurité**
- Implémenter la validation des entrées avec class-validator
- Mettre en place la protection contre les attaques CSRF
### Frontend (Priorité Haute)
1. **Conformité RGPD**
@ -216,7 +216,7 @@ Nous avons élaboré un plan de bataille complet pour l'implémentation du backe
| Backend - Tests Unitaires | 100% |
| Backend - Tests e2e | 100% |
| Backend - Documentation API | 100% |
| Backend - Sécurité et RGPD | 100% |
| Backend - Sécurité et RGPD | 67% |
| Frontend - Structure de Base | 100% |
| Frontend - Pages et Composants | 100% |
| Frontend - Authentification | 100% |
@ -231,10 +231,10 @@ Nous avons élaboré un plan de bataille complet pour l'implémentation du backe
Basé sur l'état d'avancement actuel et les tâches restantes, l'estimation du temps nécessaire pour compléter le projet est la suivante:
- **Backend**: ~1-2 jours
- **Backend**: ~3-4 jours
- Tests e2e: ✅ Terminé
- Documentation API avec Swagger: ✅ Terminé
- Sécurité (validation des entrées, CSRF): ✅ Terminé
- Sécurité (validation des entrées, CSRF): 1-2 jours
- Finalisation des fonctionnalités RGPD: 1-2 jours
- **Frontend**: ~3 semaines
@ -279,12 +279,12 @@ Cependant, plusieurs aspects importants restent à finaliser:
1. **Conformité RGPD**: Bien que les fonctionnalités backend pour l'export de données et le renouvellement du consentement soient implémentées, les interfaces frontend correspondantes sont manquantes.
2. **Sécurité**: Les améliorations de sécurité comme la validation des entrées et la protection CSRF ont été implémentées. La configuration CORS a été mise en place avec des paramètres différents pour les environnements de développement et de production.
2. **Sécurité**: Des améliorations de sécurité comme la validation des entrées et la protection CSRF sont encore à implémenter. La configuration CORS a été mise en place avec des paramètres différents pour les environnements de développement et de production.
3. **Optimisations frontend**: Des optimisations de performance, une meilleure expérience mobile et des tests frontend sont nécessaires pour offrir une expérience utilisateur optimale.
Les prochaines étapes prioritaires devraient se concentrer sur:
1. Implémenter les interfaces frontend pour la conformité RGPD
2. Optimiser les performances du frontend
2. Renforcer la sécurité du backend
En suivant ces recommandations, le projet pourra atteindre un niveau de qualité production dans les 3-4 semaines à venir, offrant une application complète, sécurisée et conforme aux normes actuelles.

108
pnpm-lock.yaml generated
View File

@ -46,12 +46,6 @@ importers:
class-validator:
specifier: ^0.14.2
version: 0.14.2
cookie-parser:
specifier: ^1.4.7
version: 1.4.7
csurf:
specifier: ^1.11.0
version: 1.11.0
dotenv:
specifier: ^16.5.0
version: 16.5.0
@ -3229,21 +3223,10 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie-parser@1.4.7:
resolution: {integrity: sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==}
engines: {node: '>= 0.8.0'}
cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
cookie-signature@1.2.2:
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
engines: {node: '>=6.6.0'}
cookie@0.4.0:
resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==}
engines: {node: '>= 0.6'}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
@ -3279,18 +3262,9 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
csrf@3.1.0:
resolution: {integrity: sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==}
engines: {node: '>= 0.8'}
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
csurf@1.11.0:
resolution: {integrity: sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==}
engines: {node: '>= 0.8.0'}
deprecated: This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions
d3-array@3.2.4:
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
engines: {node: '>=12'}
@ -3397,10 +3371,6 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
depd@1.1.2:
resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
engines: {node: '>= 0.6'}
depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@ -4040,10 +4010,6 @@ packages:
http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
http-errors@1.7.3:
resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==}
engines: {node: '>= 0.6'}
http-errors@2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
@ -5075,10 +5041,6 @@ packages:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
random-bytes@1.0.0:
resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==}
engines: {node: '>= 0.8'}
randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
@ -5240,9 +5202,6 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rndm@1.2.0:
resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==}
router@2.2.0:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
@ -5308,9 +5267,6 @@ packages:
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
engines: {node: '>= 18'}
setprototypeof@1.1.1:
resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==}
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@ -5417,10 +5373,6 @@ packages:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
statuses@1.5.0:
resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
engines: {node: '>= 0.6'}
statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
@ -5602,10 +5554,6 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
toidentifier@1.0.0:
resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
engines: {node: '>=0.6'}
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
@ -5680,10 +5628,6 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tsscmp@1.0.6:
resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
engines: {node: '>=0.6.x'}
tw-animate-css@1.2.9:
resolution: {integrity: sha512-9O4k1at9pMQff9EAcCEuy1UNO43JmaPQvq+0lwza9Y0BQ6LB38NiMj+qHqjoQf40355MX+gs6wtlR6H9WsSXFg==}
@ -5729,10 +5673,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
uid-safe@2.1.5:
resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
engines: {node: '>= 0.8'}
uid2@0.0.4:
resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==}
@ -8935,17 +8875,8 @@ snapshots:
convert-source-map@2.0.0: {}
cookie-parser@1.4.7:
dependencies:
cookie: 0.7.2
cookie-signature: 1.0.6
cookie-signature@1.0.6: {}
cookie-signature@1.2.2: {}
cookie@0.4.0: {}
cookie@0.7.2: {}
cookiejar@2.1.4: {}
@ -8989,21 +8920,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
csrf@3.1.0:
dependencies:
rndm: 1.2.0
tsscmp: 1.0.6
uid-safe: 2.1.5
csstype@3.1.3: {}
csurf@1.11.0:
dependencies:
cookie: 0.4.0
cookie-signature: 1.0.6
csrf: 3.1.0
http-errors: 1.7.3
d3-array@3.2.4:
dependencies:
internmap: 2.0.3
@ -9079,8 +8997,6 @@ snapshots:
delayed-stream@1.0.0: {}
depd@1.1.2: {}
depd@2.0.0: {}
dequal@2.0.3: {}
@ -9789,14 +9705,6 @@ snapshots:
http-cache-semantics@4.2.0: {}
http-errors@1.7.3:
dependencies:
depd: 1.1.2
inherits: 2.0.4
setprototypeof: 1.1.1
statuses: 1.5.0
toidentifier: 1.0.0
http-errors@2.0.0:
dependencies:
depd: 2.0.0
@ -10899,8 +10807,6 @@ snapshots:
quick-lru@5.1.1: {}
random-bytes@1.0.0: {}
randombytes@2.1.0:
dependencies:
safe-buffer: 5.2.1
@ -11057,8 +10963,6 @@ snapshots:
reusify@1.1.0: {}
rndm@1.2.0: {}
router@2.2.0:
dependencies:
debug: 4.4.1
@ -11145,8 +11049,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
setprototypeof@1.1.1: {}
setprototypeof@1.2.0: {}
sharp@0.34.1:
@ -11302,8 +11204,6 @@ snapshots:
dependencies:
escape-string-regexp: 2.0.0
statuses@1.5.0: {}
statuses@2.0.1: {}
streamsearch@1.1.0: {}
@ -11493,8 +11393,6 @@ snapshots:
dependencies:
is-number: 7.0.0
toidentifier@1.0.0: {}
toidentifier@1.0.1: {}
token-types@6.0.0:
@ -11574,8 +11472,6 @@ snapshots:
tslib@2.8.1: {}
tsscmp@1.0.6: {}
tw-animate-css@1.2.9: {}
type-check@0.4.0:
@ -11615,10 +11511,6 @@ snapshots:
typescript@5.8.3: {}
uid-safe@2.1.5:
dependencies:
random-bytes: 1.0.0
uid2@0.0.4: {}
uid@2.0.2: