From 3b136dfcc852c35629bfdb1f04562eee1c189ce1 Mon Sep 17 00:00:00 2001 From: Ianyourgod Date: Mon, 25 Mar 2024 11:43:16 -0500 Subject: [PATCH] almost working oauth except for 500 ERROR AGHGHJGHGH --- api/db/UserManager.js | 41 ++++++++++++++++++++++++++++++- api/v1/routes/users/OAuthlogin.js | 34 +++++++++++++++++++++++++ api/v1/routes/users/oauth.js | 24 ++++++++++++++++++ api/v1/routes/users/oauthlocal.js | 24 ++++++++++++++++++ index.js | 3 ++- test.html | 2 ++ 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 api/v1/routes/users/OAuthlogin.js create mode 100644 api/v1/routes/users/oauth.js create mode 100644 api/v1/routes/users/oauthlocal.js diff --git a/api/db/UserManager.js b/api/db/UserManager.js index de7c9ac..3719f80 100644 --- a/api/db/UserManager.js +++ b/api/db/UserManager.js @@ -1,3 +1,4 @@ +require('dotenv').config(); const { randomBytes } = require('node:crypto'); const bcrypt = require('bcrypt'); const { MongoClient } = require('mongodb'); @@ -6,6 +7,8 @@ const path = require('path'); const fs = require('fs'); var prompt = require('prompt-sync')(); +// scratch oauth name: Penguinmod-BA-Ianyourgod-Dev +// scratch oauth redir: http://localhost:8080/api/v1/users/login function generateId() { const rn = [ @@ -46,6 +49,7 @@ class UserManager { this.reports = this.db.collection('reports'); this.projects = this.db.collection('projects'); this.messages = this.db.collection('messages'); + this.oauthStates = this.db.collection('oauthStates'); this.illegalList = this.db.collection('illegalList'); if (!this.illegalList.findOne({ id: "illegalWords" })) { this.illegalList.insertMany([ @@ -74,6 +78,7 @@ class UserManager { await this.reports.deleteMany({}); await this.projects.deleteMany({}); await this.messages.deleteMany({}); + await this.oauthStates.deleteMany({}); await this.illegalList.deleteMany({}); this.illegalList.insertMany([ { id: "illegalWords", items: [] }, @@ -127,7 +132,8 @@ class UserManager { cubes: 0, firstLogin: Date.now(), lastLogin: Date.now(), - lastUpload: 0 + lastUpload: 0, + OAuth2State: generateId() }); return token; } @@ -1045,6 +1051,39 @@ class UserManager { potentiallyUnsafeWordsSpacedOut: potentiallyUnsafeWordsSpacedOut } } + + async verifyOAuth2State(state) { + const result = await this.oauthStates.findOne({ state: state }); + + return result ? true : false; + } + + async generateOAuth2State() { + const state = generateId(); + + await this.oauthStates.insertOne({ state: state }); + + return state; + } + + async makeOAuth2Request(code, method) { + switch (method) { + case "scratch": + const response = await fetch(`https://oauth2.scratch-wiki.info/w/rest.php/soa2/v0/tokens`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + client_id: Number(process.env.ScratchOauth2ClientID), + client_secret: process.env.ScratchOauth2ClientSecret, + code: code, + scopes: ["identify"] + }) + }).then(res => res.json()); + return response; + } + } } module.exports = UserManager; \ No newline at end of file diff --git a/api/v1/routes/users/OAuthlogin.js b/api/v1/routes/users/OAuthlogin.js new file mode 100644 index 0000000..2cd6a2e --- /dev/null +++ b/api/v1/routes/users/OAuthlogin.js @@ -0,0 +1,34 @@ +module.exports = (app, utils) => { + app.get("/api/v1/users/oauthlogin", async function (req, res) { + const packet = req.query; + + const state = packet.state; + const code = packet.code; + + if (!state || !code) { + utils.error(res, 400, "InvalidData"); + return; + } + + if (!await utils.UserManager.verifyOAuth2State(state)) { + utils.error(res, 400, "InvalidData"); + return; + } + + // now make the request + const response = await utils.UserManager.makeOAuth2Request(code, "scratch"); + + console.log(response.access_token); + + const username = await fetch("https://oauth2.scratch-wiki.info/w/rest.php/soa2/v0/user", { + headers: { + Authorization: `Bearer ${btoa(response.access_token)}` + } + }).then(res => res.status); + + console.log(username); + + res.status(200); + res.send("hi"); + }); +} \ No newline at end of file diff --git a/api/v1/routes/users/oauth.js b/api/v1/routes/users/oauth.js new file mode 100644 index 0000000..ed71d7d --- /dev/null +++ b/api/v1/routes/users/oauth.js @@ -0,0 +1,24 @@ +module.exports = (app, utils) => { + app.get("/api/v1/users/oauth", async function (req, res) { + // get the method + const packet = req.query; + + const method = packet.method; + + if (!method) { + utils.error(res, 400, "InvalidData"); + return; + } + + // using switch case cuz erm i like it + switch (method) { + case "scratch": + let state = await utils.UserManager.generateOAuth2State(); + res.redirect(`https://oauth2.scratch-wiki.info/wiki/Special:ScratchOAuth2/authorize?client_id=${utils.env.ScratchOauth2ClientID}&redirect_uri=https://projects.penguinmod.com/api/v1/users/oauthlogin&scopes=identify&state=${state}`); + break; + default: + utils.error(res, 400, "InvalidData"); + return; + } + }); +} \ No newline at end of file diff --git a/api/v1/routes/users/oauthlocal.js b/api/v1/routes/users/oauthlocal.js new file mode 100644 index 0000000..f6f64d3 --- /dev/null +++ b/api/v1/routes/users/oauthlocal.js @@ -0,0 +1,24 @@ +module.exports = (app, utils) => { + app.get("/api/v1/users/oauthlocal", async function (req, res) { + // get the method + const packet = req.query; + + const method = packet.method; + + if (!method) { + utils.error(res, 400, "InvalidData"); + return; + } + + // using switch case cuz erm i like it + switch (method) { + case "scratch": + let state = await utils.UserManager.generateOAuth2State(); + res.redirect(`https://oauth2.scratch-wiki.info/wiki/Special:ScratchOAuth2/authorize?client_id=${utils.env.ScratchOauth2ClientID}&redirect_uri=http://localhost:8080/api/v1/users/oauthlogin&scopes=identify&state=${state}`); + break; + default: + utils.error(res, 400, "InvalidData"); + return; + } + }); +} \ No newline at end of file diff --git a/index.js b/index.js index 315327f..9dee1e6 100644 --- a/index.js +++ b/index.js @@ -57,7 +57,8 @@ const UserManager = new um(); escapeXML: functions.escapeXML, generateProfileJSON: functions.generateProfileJSON, safeZipParse: functions.safeZipParse, - error: error + error: error, + env: process.env }); app.listen(PORT, () => { diff --git a/test.html b/test.html index f5a7a30..c470d32 100644 --- a/test.html +++ b/test.html @@ -10,6 +10,8 @@ + Login with Scratch +