refactor: update authentication flow and cookie management

- Changed COOKIE_NAME from "peakSkills_userId" to "session_token" for better clarity.
- Updated AuthClient to handle login and registration with new data structures.
- Enhanced AuthWrapper to manage user sessions and display appropriate messages.
- Added error handling in LoginForm and RegisterForm for better user feedback.
- Refactored user service methods to streamline user creation and verification processes.
This commit is contained in:
Julien Froidefond
2025-08-25 16:19:31 +02:00
parent caf396d964
commit 5c71ce1a54
14 changed files with 537 additions and 91 deletions

View File

@@ -4,51 +4,9 @@ import { UserProfile } from "../lib/types";
export class UserService {
/**
* Crée ou met à jour un utilisateur et retourne son UUID
* Note: Cette méthode est pour la compatibilité avec l'ancien système
* Les nouveaux utilisateurs doivent utiliser createUser avec email/password
*/
async upsertUserUuid(profile: UserProfile): Promise<string> {
const pool = getPool();
const client = await pool.connect();
try {
// Créer un nouvel utilisateur avec UUID auto-généré
const insertQuery = `
INSERT INTO users (first_name, last_name, team_id, uuid_id)
VALUES ($1, $2, $3, uuid_generate_v4())
RETURNING uuid_id
`;
const result = await client.query(insertQuery, [
profile.firstName,
profile.lastName,
profile.teamId,
]);
return result.rows[0].uuid_id;
} catch (error: any) {
// Si erreur de contrainte unique, l'utilisateur existe déjà
if (
error.code === "23505" &&
error.constraint === "users_first_name_last_name_team_id_key"
) {
// Récupérer l'utilisateur existant
const existingUserQuery = `
SELECT uuid_id FROM users
WHERE first_name = $1 AND last_name = $2 AND team_id = $3
`;
const existingUser = await client.query(existingUserQuery, [
profile.firstName,
profile.lastName,
profile.teamId,
]);
return existingUser.rows[0].uuid_id;
}
throw error;
} finally {
client.release();
}
}
/**
* Met à jour un utilisateur existant par son UUID
@@ -314,6 +272,132 @@ export class UserService {
throw new Error("Failed to fetch users");
}
}
/**
* Récupère un utilisateur par son email
*/
async getUserByEmail(email: string): Promise<{
uuid_id: string;
first_name: string;
last_name: string;
email: string;
team_id: string;
} | null> {
const pool = getPool();
const client = await pool.connect();
try {
const query = `
SELECT uuid_id, first_name, last_name, email, team_id
FROM users
WHERE email = $1
`;
const result = await client.query(query, [email]);
if (result.rows.length === 0) {
return null;
}
return result.rows[0];
} finally {
client.release();
}
}
/**
* Crée un nouvel utilisateur avec email et mot de passe hashé
*/
async createUser(data: {
firstName: string;
lastName: string;
email: string;
passwordHash: string;
teamId: string;
}): Promise<{
uuid_id: string;
first_name: string;
last_name: string;
email: string;
team_id: string;
} | null> {
const pool = getPool();
const client = await pool.connect();
try {
const query = `
INSERT INTO users (first_name, last_name, email, password_hash, team_id, uuid_id)
VALUES ($1, $2, $3, $4, $5, uuid_generate_v4())
RETURNING uuid_id, first_name, last_name, email, team_id
`;
const result = await client.query(query, [
data.firstName,
data.lastName,
data.email,
data.passwordHash,
data.teamId,
]);
if (result.rows.length === 0) {
return null;
}
return result.rows[0];
} finally {
client.release();
}
}
/**
* Vérifie les identifiants de connexion
*/
async verifyCredentials(
email: string,
password: string
): Promise<{
uuid_id: string;
first_name: string;
last_name: string;
email: string;
team_id: string;
} | null> {
const pool = getPool();
const client = await pool.connect();
try {
const query = `
SELECT uuid_id, first_name, last_name, email, team_id, password_hash
FROM users
WHERE email = $1
`;
const result = await client.query(query, [email]);
if (result.rows.length === 0) {
return null;
}
const user = result.rows[0];
// Vérifier le mot de passe
const bcrypt = require("bcryptjs");
const isValidPassword = await bcrypt.compare(
password,
user.password_hash
);
if (!isValidPassword) {
return null;
}
// Retourner l'utilisateur sans le hash du mot de passe
const { password_hash, ...userWithoutPassword } = user;
return userWithoutPassword;
} finally {
client.release();
}
}
}
// Instance singleton