Skip to content
This repository was archived by the owner on Dec 12, 2025. It is now read-only.

Commit 901b48a

Browse files
committed
feat: Implement user ID encryption and caching in UserService
- Added `apiKeyUserCache` to cache users by their API keys in UserService. - Modified UserService constructor to populate the cache with users from the database. - Introduced `encryptUserId` and `decryptUserId` functions for secure user ID handling. - Updated `authenticateUser` method to utilize the new decryption logic for API keys. - Refactored user fetching methods to improve readability and maintainability.
1 parent 0dfe3af commit 901b48a

File tree

6 files changed

+603
-543
lines changed

6 files changed

+603
-543
lines changed

dist/services/UserService.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface IUserService {
3838
}
3939
export declare class UserService implements IUserService {
4040
private databaseService;
41+
private apiKeyUserCache;
4142
constructor(databaseService: IDatabaseService);
4243
private static getIdWhereClause;
4344
private fetchUserByAnyId;

dist/services/UserService.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ function slugify(str) {
6060
let UserService = UserService_1 = class UserService {
6161
constructor(databaseService) {
6262
this.databaseService = databaseService;
63+
this.apiKeyUserCache = new Map();
64+
this.getAllUsersWithDisabled().then((users) => {
65+
for (const user of users) {
66+
const key = (0, GenKey_1.genKey)(user.user_id);
67+
this.apiKeyUserCache.set(key, user);
68+
}
69+
});
6370
}
6471
static getIdWhereClause(includeDisabled = false) {
6572
const base = "(user_id = ? OR discord_id = ? OR google_id = ? OR steam_id = ?)";
@@ -208,26 +215,21 @@ let UserService = UserService_1 = class UserService {
208215
return token;
209216
}
210217
async deleteUser(user_id) {
211-
await this.databaseService.request("DELETE FROM users WHERE user_id = ?", [user_id]);
218+
await this.databaseService.request("DELETE FROM users WHERE user_id = ?", [
219+
user_id,
220+
]);
212221
}
213222
async authenticateUser(tokenOrApiKey) {
214-
// Essaye de décoder comme JWT
215223
const jwtPayload = (0, Jwt_1.verifyUserJwt)(tokenOrApiKey);
216-
let apiKey = tokenOrApiKey;
217224
if (jwtPayload && jwtPayload.apiKey) {
218-
apiKey = jwtPayload.apiKey;
225+
return this.getUser(jwtPayload.user_id);
219226
}
220-
// Recherche l'utilisateur par apiKey (clé API)
221-
const users = await this.getAllUsersWithDisabled();
222-
if (!users) {
223-
console.error("Error fetching users", users);
227+
const apiKey = tokenOrApiKey;
228+
// Déchiffre l'user_id depuis la clé API
229+
const userId = (0, GenKey_1.decryptUserId)(apiKey);
230+
if (!userId)
224231
return null;
225-
}
226-
const user = users.find((user) => (0, GenKey_1.genKey)(user.user_id) === apiKey) || null;
227-
if (!user) {
228-
return null;
229-
}
230-
return user;
232+
return this.getUser(userId);
231233
}
232234
async updateWebauthnChallenge(user_id, challenge) {
233235
await this.databaseService.request("UPDATE users SET webauthn_challenge = ? WHERE user_id = ?", [challenge, user_id]);
@@ -377,7 +379,7 @@ let UserService = UserService_1 = class UserService {
377379
isStudio: user.isStudio,
378380
admin: user.admin,
379381
beta_user: user.beta_user,
380-
badges: user.badges
382+
badges: user.badges,
381383
};
382384
return publicProfile;
383385
}
@@ -393,7 +395,7 @@ let UserService = UserService_1 = class UserService {
393395
admin: user.admin,
394396
beta_user: user.beta_user,
395397
badges: user.badges,
396-
disabled: user.disabled
398+
disabled: user.disabled,
397399
};
398400
return publicProfile;
399401
}

dist/utils/GenKey.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
export declare function encryptUserId(userId: string): string;
2+
export declare function decryptUserId(apiKey: string): string | null;
13
export declare function genKey(userId: string): string;
24
export declare function genVerificationKey(userId: string): string;

dist/utils/GenKey.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,39 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
return (mod && mod.__esModule) ? mod : { "default": mod };
44
};
55
Object.defineProperty(exports, "__esModule", { value: true });
6-
exports.genVerificationKey = exports.genKey = void 0;
6+
exports.genVerificationKey = exports.genKey = exports.decryptUserId = exports.encryptUserId = void 0;
77
const crypto_1 = __importDefault(require("crypto"));
88
const dotenv_1 = __importDefault(require("dotenv"));
99
const path_1 = __importDefault(require("path"));
1010
dotenv_1.default.config({ path: path_1.default.join(__dirname, "..", ".env") });
11+
const ALGO = "aes-256-cbc";
12+
const IV_LENGTH = 16;
13+
function encryptUserId(userId) {
14+
const SECRET = process.env.HASH_SECRET;
15+
const iv = crypto_1.default.randomBytes(IV_LENGTH);
16+
const key = crypto_1.default.createHash("sha256").update(SECRET).digest(); // 32 bytes
17+
const cipher = crypto_1.default.createCipheriv(ALGO, key, iv);
18+
let encrypted = cipher.update(userId, "utf8", "hex");
19+
encrypted += cipher.final("hex");
20+
return iv.toString("hex") + ":" + encrypted;
21+
}
22+
exports.encryptUserId = encryptUserId;
23+
function decryptUserId(apiKey) {
24+
try {
25+
const SECRET = process.env.HASH_SECRET;
26+
const [ivHex, encrypted] = apiKey.split(":");
27+
const iv = Buffer.from(ivHex, "hex");
28+
const key = crypto_1.default.createHash("sha256").update(SECRET).digest(); // 32 bytes
29+
const decipher = crypto_1.default.createDecipheriv(ALGO, key, iv);
30+
let decrypted = decipher.update(encrypted, "hex", "utf8");
31+
decrypted += decipher.final("utf8");
32+
return decrypted;
33+
}
34+
catch {
35+
return null;
36+
}
37+
}
38+
exports.decryptUserId = decryptUserId;
1139
function createHash(userId, secret) {
1240
if (!userId)
1341
throw new Error("userId is required for key generation");
@@ -19,7 +47,9 @@ function createHash(userId, secret) {
1947
.digest("hex");
2048
}
2149
function genKey(userId) {
22-
return createHash(userId, process.env.HASH_SECRET);
50+
// return createHash(userId, process.env.HASH_SECRET);
51+
const encryptedUserId = encryptUserId(userId);
52+
return encryptedUserId;
2353
}
2454
exports.genKey = genKey;
2555
function genVerificationKey(userId) {

0 commit comments

Comments
 (0)