Files
sell/middlelayer/auth/userService.ts

141 lines
3.1 KiB
TypeScript

import type {
User,
UserRole,
LoginCredentials,
RegisterData,
} from "../types/user.js";
import { hashPassword, comparePassword } from "./password.js";
import { createToken, verifyToken } from "./jwt.js";
import { logger } from "../monitoring/logger.js";
/**
* Mock User Store (später durch Datenbank ersetzen)
*/
const users = new Map<string, User & { passwordHash: string }>();
/**
* User Service für Authentication
*/
export class UserService {
/**
* Registriert einen neuen User
*/
async register(
data: RegisterData,
role: UserRole = "customer"
): Promise<{
user: User;
token: string;
}> {
// Prüfe ob User bereits existiert
const existingUser = Array.from(users.values()).find(
(u) => u.email === data.email
);
if (existingUser) {
throw new Error("User mit dieser E-Mail existiert bereits");
}
// Hashe Passwort
const passwordHash = await hashPassword(data.password);
// Erstelle User
const user: User = {
id: `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
email: data.email,
name: data.name,
role,
createdAt: new Date(),
};
// Speichere User
users.set(user.id, { ...user, passwordHash });
// Erstelle Token
const token = createToken({
userId: user.id,
email: user.email,
role: user.role,
});
logger.info("User registered", { userId: user.id, email: user.email });
return { user, token };
}
/**
* Login eines Users
*/
async login(credentials: LoginCredentials): Promise<{
user: User;
token: string;
}> {
// Finde User
const userEntry = Array.from(users.values()).find(
(u) => u.email === credentials.email
);
if (!userEntry) {
throw new Error("Ungültige E-Mail oder Passwort");
}
// Vergleiche Passwort
const isValid = await comparePassword(
credentials.password,
userEntry.passwordHash
);
if (!isValid) {
throw new Error("Ungültige E-Mail oder Passwort");
}
// Erstelle User-Objekt ohne Passwort
const user: User = {
id: userEntry.id,
email: userEntry.email,
name: userEntry.name,
role: userEntry.role,
createdAt: userEntry.createdAt,
};
// Erstelle Token
const token = createToken({
userId: user.id,
email: user.email,
role: user.role,
});
logger.info("User logged in", { userId: user.id, email: user.email });
return { user, token };
}
/**
* Holt User anhand der ID
*/
async getUserById(userId: string): Promise<User | null> {
const userEntry = users.get(userId);
if (!userEntry) return null;
return {
id: userEntry.id,
email: userEntry.email,
name: userEntry.name,
role: userEntry.role,
createdAt: userEntry.createdAt,
};
}
/**
* Holt User anhand des Tokens
*/
async getUserFromToken(token: string): Promise<User | null> {
const payload = verifyToken(token);
if (!payload) return null;
return this.getUserById(payload.userId);
}
}
// Singleton-Instanz
export const userService = new UserService();