Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

Commit 5bb924a

Browse files
committed
Add OAuth token verification for Discord and Google in UserController
- Updated loginOAuth method to include accessToken in request body validation. - Implemented verifyDiscordToken and verifyGoogleToken methods to validate OAuth tokens. - Enhanced error handling for unsupported providers and token verification failures. - Ensured email and providerId match verified user data before proceeding with login.
1 parent ec2e6a4 commit 5bb924a

3 files changed

Lines changed: 139 additions & 22 deletions

File tree

dist/controllers/UserController.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ export declare class Users {
3737
transferCredits(req: AuthenticatedRequest, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
3838
checkVerificationKey(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
3939
changeRole(req: AuthenticatedRequest, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
40+
private verifyDiscordToken;
41+
private verifyGoogleToken;
4042
}

dist/controllers/UserController.js

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,27 +92,43 @@ let Users = class Users {
9292
}
9393
// --- AUTHENTIFICATION & INSCRIPTION ---
9494
async loginOAuth(req, res) {
95-
const { email, provider, providerId, username } = req.body;
96-
if (!email || !provider || !providerId) {
95+
const { email, provider, providerId, username, accessToken } = req.body;
96+
if (!email || !provider || !providerId || !accessToken) {
9797
await this.createLog(req, "loginOAuth", "users", 400);
98-
return this.sendError(res, 400, "Missing email, provider or providerId");
98+
return this.sendError(res, 400, "Missing email, provider, providerId or accessToken");
99+
}
100+
// Vérifier le token OAuth avec le provider
101+
let verifiedUser;
102+
try {
103+
if (provider === "discord") {
104+
verifiedUser = await this.verifyDiscordToken(accessToken, providerId);
105+
}
106+
else if (provider === "google") {
107+
verifiedUser = await this.verifyGoogleToken(accessToken, providerId);
108+
}
109+
else {
110+
await this.createLog(req, "loginOAuth", "users", 400);
111+
return this.sendError(res, 400, "Unsupported OAuth provider");
112+
}
113+
}
114+
catch (error) {
115+
await this.createLog(req, "loginOAuth", "users", 401);
116+
return this.sendError(res, 401, "Invalid OAuth token");
117+
}
118+
// Vérifier que l'email et l'ID correspondent aux données du provider
119+
if (verifiedUser.email !== email || verifiedUser.id !== providerId) {
120+
await this.createLog(req, "loginOAuth", "users", 401);
121+
return this.sendError(res, 401, "OAuth data mismatch");
99122
}
100123
const users = await this.userService.getAllUsersWithDisabled();
101-
// console.log(users);
102124
const token = req.headers["cookie"]?.toString().split("token=")[1]?.split(";")[0];
103-
// const authHeader =
104-
// req.headers["authorization"] ||
105-
// "Bearer " +
106-
// req.headers["cookie"]?.toString().split("token=")[1]?.split(";")[0];
107-
// const token = authHeader.split("Bearer ")[1];
108125
let user = await this.userService.authenticateUser(token);
109126
if (!user) {
110127
user = users.find((u) => u.discord_id == providerId || u.google_id == providerId) || null;
111128
}
112129
if (!user) {
113130
const userId = crypto_1.default.randomUUID();
114-
user = await this.userService.createUser(userId, username || "", email, null, provider, providerId);
115-
// await this.mailService.sendAccountConfirmationMail(user.email);
131+
user = await this.userService.createUser(userId, username || verifiedUser.username || "", email, null, provider, providerId);
116132
await this.createLog(req, "loginOAuth", "users", 201, userId);
117133
}
118134
else {
@@ -631,6 +647,45 @@ let Users = class Users {
631647
this.sendError(res, 500, "Error setting role cookie");
632648
}
633649
}
650+
// Ajouter ces méthodes de vérification OAuth
651+
async verifyDiscordToken(accessToken, expectedUserId) {
652+
try {
653+
const response = await fetch("https://discord.com/api/users/@me", {
654+
headers: {
655+
Authorization: `Bearer ${accessToken}`,
656+
},
657+
});
658+
if (!response.ok) {
659+
throw new Error("Invalid Discord token");
660+
}
661+
const userData = await response.json();
662+
return {
663+
id: userData.id,
664+
email: userData.email,
665+
username: userData.username,
666+
};
667+
}
668+
catch (error) {
669+
throw new Error("Failed to verify Discord token");
670+
}
671+
}
672+
async verifyGoogleToken(accessToken, expectedUserId) {
673+
try {
674+
const response = await fetch(`https://www.googleapis.com/oauth2/v2/userinfo?access_token=${accessToken}`);
675+
if (!response.ok) {
676+
throw new Error("Invalid Google token");
677+
}
678+
const userData = await response.json();
679+
return {
680+
id: userData.id,
681+
email: userData.email,
682+
username: userData.name,
683+
};
684+
}
685+
catch (error) {
686+
throw new Error("Failed to verify Google token");
687+
}
688+
}
634689
};
635690
exports.Users = Users;
636691
__decorate([

src/controllers/UserController.ts

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,36 @@ export class Users {
8787

8888
@httpPost("/login-oauth")
8989
public async loginOAuth(req: Request, res: Response) {
90-
const { email, provider, providerId, username } = req.body;
91-
if (!email || !provider || !providerId) {
90+
const { email, provider, providerId, username, accessToken } = req.body;
91+
if (!email || !provider || !providerId || !accessToken) {
9292
await this.createLog(req, "loginOAuth", "users", 400);
93-
return this.sendError(res, 400, "Missing email, provider or providerId");
93+
return this.sendError(res, 400, "Missing email, provider, providerId or accessToken");
94+
}
95+
96+
// Vérifier le token OAuth avec le provider
97+
let verifiedUser;
98+
try {
99+
if (provider === "discord") {
100+
verifiedUser = await this.verifyDiscordToken(accessToken, providerId);
101+
} else if (provider === "google") {
102+
verifiedUser = await this.verifyGoogleToken(accessToken, providerId);
103+
} else {
104+
await this.createLog(req, "loginOAuth", "users", 400);
105+
return this.sendError(res, 400, "Unsupported OAuth provider");
106+
}
107+
} catch (error) {
108+
await this.createLog(req, "loginOAuth", "users", 401);
109+
return this.sendError(res, 401, "Invalid OAuth token");
110+
}
111+
112+
// Vérifier que l'email et l'ID correspondent aux données du provider
113+
if (verifiedUser.email !== email || verifiedUser.id !== providerId) {
114+
await this.createLog(req, "loginOAuth", "users", 401);
115+
return this.sendError(res, 401, "OAuth data mismatch");
94116
}
95117

96118
const users = await this.userService.getAllUsersWithDisabled();
97-
// console.log(users);
98119
const token = req.headers["cookie"]?.toString().split("token=")[1]?.split(";")[0];
99-
// const authHeader =
100-
// req.headers["authorization"] ||
101-
// "Bearer " +
102-
// req.headers["cookie"]?.toString().split("token=")[1]?.split(";")[0];
103-
// const token = authHeader.split("Bearer ")[1];
104120

105121
let user = await this.userService.authenticateUser(token as string);
106122

@@ -110,8 +126,7 @@ export class Users {
110126

111127
if (!user) {
112128
const userId = crypto.randomUUID();
113-
user = await this.userService.createUser(userId, username || "", email, null, provider, providerId);
114-
// await this.mailService.sendAccountConfirmationMail(user.email);
129+
user = await this.userService.createUser(userId, username || verifiedUser.username || "", email, null, provider, providerId);
115130
await this.createLog(req, "loginOAuth", "users", 201, userId);
116131
} else {
117132
if ((provider === "discord" && !user.discord_id) || (provider === "google" && !user.google_id)) {
@@ -122,10 +137,12 @@ export class Users {
122137
return this.sendError(res, 401, "OAuth providerId mismatch");
123138
}
124139
}
140+
125141
if (user.disabled) {
126142
await this.createLog(req, "loginOAuth", "users", 403, user.user_id);
127143
return this.sendError(res, 403, "Account is disabled");
128144
}
145+
129146
await this.createLog(req, "loginOAuth", "users", 200, user.user_id);
130147
const apiKey = genKey(user.user_id);
131148
const jwtToken = generateUserJwt(user, apiKey);
@@ -746,4 +763,47 @@ export class Users {
746763
this.sendError(res, 500, "Error setting role cookie");
747764
}
748765
}
766+
767+
// Ajouter ces méthodes de vérification OAuth
768+
private async verifyDiscordToken(accessToken: string, expectedUserId: string) {
769+
try {
770+
const response = await fetch("https://discord.com/api/users/@me", {
771+
headers: {
772+
Authorization: `Bearer ${accessToken}`,
773+
},
774+
});
775+
776+
if (!response.ok) {
777+
throw new Error("Invalid Discord token");
778+
}
779+
780+
const userData = await response.json();
781+
return {
782+
id: userData.id,
783+
email: userData.email,
784+
username: userData.username,
785+
};
786+
} catch (error) {
787+
throw new Error("Failed to verify Discord token");
788+
}
789+
}
790+
791+
private async verifyGoogleToken(accessToken: string, expectedUserId: string) {
792+
try {
793+
const response = await fetch(`https://www.googleapis.com/oauth2/v2/userinfo?access_token=${accessToken}`);
794+
795+
if (!response.ok) {
796+
throw new Error("Invalid Google token");
797+
}
798+
799+
const userData = await response.json();
800+
return {
801+
id: userData.id,
802+
email: userData.email,
803+
username: userData.name,
804+
};
805+
} catch (error) {
806+
throw new Error("Failed to verify Google token");
807+
}
808+
}
749809
}

0 commit comments

Comments
 (0)