Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions actions/account.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,35 @@
"region": "Aube",
"codePostal": "10000"
}
},
{
"id": "newuser",
"password": "1234",
"role": "enseignant",
"prenom": "GoodName",
"nom": "GoodSurname",
"email": "email@valid.com",
"telephone": "0123456789",
"adresse": {
"rue": "Rue 1",
"ville": "City",
"region": "Region",
"codePostal": "10000"
}
},
{
"id": "prof3",
"password": "prof3",
"role": "enseignant",
"prenom": "pierre",
"nom": "paul",
"email": "abc@gmail.com",
"telephone": "11",
"adresse": {
"rue": "11",
"ville": "11",
"region": ":''\"#",
"codePostal": "/<>**?.\"\" Dupont//><*\"?:,;."
}
}
]
58 changes: 47 additions & 11 deletions actions/ajoutAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import path from "node:path";
import fs from "node:fs/promises";
import { colors } from '../utils/colors.js';

import { isValidName, isValidEmail, isValidPhone } from '../utils/validators.js';

export default async function ajoutAccount(rl = null) {
console.log("\n Ajout d'un compte : \n");

Expand All @@ -15,16 +17,50 @@ export default async function ajoutAccount(rl = null) {

try {
const jsonFile = path.join(process.cwd(), "actions", "account.json");
const data = await fs.readFile(jsonFile, "utf-8");
const accounts = JSON.parse(data);

let accounts = [];
try {
const data = await fs.readFile(jsonFile, "utf-8");
accounts = JSON.parse(data);
} catch (readErr) {
// Si le fichier n'existe pas, on part d'une liste vide (ou on pourrait gérer l'erreur autrement)
if (readErr.code !== 'ENOENT') {
throw readErr;
}
}

const id = await rl.question("Identifiant : ");
const password = await rl.question("Mot de passe : ");
const role = await demanderRole(rl);
const prenom = await rl.question("Prenom : ");
const nom = await rl.question("Nom : ");
const email = await rl.question("Email : ");
const telephone = await rl.question("Telephone : ");

let prenom;
while (true) {
prenom = await rl.question("Prenom : ");
if (isValidName(prenom)) break;
console.log(`${colors.red}Prénom invalide. Caractères interdits : < > * ? " / \\ : , ; .${colors.reset}`);
}

let nom;
while (true) {
nom = await rl.question("Nom : ");
if (isValidName(nom)) break;
console.log(`${colors.red}Nom invalide. Caractères interdits : < > * ? " / \\ : , ; .${colors.reset}`);
}

let email;
while (true) {
email = await rl.question("Email : ");
if (isValidEmail(email)) break;
console.log(`${colors.red}Email invalide. Format attendu : exemple@domaine.com${colors.reset}`);
}

let telephone;
while (true) {
telephone = await rl.question("Telephone : ");
if (isValidPhone(telephone)) break;
console.log(`${colors.red}Téléphone invalide. Utilisez uniquement des chiffres, espaces, +, -, (, ).${colors.reset}`);
}

const rue = await rl.question("Rue : ");
const ville = await rl.question("Ville : ");
const region = await rl.question("Region : ");
Expand Down Expand Up @@ -63,16 +99,16 @@ export default async function ajoutAccount(rl = null) {
}
}

async function demanderRole(rl){
while (true){
async function demanderRole(rl) {
while (true) {
const role = await rl.question(`Role 1 : enseignant / Rôle 2 : etudiant) :\n${colors.blue}(taper "1" si vous êtes enseignant, taper "2" si vous êtes étudiant)${colors.reset} `);
if (role === "1"){
if (role === "1") {
return "enseignant";
}
else if (role === "2"){
else if (role === "2") {
return "etudiant";
}
else{
else {
console.log(`${colors.red}Veuillez entrer un nombre valide. 1 pour enseignant | 2 pour étudiant.${colors.reset}`);
}
}
Expand Down
8 changes: 8 additions & 0 deletions actions/genererVCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fs from "node:fs/promises";
import vCardJS from "vcards-js";
import ajoutAccount from "./ajoutAccount.js";
import { colors } from '../utils/colors.js';
import { isValidName } from '../utils/validators.js';

export default async function genererVCard(rl = null) {
console.log("\n[actions] Génération d'un vCard...");
Expand Down Expand Up @@ -60,11 +61,18 @@ export default async function genererVCard(rl = null) {

if (!(index >= 0 && index < enseignants.length)) {
console.log(`${colors.red}Choix invalide.${colors.reset} Tapez 7 pour l'aide (enseignant) ou 3 pour l'aide (étudiant).`);
return;
}

const selected = enseignants[index];
console.log(`\n Enseignant choisi : ${selected.nom}, ${selected.prenom}`);

if (!isValidName(selected.nom) || !isValidName(selected.prenom)) {
console.error(`${colors.red}Erreur : Le nom ou prénom contient des caractères invalides pour un nom de fichier.${colors.reset}`);
console.error("Veuillez corriger les informations de ce compte dans account.json.");
return;
}

const v = vCardJS();
v.version = "4.0";
v.firstName = selected.prenom;
Expand Down
38 changes: 38 additions & 0 deletions utils/validators.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

/**
* Vérifie si le nom/prénom est valide.
* Pas de caractères spéciaux : < > * ? " / \ : , ; .
* @param {string} name
* @returns {boolean}
*/
export function isValidName(name) {
if (!name || name.trim() === '') return false;
// Regex : Ne contient aucun des caractères interdits
// On interdit aussi \ (backslash) car problématique pour les fichiers aussi sur Windows
const forbidden = /[<>*?"/\\:,;.]/;
return !forbidden.test(name);
}

/**
* Vérifie si l'email est valide (format standard).
* @param {string} email
* @returns {boolean}
*/
export function isValidEmail(email) {
// Regex simple pour email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

/**
* Vérifie si le numéro de téléphone est valide.
* Chiffres, +, -, (, ), espaces autorisés.
* @param {string} phone
* @returns {boolean}
*/
export function isValidPhone(phone) {
if (!phone || phone.trim() === '') return false;
// Doit contenir au moins un chiffre, et seulement des caractères autorisés
const phoneRegex = /^[0-9+\-()\s]+$/;
return phoneRegex.test(phone) && /\d/.test(phone);
}
10 changes: 10 additions & 0 deletions vcards/pierre_paul.vcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN:VCARD
VERSION:4.0
FN:pierre paul
N:paul;pierre;;;
EMAIL;type=HOME:abc@gmail.com
TEL;VALUE=uri;TYPE="voice,cell":tel:11
ADR;TYPE=HOME:;;11;11;;/<>**?."" Dupont//><*"?:\,\;.;:''"#
ROLE:enseignant
REV:2026-01-08T13:43:09.904Z
END:VCARD