├── .env ├── .gitignore ├── .vscode └── settings.json ├── babel.config.js ├── package.json ├── src ├── api │ └── discord.api.ts ├── app.ts ├── assets │ ├── creating-app-1.jpg │ ├── creating-app-2.jpg │ ├── json.jpg │ ├── keys.jpg │ ├── oauth-screen.jpg │ └── redirect.jpg ├── config │ └── db.config.js ├── controllers │ └── discorduser.controller.js ├── lib │ └── env.ts ├── models │ ├── discorduser.model.js │ └── index.js └── server.ts └── tsconfig.json /.env: -------------------------------------------------------------------------------- 1 | CLIENT_ID=980928412740902934 2 | CLIENT_SECRET=SecH3EpilmM3aZweViEvuI_4V9d1kpI3 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /package-lock.json -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Artur", 4 | "discordid", 5 | "discordname", 6 | "discorduser", 7 | "groupid", 8 | "prebuild", 9 | "prestart", 10 | "respawn", 11 | "userdata", 12 | "walletadddress" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | targets: { 7 | node: "current", 8 | }, 9 | }, 10 | ], 11 | "@babel/preset-typescript", 12 | ], 13 | }; 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-oauth2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "prestart": "npm run build", 8 | "start": "node dist/server.js", 9 | "dev": "ts-node-dev --respawn --transpile-only --ignore-watch node_modules src/server.ts", 10 | "prebuild": "rm -rf node_modules && rm -f package-lock.json && rm -rf dist && npm i", 11 | "build": "babel src --out-dir dist --extensions \".ts\" --copy-files" 12 | }, 13 | "keywords": [ 14 | "discord", 15 | "oauth2" 16 | ], 17 | "author": "ArturMiguel", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "@babel/cli": "^7.11.6", 21 | "@babel/core": "^7.11.6", 22 | "@babel/preset-env": "^7.11.5", 23 | "@babel/preset-typescript": "^7.10.4", 24 | "@types/cors": "^2.8.8", 25 | "@types/express": "^4.17.8", 26 | "ts-node-dev": "^1.0.0-pre.63", 27 | "typescript": "^4.0.3" 28 | }, 29 | "dependencies": { 30 | "axios": "^0.20.0", 31 | "cors": "^2.8.5", 32 | "dotenv": "^8.2.0", 33 | "express": "^4.18.1", 34 | "mongoose": "^6.3.5" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/api/discord.api.ts: -------------------------------------------------------------------------------- 1 | import { Router, Request, Response } from "express"; 2 | import axios from "axios"; 3 | 4 | const router = Router(); 5 | 6 | const CLIENT_ID = process.env.CLIENT_ID as string; 7 | const CLIENT_SECRET = process.env.CLIENT_SECRET as string; 8 | const REDIRECT_URI = "http://localhost:5000/api/discord/auth-callback"; 9 | const RESPONSE_TYPE = "code"; 10 | const SCOPE = "identify+email+guilds+guilds.members.read"; 11 | const GUILD_ID = "374620978577408000"; 12 | 13 | router.get("/auth", (request: Request, response: Response) => { 14 | response.redirect( 15 | `https://discord.com/api/oauth2/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=${RESPONSE_TYPE}&scope=${SCOPE}` 16 | ); 17 | }); 18 | 19 | router.get("/auth-callback", async (req: Request, res: Response) => { 20 | const code = req.query.code as string; 21 | 22 | const params = new URLSearchParams({ 23 | client_id: CLIENT_ID, 24 | client_secret: CLIENT_SECRET, 25 | code: code, 26 | grant_type: "authorization_code", 27 | redirect_uri: REDIRECT_URI, 28 | }); 29 | 30 | try { 31 | const tokenRes = await axios.post( 32 | "https://discordapp.com/api/oauth2/token", 33 | params, 34 | {} 35 | ); 36 | const token = tokenRes.data.access_token; 37 | 38 | const userRes = await axios.get(`https://discord.com/api/users/@me`, { 39 | headers: { 40 | Authorization: `Bearer ${token}`, 41 | }, 42 | }); 43 | // const guild = await axios.get(`/users/@me/guilds/${GUILD_ID}/member`,{ 44 | // headers: { 45 | // Authorization: `Bearer ${token}`, 46 | // }, 47 | // });userRes.data 48 | res.redirect(`http://localhost:3000/login/wonderful/0215456/3`); 49 | // return res.send({ userdata: userRes.data, guild: guild.data }); 50 | } catch (err: any) { 51 | //return res.send(err.response.data); 52 | } 53 | }); 54 | 55 | export default router; 56 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import "./lib/env"; 2 | import express from "express"; 3 | import cors from "cors"; 4 | 5 | import discordApi from "./api/discord.api"; 6 | 7 | const app = express(); 8 | app.use(cors()); 9 | app.use(express.json()); 10 | 11 | // const db = require("./models"); 12 | // db.mongoose 13 | // .connect(db.url, { 14 | // useNewUrlParser: true, 15 | // useUnifiedTopology: true, 16 | // }) 17 | // .then(() => { 18 | // console.log("Connected to the database!"); 19 | // }) 20 | // .catch((err: any) => { 21 | // console.log("Cannot connect to the database!", err); 22 | // process.exit(); 23 | // }); 24 | 25 | app.use("/api/discord", discordApi); 26 | 27 | export default app; 28 | -------------------------------------------------------------------------------- /src/assets/creating-app-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/creating-app-1.jpg -------------------------------------------------------------------------------- /src/assets/creating-app-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/creating-app-2.jpg -------------------------------------------------------------------------------- /src/assets/json.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/json.jpg -------------------------------------------------------------------------------- /src/assets/keys.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/keys.jpg -------------------------------------------------------------------------------- /src/assets/oauth-screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/oauth-screen.jpg -------------------------------------------------------------------------------- /src/assets/redirect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acehood0126/discord-oauth2-express/c3b730ff5924887e0e2768f74ff4c2e63a208fcd/src/assets/redirect.jpg -------------------------------------------------------------------------------- /src/config/db.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: "mongodb://localhost:27017/DiscordUsers", 3 | }; 4 | -------------------------------------------------------------------------------- /src/controllers/discorduser.controller.js: -------------------------------------------------------------------------------- 1 | const db = require("../models"); 2 | const Discorduser = db.discorduser; 3 | 4 | // Create and Save a new Tutorial 5 | exports.create = (req, res) => { 6 | // Validate request 7 | if (!req.body.discordid) { 8 | res.status(400).send({ message: "Content can not be empty!" }); 9 | return; 10 | } 11 | 12 | // Create a Tutorial 13 | const discorduser = new Discorduser({ 14 | discordid: req.body.discordid, 15 | discordname: req.body.discordname, 16 | walletadddress: req.body.wadres, 17 | groupid: req.body.groupid, 18 | }); 19 | 20 | // Save Tutorial in the database 21 | Discorduser.find({ 22 | discordid: req.body.discordid, 23 | }) 24 | .then((data) => { 25 | if (!data.length) { 26 | discorduser 27 | .save(discorduser) 28 | .then((data) => { 29 | res.send({ message: "Success" }); 30 | }) 31 | .catch((err) => { 32 | res.status(500).send({ 33 | message: 34 | err.message || 35 | "Some error occurred while creating the DiscordUser.", 36 | }); 37 | }); 38 | } else { 39 | res.send({ message: "The user exists" }); 40 | } 41 | }) 42 | .catch((err) => { 43 | res.status(500).send({ message: "Error retrieving DiscordUser" }); 44 | }); 45 | }; 46 | -------------------------------------------------------------------------------- /src/lib/env.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path'; 2 | import { config } from 'dotenv'; 3 | 4 | config({ path: resolve(__dirname, '../../.env') }); 5 | -------------------------------------------------------------------------------- /src/models/discorduser.model.js: -------------------------------------------------------------------------------- 1 | module.exports = (mongoose) => { 2 | var schema = mongoose.Schema( 3 | { 4 | discordid: String, 5 | discordname: String, 6 | walletadddress: String, 7 | groupid: String, 8 | }, 9 | { timestamps: true } 10 | ); 11 | 12 | schema.method("toJSON", function () { 13 | const { __v, _id, ...object } = this.toObject(); 14 | object.id = _id; 15 | return object; 16 | }); 17 | 18 | const Discorduser = mongoose.model("discorduser", schema); 19 | return Discorduser; 20 | }; 21 | -------------------------------------------------------------------------------- /src/models/index.js: -------------------------------------------------------------------------------- 1 | const dbConfig = require("../config/db.config.js"); 2 | 3 | const mongoose = require("mongoose"); 4 | mongoose.Promise = global.Promise; 5 | 6 | const db = {}; 7 | db.mongoose = mongoose; 8 | db.url = dbConfig.url; 9 | db.discorduser = require("./discorduser.model.js")(mongoose); 10 | 11 | module.exports = db; 12 | -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- 1 | import app from "./app"; 2 | 3 | app.listen(5000, () => console.log("Server started!")); 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, 4 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ /* Concatenate and emit output to single file. */, 5 | "outDir": "./dist" /* Redirect output structure to the directory. */, 6 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, 7 | "removeComments": true /* Do not emit comments to output. */, 8 | "strict": true /* Enable all strict type-checking options. */, 9 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 10 | "skipLibCheck": true /* Skip type checking of declaration files. */, 11 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, 12 | "resolveJsonModule": true 13 | }, 14 | "include": ["src/**/*"] 15 | } 16 | --------------------------------------------------------------------------------