Skip to content

Commit 3df84f7

Browse files
feat: google auth
1 parent 54e68da commit 3df84f7

File tree

3 files changed

+225
-140
lines changed

3 files changed

+225
-140
lines changed

package.json

Lines changed: 134 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,136 @@
11
{
2-
"name": "sudobot",
3-
"version": "9.0.0-alpha.1",
4-
"description": "A Discord bot for moderation purposes.",
5-
"author": {
6-
"name": "Ar Rakin",
7-
"email": "[email protected]",
8-
"url": "https://virtual-designer.github.io"
9-
},
10-
"main": "build/index.js",
11-
"license": "AGPL-3.0-or-later",
12-
"keywords": [
13-
"bot",
14-
"discord-bot",
15-
"moderation",
16-
"automoderation",
17-
"discord-moderation",
18-
"discord-moderation-bot",
19-
"discord-automoderation",
20-
"discord-automoderation-bot"
21-
],
22-
"homepage": "https://github.com/onesoft-sudo/sudobot",
23-
"icon": "https://res.cloudinary.com/rakinar2/image/upload/v1659628446/SudoBot-new_cvwphw.png",
24-
"readme": "https://github.com/onesoft-sudo/sudobot#readme",
25-
"repository": {
26-
"type": "git",
27-
"url": "https://github.com/onesoft-sudo/sudobot"
28-
},
29-
"bugs": {
30-
"url": "https://github.com/onesoft-sudo/sudobot/issues",
31-
"email": "[email protected]"
32-
},
33-
"_meta": {
34-
"release_codename": "Chocolate Cake",
35-
"release_short_codename": "Cake"
36-
},
37-
"scripts": {
38-
"start": "node build/out/main/typescript/index.js",
39-
"start:bun": "bun --tsconfig-override=tsconfig.bun.json src/bun.ts",
40-
"prepare": "husky && rm -f node_modules/blazebuild && ln -s $(pwd)/blazebuild $(pwd)/node_modules/blazebuild",
41-
"dev": "bun run src/main/typescript/bun.ts",
42-
"start:blazew": "node build/out/main/typescript/index.js",
43-
"lint": "eslint src",
44-
"lint:fix": "eslint src --fix",
45-
"build": "tsc && mv build/out/src _build && rm -fr build/out && mv _build build/out",
46-
"start:prod": "pm2 start ./ecosystem.config.js",
47-
"deploy": "node scripts/deploy-commands.js",
48-
"gen:schema": "node scripts/generate-config-schema.js",
49-
"clean": "rm -frv build tsconfig.tsbuildinfo; make clean",
50-
"test": "vitest"
51-
},
52-
"_moduleAliases": {
53-
"@sudobot": "build/out",
54-
"@framework": "build/out/framework/typescript",
55-
"@main": "build/out/main/typescript",
56-
"@root": "."
57-
},
58-
"trustedDependencies": [
59-
"@prisma/client",
60-
"@prisma/engines",
61-
"@tensorflow/tfjs-node",
62-
"bcrypt",
63-
"core-js",
64-
"esbuild",
65-
"prisma",
66-
"sharp",
67-
"tesseract.js"
68-
],
69-
"dependencies": {
70-
"@prisma/client": "^5.11.0",
71-
"@tensorflow/tfjs-node": "^4.17.0",
72-
"archiver": "^7.0.1",
73-
"ascii-table3": "^0.8.2",
74-
"axios": "^1.6.7",
75-
"bcrypt": "^5.1.1",
76-
"chalk": "^4.1.2",
77-
"cors": "^2.8.5",
78-
"date-fns": "^2.30.0",
79-
"deepmerge": "^4.3.1",
80-
"discord.js": "^14.15.2",
81-
"dot-object": "^2.1.4",
82-
"dotenv": "^16.3.1",
83-
"express": "^4.18.2",
84-
"express-rate-limit": "^6.9.0",
85-
"figlet": "^1.7.0",
86-
"glob": "^10.4.1",
87-
"googleapis": "^126.0.1",
88-
"jpeg-js": "^0.4.4",
89-
"json5": "^2.2.3",
90-
"jsonwebtoken": "^9.0.1",
91-
"module-alias": "^2.2.3",
92-
"nsfwjs": "^3.0.0",
93-
"pm2": "^5.3.1",
94-
"reflect-metadata": "^0.1.13",
95-
"semver": "^7.5.4",
96-
"sharp": "^0.33.2",
97-
"socket.io": "^4.7.2",
98-
"tar": "^6.2.1",
99-
"tesseract.js": "^5.0.4",
100-
"tslib": "^2.6.2",
101-
"undici": "^5.23.0",
102-
"uuid": "^9.0.0",
103-
"zod": "^3.21.4"
104-
},
105-
"devDependencies": {
106-
"@commitlint/cli": "^17.6.6",
107-
"@commitlint/config-conventional": "^17.6.6",
108-
"@faker-js/faker": "^8.4.1",
109-
"@onesoftnet/pm2-config": "^0.0.7",
110-
"@types/archiver": "^6.0.2",
111-
"@types/bcrypt": "^5.0.0",
112-
"@types/bun": "latest",
113-
"@types/cors": "^2.8.13",
114-
"@types/dot-object": "^2.1.2",
115-
"@types/express": "^4.17.17",
116-
"@types/figlet": "^1.5.8",
117-
"@types/glob": "^8.1.0",
118-
"@types/jsonwebtoken": "^9.0.2",
119-
"@types/module-alias": "^2.0.2",
120-
"@types/node": "^20.4.0",
121-
"@types/semver": "^7.5.4",
122-
"@types/tar": "^6.1.11",
123-
"@types/uuid": "^9.0.2",
124-
"@typescript-eslint/eslint-plugin": "^7.7.0",
125-
"@typescript-eslint/parser": "^7.7.0",
126-
"@vitest/coverage-v8": "^1.3.1",
127-
"eslint": "^8.57.0",
128-
"husky": "latest",
129-
"prettier": "^3.2.5",
130-
"prisma": "^5.11.0",
131-
"typescript": "^5.4.3",
132-
"typescript-eslint": "^7.7.0",
133-
"vitest": "^1.3.1",
134-
"zod-to-json-schema": "^3.22.5"
135-
},
136-
"optionalDependencies": {
137-
"openai": "^4.26.0"
138-
}
2+
"name": "sudobot",
3+
"version": "9.0.0-alpha.1",
4+
"description": "A Discord bot for moderation purposes.",
5+
"author": {
6+
"name": "Ar Rakin",
7+
"email": "[email protected]",
8+
"url": "https://virtual-designer.github.io"
9+
},
10+
"main": "build/index.js",
11+
"license": "AGPL-3.0-or-later",
12+
"keywords": [
13+
"bot",
14+
"discord-bot",
15+
"moderation",
16+
"automoderation",
17+
"discord-moderation",
18+
"discord-moderation-bot",
19+
"discord-automoderation",
20+
"discord-automoderation-bot"
21+
],
22+
"homepage": "https://github.com/onesoft-sudo/sudobot",
23+
"icon": "https://res.cloudinary.com/rakinar2/image/upload/v1659628446/SudoBot-new_cvwphw.png",
24+
"readme": "https://github.com/onesoft-sudo/sudobot#readme",
25+
"repository": {
26+
"type": "git",
27+
"url": "https://github.com/onesoft-sudo/sudobot"
28+
},
29+
"bugs": {
30+
"url": "https://github.com/onesoft-sudo/sudobot/issues",
31+
"email": "[email protected]"
32+
},
33+
"_meta": {
34+
"release_codename": "Chocolate Cake",
35+
"release_short_codename": "Cake"
36+
},
37+
"scripts": {
38+
"start": "node build/out/main/typescript/index.js",
39+
"start:bun": "bun --tsconfig-override=tsconfig.bun.json src/bun.ts",
40+
"prepare": "husky && rm -f node_modules/blazebuild && ln -s $(pwd)/blazebuild $(pwd)/node_modules/blazebuild",
41+
"dev": "bun run src/main/typescript/bun.ts",
42+
"start:blazew": "node build/out/main/typescript/index.js",
43+
"lint": "eslint src",
44+
"lint:fix": "eslint src --fix",
45+
"build": "tsc && mv build/out/src _build && rm -fr build/out && mv _build build/out",
46+
"start:prod": "pm2 start ./ecosystem.config.js",
47+
"deploy": "node scripts/deploy-commands.js",
48+
"gen:schema": "node scripts/generate-config-schema.js",
49+
"clean": "rm -frv build tsconfig.tsbuildinfo; make clean",
50+
"test": "vitest"
51+
},
52+
"_moduleAliases": {
53+
"@sudobot": "build/out",
54+
"@framework": "build/out/framework/typescript",
55+
"@main": "build/out/main/typescript",
56+
"@root": "."
57+
},
58+
"trustedDependencies": [
59+
"@prisma/client",
60+
"@prisma/engines",
61+
"@tensorflow/tfjs-node",
62+
"bcrypt",
63+
"core-js",
64+
"esbuild",
65+
"prisma",
66+
"sharp",
67+
"tesseract.js"
68+
],
69+
"dependencies": {
70+
"@googleapis/oauth2": "^1.0.7",
71+
"@prisma/client": "^5.11.0",
72+
"@tensorflow/tfjs-node": "^4.17.0",
73+
"archiver": "^7.0.1",
74+
"ascii-table3": "^0.8.2",
75+
"axios": "^1.6.7",
76+
"bcrypt": "^5.1.1",
77+
"chalk": "^4.1.2",
78+
"cors": "^2.8.5",
79+
"date-fns": "^2.30.0",
80+
"deepmerge": "^4.3.1",
81+
"discord.js": "^14.15.2",
82+
"dot-object": "^2.1.4",
83+
"dotenv": "^16.3.1",
84+
"express": "^4.18.2",
85+
"express-rate-limit": "^6.9.0",
86+
"figlet": "^1.7.0",
87+
"glob": "^10.4.1",
88+
"jpeg-js": "^0.4.4",
89+
"json5": "^2.2.3",
90+
"jsonwebtoken": "^9.0.1",
91+
"module-alias": "^2.2.3",
92+
"nsfwjs": "^3.0.0",
93+
"pm2": "^5.3.1",
94+
"reflect-metadata": "^0.1.13",
95+
"semver": "^7.5.4",
96+
"sharp": "^0.33.2",
97+
"socket.io": "^4.7.2",
98+
"tar": "^6.2.1",
99+
"tesseract.js": "^5.0.4",
100+
"tslib": "^2.6.2",
101+
"undici": "^5.23.0",
102+
"uuid": "^9.0.0",
103+
"zod": "^3.21.4"
104+
},
105+
"devDependencies": {
106+
"@commitlint/cli": "^17.6.6",
107+
"@commitlint/config-conventional": "^17.6.6",
108+
"@faker-js/faker": "^8.4.1",
109+
"@onesoftnet/pm2-config": "^0.0.7",
110+
"@types/archiver": "^6.0.2",
111+
"@types/bcrypt": "^5.0.0",
112+
"@types/bun": "latest",
113+
"@types/cors": "^2.8.13",
114+
"@types/dot-object": "^2.1.2",
115+
"@types/express": "^4.17.17",
116+
"@types/figlet": "^1.5.8",
117+
"@types/glob": "^8.1.0",
118+
"@types/jsonwebtoken": "^9.0.2",
119+
"@types/module-alias": "^2.0.2",
120+
"@types/node": "^20.4.0",
121+
"@types/semver": "^7.5.4",
122+
"@types/tar": "^6.1.11",
123+
"@types/uuid": "^9.0.2",
124+
"@typescript-eslint/eslint-plugin": "^7.7.0",
125+
"@typescript-eslint/parser": "^7.7.0",
126+
"@vitest/coverage-v8": "^1.3.1",
127+
"eslint": "^8.57.0",
128+
"husky": "latest",
129+
"prettier": "^3.2.5",
130+
"prisma": "^5.11.0",
131+
"typescript": "^5.4.3",
132+
"typescript-eslint": "^7.7.0",
133+
"vitest": "^1.3.1",
134+
"zod-to-json-schema": "^3.22.5"
135+
}
139136
}

src/main/typescript/api/controllers/VerificationController.ts

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Controller from "@framework/api/http/Controller";
44
import type Request from "@framework/api/http/Request";
55
import Response from "@framework/api/http/Response";
66
import { Inject } from "@framework/container/Inject";
7+
import { auth, oauth2 } from "@googleapis/oauth2";
78
import type VerificationService from "@main/automod/VerificationService";
89
import { env } from "@main/env/env";
910
import { VerificationMethod } from "@prisma/client";
@@ -14,6 +15,15 @@ class VerificationController extends Controller {
1415
@Inject("verificationService")
1516
private readonly verificationService!: VerificationService;
1617

18+
private readonly googleOauth2Client =
19+
env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET
20+
? new auth.OAuth2({
21+
clientId: env.GOOGLE_CLIENT_ID,
22+
clientSecret: env.GOOGLE_CLIENT_SECRET,
23+
redirectUri: `${env.FRONTEND_URL}/challenge/google`
24+
})
25+
: null;
26+
1727
@Action("POST", "/verification/guild")
1828
@Validate(
1929
z.object({
@@ -200,8 +210,6 @@ class VerificationController extends Controller {
200210

201211
const { access_token, token_type, scope } = oauthData as Record<string, string>;
202212

203-
console.log(oauthData);
204-
205213
if (!scope.includes("read:user")) {
206214
return new Response({
207215
status: 403,
@@ -271,6 +279,84 @@ class VerificationController extends Controller {
271279
body: { error: "We're unable to verify your GitHub Account." }
272280
});
273281
}
282+
283+
@Action("POST", "/challenge/google")
284+
@Validate(
285+
z.object({
286+
code: z.string(),
287+
token: z.string()
288+
})
289+
)
290+
public async verifyByGoogle(request: Request) {
291+
const { code, token } = request.parsedBody ?? {};
292+
293+
if (!this.googleOauth2Client) {
294+
return new Response({
295+
status: 403,
296+
body: { error: "Google OAuth is not supported." }
297+
});
298+
}
299+
300+
try {
301+
const { tokens } = await this.googleOauth2Client.getToken(code);
302+
this.googleOauth2Client.setCredentials(tokens);
303+
304+
const userInfo = await oauth2("v2").userinfo.get({ auth: this.googleOauth2Client });
305+
306+
const { name, id } = userInfo.data;
307+
308+
if (!id || !name) {
309+
return new Response({
310+
status: 403,
311+
body: { error: "We're unable to verify you, please try again." }
312+
});
313+
}
314+
315+
const entry = await this.verificationService.getVerificationEntry(token);
316+
317+
if (!entry || entry.code !== token) {
318+
return new Response({
319+
status: 403,
320+
body: { error: "We're unable to verify you, please try again." }
321+
});
322+
}
323+
324+
const result = await this.application
325+
.service("verificationService")
326+
.verifyWithEntry(entry, {
327+
googleId: id,
328+
method: VerificationMethod.GOOGLE
329+
});
330+
331+
if (!result) {
332+
return new Response({
333+
status: 403,
334+
body: { error: "We're unable to verify you, please try again." }
335+
});
336+
}
337+
338+
if (result.error === "record_exists") {
339+
return new Response({
340+
status: 403,
341+
body: { error: "You cannot use this account to verify." }
342+
});
343+
}
344+
345+
return new Response({
346+
status: 200,
347+
body: {
348+
message: "You have been verified successfully."
349+
}
350+
});
351+
} catch (error) {
352+
this.application.logger.error(error);
353+
}
354+
355+
return new Response({
356+
status: 403,
357+
body: { error: "We're unable to verify your Google Account." }
358+
});
359+
}
274360
}
275361

276362
export default VerificationController;

0 commit comments

Comments
 (0)