Amélioration de la splash_page et du login

This commit is contained in:
d6soft
2025-06-04 16:51:40 +02:00
parent 8c9e9a21c4
commit bcfdbb2c8b
168 changed files with 153842 additions and 6183 deletions

View File

@@ -1,17 +1,19 @@
{
"window.zoomLevel": 1, // Permet de zoomer, pratique si vous faites une présentation
// Apparence
// -- Editeur
"workbench.startupEditor": "none", // On ne veut pas une page d'accueil chargée
"editor.minimap.enabled": false, // On veut voir la minimap
"editor.minimap.enabled": true, // On veut voir la minimap
"editor.minimap.showSlider": "always", // On veut voir la minimap
"editor.minimap.size": "fill", // On veut voir la minimap
"editor.minimap.scale": 2,
"editor.minimap.scale": 1,
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": ["storage.type.function", "storage.type.class"],
"scope": [
"storage.type.function",
"storage.type.class"
],
"settings": {
"fontStyle": "bold",
"foreground": "#4B9CD3"
@@ -27,7 +29,6 @@
"workbench.editor.tabSizing": "shrink", // On veut voir les tabs
"workbench.editor.pinnedTabSizing": "compact",
"workbench.editor.enablePreview": false, // Un clic sur un fichier l'ouvre
// -- Sidebar
"workbench.tree.indent": 15, // Indente plus pour plus de clarté dans la sidebar
"workbench.tree.renderIndentGuides": "always",
@@ -41,7 +42,6 @@
"editor.fontSize": 13,
"editor.lineHeight": 22,
"editor.guides.bracketPairs": "active",
// Ergonomie
"editor.wordWrap": "off",
"editor.rulers": [],
@@ -52,7 +52,6 @@
"editor.linkedEditing": true, // Quand on change un élément HTML, change la balise fermante
"editor.tabSize": 2,
"editor.unicodeHighlight.nonBasicASCII": false,
"[php]": {
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client",
"editor.formatOnSave": true,
@@ -60,7 +59,8 @@
},
"intelephense.format.braces": "k&r",
"intelephense.format.enable": true,
"php.validate.executablePath": "/opt/homebrew/opt/php@8.3/bin/php",
"php.executablePath": "/opt/homebrew/opt/php@8.3/bin/php",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
@@ -71,11 +71,22 @@
"prettier.singleQuote": true,
"prettier.tabWidth": 2,
"prettier.trailingComma": "es5",
"explorer.autoReveal": false,
"explorer.confirmDragAndDrop": false,
"emmet.triggerExpansionOnTab": true,
"emmet.includeLanguages": {
"javascript": "javascript",
"php": "php",
"svelte": "html",
"dart": "dart"
},
"problems.decorations.enabled": true,
"explorer.decorations.colors": true,
"explorer.decorations.badges": true,
"php.validate.enable": true,
"php.suggest.basic": false,
"dart.analysisExcludedFolders": [],
"dart.enableSdkFormatter": true,
// Fichiers
"files.defaultLanguage": "markdown",
"files.autoSaveWorkspaceFilesOnly": true,
@@ -85,40 +96,58 @@
// Languages
"javascript.preferences.importModuleSpecifierEnding": "js",
"typescript.preferences.importModuleSpecifierEnding": "js",
// Extensions
"tailwindCSS.experimental.configFile": "frontend/tailwind.config.js",
"tailwindCSS.experimental.configFile": "web/tailwind.config.js",
"editor.quickSuggestions": {
"strings": true
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode",
"editor.formatOnSave": true
},
"prettier.documentSelectors": ["**/*.svelte"],
"prettier.documentSelectors": [
"**/*.svelte"
],
"svelte.plugin.svelte.diagnostics.enable": false,
"problems.decorations.enabled": false,
"js/ts.implicitProjectConfig.checkJs": false,
"svelte.enable-ts-plugin": false,
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#ff6433",
"activityBar.background": "#ff6433",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#00ff3d",
"activityBarBadge.foreground": "#15202b",
"commandCenter.border": "#e7e7e799",
"sash.hoverBorder": "#ff6433",
"statusBar.background": "#ff3d00",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#ff6433",
"statusBarItem.remoteBackground": "#ff3d00",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#ff3d00",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#ff3d0099",
"titleBar.inactiveForeground": "#e7e7e799"
"cline.autoApproveLimit": 100,
"cline.autoApproveRequests": true,
"cline.enableMemoryBank": true,
"cline.includeSnippetsFromMemory": true,
"cline.contextLength": 10000,
"cline.autoFormat": true,
"cline.primaryDocumentationFile": ".cline",
"cline.gitIntegration": true,
"cline.projectStructure": {
"api": "php",
"app": "flutter",
"web": "svelte"
},
"peacock.color": "#ff3d00"
}
"cline.referenceFiles": {
"database": "docs/db-resalice.dump",
"apiEndpoints": "docs/api_endpoints.md",
"architecture": "docs/architecture.md"
},
"cline.databaseSchema": "docs/db-resalice.dump",
"peacock.color": "#dd0531",
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#fa1b49",
"activityBar.background": "#fa1b49",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#155e02",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#e7e7e799",
"sash.hoverBorder": "#fa1b49",
"statusBar.background": "#dd0531",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#fa1b49",
"statusBarItem.remoteBackground": "#dd0531",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#dd0531",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#dd053199",
"titleBar.inactiveForeground": "#e7e7e799"
}
}

View File

@@ -1,612 +0,0 @@
# API D6MON - Documentation
## Introduction
L'API D6MON est une interface RESTful permettant d'interagir avec l'application D6MON. Cette API gère l'authentification des utilisateurs, la gestion des profils utilisateurs et la gestion des entités.
## Configuration
### Base URL
```
https://app.d6mon.com/api/mon
```
### En-têtes requis
Pour toutes les requêtes à l'API, les en-têtes suivants sont requis :
```
Content-Type: application/json
X-App-Identifier: app.d6mon.com
X-Client-Type: mobile
```
Pour les endpoints protégés (nécessitant une authentification), ajoutez également :
```
Authorization: Bearer {token}
```
`{token}` est le jeton d'authentification obtenu lors de la connexion.
## Authentification
### Connexion
**Endpoint :** `POST /login`
**Corps de la requête :**
```json
{
"email": "utilisateur@exemple.com",
"password": "motdepasse"
}
```
**Réponse réussie :**
```json
{
"success": true,
"data": {
"token": "session_token_here",
"user": {
"id": 123,
"email": "utilisateur@exemple.com",
"last_name": "Nom",
"first_name": "Prénom",
"display_name": "Nom d'affichage",
"entity_id": 456
}
}
}
```
### Inscription
**Endpoint :** `POST /register`
**Corps de la requête :**
```json
{
"display_name": "Nom d'affichage",
"email": "utilisateur@exemple.com",
"first_name": "Prénom",
"last_name": "Nom",
"entity_id": 456
}
```
**Réponse réussie :**
```json
{
"success": true,
"message": "Inscription réussie. Un email contenant vos identifiants vous a été envoyé.",
"data": {
"user": {
"id": 123,
"email": "utilisateur@exemple.com",
"display_name": "Nom d'affichage"
}
}
}
```
### Mot de passe oublié
**Endpoint :** `POST /lost-password`
**Corps de la requête :**
```json
{
"email": "utilisateur@exemple.com"
}
```
**Réponse réussie :**
```json
{
"success": true,
"message": "Un nouveau mot de passe a été envoyé à votre adresse email."
}
```
### Déconnexion
**Endpoint :** `POST /logout`
**Réponse réussie :**
```json
{
"success": true,
"message": "Déconnecté avec succès"
}
```
## Gestion des utilisateurs
### Récupérer le profil de l'utilisateur connecté
**Endpoint :** `GET /user/profile`
**Réponse réussie :**
```json
{
"success": true,
"data": {
"id": 123,
"entity_id": 456,
"display_name": "Nom d'affichage",
"first_name": "Prénom",
"last_name": "Nom",
"avatar": "url_avatar",
"email": "utilisateur@exemple.com",
"phone": "+33612345678",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"seat_name": "Siège",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"connected_at": "2023-01-01T00:00:00Z",
"is_active": true,
"entity": {
"id": 456,
"name": "Nom de l'entité",
"email": "entite@exemple.com",
"phone": "+33123456789",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"is_active": true
}
}
}
```
### Mettre à jour le profil de l'utilisateur connecté
**Endpoint :** `PUT /user/profile`
**Corps de la requête :**
```json
{
"display_name": "Nouveau nom d'affichage",
"first_name": "Nouveau prénom",
"last_name": "Nouveau nom",
"phone": "+33612345678",
"address1": "Nouvelle adresse ligne 1",
"address2": "Nouvelle adresse ligne 2",
"code_postal": "75001",
"city": "Paris",
"country": "France",
"seat_name": "Nouveau siège"
}
```
**Réponse réussie :**
Même format que `GET /user/profile` avec les données mises à jour.
### Changer le mot de passe
**Endpoint :** `POST /user/change-password`
**Corps de la requête :**
```json
{
"current_password": "ancien_mot_de_passe",
"new_password": "nouveau_mot_de_passe"
}
```
**Réponse réussie :**
```json
{
"success": true,
"message": "Mot de passe changé avec succès"
}
```
### Récupérer un utilisateur par ID
**Endpoint :** `GET /user/{id}`
**Réponse réussie :**
```json
{
"success": true,
"data": {
"id": 123,
"entity_id": 456,
"display_name": "Nom d'affichage",
"first_name": "Prénom",
"last_name": "Nom",
"avatar": "url_avatar",
"email": "utilisateur@exemple.com",
"phone": "+33612345678",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"seat_name": "Siège",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"connected_at": "2023-01-01T00:00:00Z",
"is_active": true
}
}
```
### Récupérer la liste des utilisateurs
**Endpoint :** `GET /users`
**Paramètres de requête :**
- `page` (optionnel) : Numéro de page (défaut : 1)
- `limit` (optionnel) : Nombre d'éléments par page (défaut : 20)
- `entity_id` (optionnel) : Filtrer par ID d'entité
**Réponse réussie :**
```json
{
"success": true,
"data": {
"users": [
{
"id": 123,
"entity_id": 456,
"display_name": "Nom d'affichage",
"first_name": "Prénom",
"last_name": "Nom",
"avatar": "url_avatar",
"email": "utilisateur@exemple.com",
"address1": "Adresse ligne 1",
"city": "Paris",
"country": "France",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"connected_at": "2023-01-01T00:00:00Z",
"is_active": true
}
],
"pagination": {
"total": 100,
"page": 1,
"limit": 20,
"pages": 5
}
}
}
```
### Créer un nouvel utilisateur
**Endpoint :** `POST /user`
**Corps de la requête :**
```json
{
"display_name": "Nom d'affichage",
"email": "utilisateur@exemple.com",
"first_name": "Prénom",
"last_name": "Nom",
"entity_id": 456,
"phone": "+33612345678",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"seat_name": "Siège"
}
```
**Réponse réussie :**
```json
{
"success": true,
"message": "Utilisateur créé avec succès. Un email avec les identifiants a été envoyé.",
"data": {
"id": 123,
"display_name": "Nom d'affichage",
"email": "utilisateur@exemple.com"
}
}
```
### Désactiver un utilisateur
**Endpoint :** `DELETE /user/{id}`
**Réponse réussie :**
```json
{
"success": true,
"message": "Utilisateur désactivé avec succès"
}
```
## Gestion des entités
### Récupérer toutes les entités
**Endpoint :** `GET /entities`
**Paramètres de requête :**
- `page` (optionnel) : Numéro de page (défaut : 1)
- `limit` (optionnel) : Nombre d'éléments par page (défaut : 20)
- `search` (optionnel) : Terme de recherche
**Réponse réussie :**
```json
{
"success": true,
"data": {
"entities": [
{
"id": 456,
"name": "Nom de l'entité",
"email": "entite@exemple.com",
"phone": "+33123456789",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"is_active": true
}
],
"pagination": {
"total": 50,
"page": 1,
"limit": 20,
"pages": 3
}
}
}
```
### Récupérer une entité par ID
**Endpoint :** `GET /entity/{id}`
**Réponse réussie :**
```json
{
"success": true,
"data": {
"id": 456,
"name": "Nom de l'entité",
"email": "entite@exemple.com",
"phone": "+33123456789",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"is_active": true,
"users": [
{
"id": 123,
"display_name": "Nom d'affichage",
"first_name": "Prénom",
"last_name": "Nom",
"avatar": "url_avatar",
"email": "utilisateur@exemple.com",
"created_at": "2023-01-01T00:00:00Z",
"is_active": true
}
]
}
}
```
### Créer une nouvelle entité
**Endpoint :** `POST /entity`
**Corps de la requête :**
```json
{
"name": "Nom de l'entité",
"email": "entite@exemple.com",
"phone": "+33123456789",
"address1": "Adresse ligne 1",
"address2": "Adresse ligne 2",
"code_postal": "75000",
"city": "Paris",
"country": "France"
}
```
**Réponse réussie :**
```json
{
"success": true,
"message": "Entité créée avec succès",
"data": {
"id": 456,
"name": "Nom de l'entité"
}
}
```
### Mettre à jour une entité
**Endpoint :** `PUT /entity/{id}`
**Corps de la requête :**
```json
{
"name": "Nouveau nom de l'entité",
"email": "nouvelle-entite@exemple.com",
"phone": "+33987654321",
"address1": "Nouvelle adresse ligne 1",
"address2": "Nouvelle adresse ligne 2",
"code_postal": "75001",
"city": "Paris",
"country": "France"
}
```
**Réponse réussie :**
Même format que `GET /entity/{id}` avec les données mises à jour.
### Désactiver une entité
**Endpoint :** `DELETE /entity/{id}`
**Réponse réussie :**
```json
{
"success": true,
"message": "Entité désactivée avec succès"
}
```
### Récupérer les utilisateurs d'une entité
**Endpoint :** `GET /entity/{id}/users`
**Paramètres de requête :**
- `page` (optionnel) : Numéro de page (défaut : 1)
- `limit` (optionnel) : Nombre d'éléments par page (défaut : 20)
**Réponse réussie :**
```json
{
"success": true,
"data": {
"users": [
{
"id": 123,
"display_name": "Nom d'affichage",
"first_name": "Prénom",
"last_name": "Nom",
"avatar": "url_avatar",
"email": "utilisateur@exemple.com",
"phone": "+33612345678",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"connected_at": "2023-01-01T00:00:00Z",
"is_active": true
}
],
"pagination": {
"total": 25,
"page": 1,
"limit": 20,
"pages": 2
}
}
}
```
## Structure des données
### Table `users`
```sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
entity_id INT,
display_name VARCHAR(100) NOT NULL,
first_name VARCHAR(100),
encrypted_last_name VARCHAR(512),
avatar VARCHAR(255),
encrypted_email VARCHAR(512),
encrypted_phone VARCHAR(255),
address1 VARCHAR(255),
address2 VARCHAR(255),
code_postal VARCHAR(20),
city VARCHAR(100),
country VARCHAR(100),
seat_name VARCHAR(20),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
connected_at DATETIME,
is_active BOOLEAN DEFAULT TRUE,
FOREIGN KEY (entity_id) REFERENCES entities(id)
);
```
### Table `entities`
```sql
CREATE TABLE entities (
id INT AUTO_INCREMENT PRIMARY KEY,
encrypted_name VARCHAR(512) NOT NULL,
encrypted_email VARCHAR(512),
encrypted_phone VARCHAR(255),
address1 VARCHAR(255),
address2 VARCHAR(255),
code_postal VARCHAR(20),
city VARCHAR(100),
country VARCHAR(100),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT TRUE
);
```
## Sécurité
L'API utilise plusieurs mécanismes pour assurer la sécurité des données :
1. **Authentification par jeton** : Un jeton d'authentification est requis pour accéder aux endpoints protégés.
2. **Chiffrement des données sensibles** : Les données sensibles comme les noms, emails et numéros de téléphone sont chiffrées en base de données.
3. **Validation des entrées** : Toutes les entrées utilisateur sont validées avant traitement.
4. **Gestion des erreurs** : Les erreurs sont gérées de manière sécurisée sans divulguer d'informations sensibles.
## Codes d'erreur
- `400 Bad Request` : Requête invalide ou données manquantes
- `401 Unauthorized` : Authentification requise ou échouée
- `403 Forbidden` : Accès non autorisé à la ressource
- `404 Not Found` : Ressource non trouvée
- `409 Conflict` : Conflit avec l'état actuel de la ressource
- `500 Internal Server Error` : Erreur serveur
## Notes d'implémentation
- Les mots de passe sont hachés avec l'algorithme bcrypt.
- Les données sensibles sont chiffrées avec AES-256-CBC.
- Les emails sont envoyés pour les opérations importantes (inscription, réinitialisation de mot de passe).
- Les sessions sont gérées côté serveur avec un délai d'expiration.

View File