mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-22 03:50:41 +03:00
Added unauth w/discord, and better auth
This commit is contained in:
parent
43720f0ca0
commit
cf8de73e7c
8 changed files with 130 additions and 90 deletions
|
@ -1,2 +1,3 @@
|
|||
MONGO_DB_URL = mongodb://localhost:27017/akf-forum
|
||||
SECRET = secret
|
||||
DISCORD_SECRET = yourDiscordSecret
|
49
APIDOCS.md
49
APIDOCS.md
|
@ -67,30 +67,35 @@ You can change them in config.json.
|
|||
GET ```/api/messages/0```
|
||||
|
||||
#### Example API Output:
|
||||
```json
|
||||
```js
|
||||
{
|
||||
"_id": "63067429bc01da866fad508b",
|
||||
"threadID": "0",
|
||||
"author": {
|
||||
"id": "0",
|
||||
"name": "Akif9748",
|
||||
"avatar": "https://cdn.discordapp.com/avatars/539506680140922890/abd74d10aac094fc8a5ad5c86f29fdb9.png?size=1024",
|
||||
"time": "2022-08-24T18:54:55.666Z",
|
||||
"deleted": false,
|
||||
"admin": false,
|
||||
"_id": "630673ffbc01da866fad507b",
|
||||
"__v": 0
|
||||
},
|
||||
"content": "deneme",
|
||||
"deleted": false,
|
||||
"edited": false,
|
||||
"time": "2022-08-24T18:55:37.744Z",
|
||||
"id": "0",
|
||||
"__v": 0,
|
||||
"react": {
|
||||
"like": [0],
|
||||
"dislike": []
|
||||
"like": [],
|
||||
"dislike": ["0"]
|
||||
},
|
||||
"authorID": "0"
|
||||
"_id": "6325c216faa938c4cfc43075",
|
||||
"author": {
|
||||
"_id": "632e028ca4ba362ebbb75a43",
|
||||
"name": "Akif9748",
|
||||
"avatar": "/images/avatars/0.jpg",
|
||||
"deleted": false,
|
||||
"edited": true,
|
||||
"about": "# Owner",
|
||||
"admin": true,
|
||||
"theme": "black",
|
||||
"hideLastSeen": false,
|
||||
"time": "2022-09-23T19:01:32.610Z",
|
||||
"id": "0",
|
||||
"__v": 0,
|
||||
"discordID": "539506680140922890"
|
||||
},
|
||||
"threadID": "0",
|
||||
"content": "This is a thread opened via API, yes",
|
||||
"deleted": false,
|
||||
"edited": true,
|
||||
"time": "2022-09-17T12:48:22.378Z",
|
||||
"id": "0",
|
||||
"__v": 4,
|
||||
"oldContents": []
|
||||
}
|
||||
```
|
|
@ -14,6 +14,7 @@ Edit `config.json` for default themes (`black` or `default`) of users, and forum
|
|||
|
||||
### DISCORD AUTH:
|
||||
`"discord_auth": "your_app_id"` in config.json.
|
||||
Add your app secret to `.env` as `DISCORD_SECRET`.
|
||||
Create a redirect url in discord developer portal:
|
||||
`https://forum_url.com/discord_auth/hash`
|
||||
|
||||
|
@ -43,7 +44,6 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
|
|||
- mod role, permissions
|
||||
- upload other photos, model for it
|
||||
- categories page is need a update, thread count in category
|
||||
- DC auth will store code for taking tokens, and create secret model setting
|
||||
- Disable last seen button for web.
|
||||
- email auth.
|
||||
- old contents / titles add to forum interface
|
||||
|
|
4
index.js
4
index.js
|
@ -29,7 +29,7 @@ app.use(express.static("public"), express.json(), express.urlencoded({extended:t
|
|||
|
||||
req.user = req.session.userID ? await UserModel.findOneAndUpdate({ id: req.session.userID }, {
|
||||
lastSeen: Date.now(), $addToSet: { ips: req.clientIp }
|
||||
}) : null;
|
||||
}): null;
|
||||
res.reply = (page, options = {}, status = 200) => res.status(status)
|
||||
.render(page, { user: req.user, theme: req.user?.theme || def_theme, forum_name, description, ...options });
|
||||
|
||||
|
@ -44,7 +44,7 @@ app.use(express.static("public"), express.json(), express.urlencoded({extended:t
|
|||
);
|
||||
|
||||
if (discord_auth)
|
||||
app.set("discord_auth", `https://discord.com/api/oauth2/authorize?client_id=${discord_auth}&redirect_uri=${host}%2Fdiscord_auth%2Fhash&response_type=token&scope=identify`);
|
||||
app.set("discord_auth", `https://discord.com/api/oauth2/authorize?client_id=${discord_auth}&redirect_uri=${host}%2Fauth%2Fdiscord&response_type=code&scope=identify`);
|
||||
|
||||
if (RLS.enabled) app.use(RL(RLS.windowMs, RLS.max));
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ const schema = new mongoose.Schema({
|
|||
lastSeen: { type: Date, default: Date.now, select: false },
|
||||
hideLastSeen: { type: Boolean, default: false },
|
||||
ips: { type: [String], default: [], select: false },
|
||||
password: { type: String, select: false }
|
||||
password: { type: String, select: false },
|
||||
discord_code: { type: String, select: false }
|
||||
});
|
||||
|
||||
schema.methods.takeId = async function () {
|
||||
|
|
87
routes/auth.js
Normal file
87
routes/auth.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
const { Router } = require("express")
|
||||
const { UserModel } = require("../models");
|
||||
const fetch = require("node-fetch");
|
||||
const app = Router();
|
||||
const { host, discord_auth } = require("../config.json")
|
||||
|
||||
app.get("/discord", async (req, res) => {
|
||||
const client_id = discord_auth;
|
||||
if (!client_id) return res.error(404, "Discord auth is disabled")
|
||||
const { code } = req.query;
|
||||
if (!code) return res.error(400, "No code provided");
|
||||
try {
|
||||
const response = await fetch('https://discord.com/api/v10/oauth2/token', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
client_id, code,
|
||||
client_secret: process.env.DISCORD_SECRET,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: host + "/auth/discord",
|
||||
scope: 'identify',
|
||||
}).toString(),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) return res.error(500, "Bad request to discord");
|
||||
|
||||
const { access_token, token_type } = await response.json();
|
||||
|
||||
const discord = await fetch('https://discord.com/api/users/@me', {
|
||||
headers: { authorization: `${token_type} ${access_token}` }
|
||||
}).then(res => res.json());
|
||||
|
||||
const forum = await UserModel.findOne({ discordID: discord.id });
|
||||
|
||||
if (req.user) {
|
||||
if (req.user.discordID)
|
||||
return res.error(403, "Your forum account is already linked to a discord account.");
|
||||
|
||||
if (forum)
|
||||
return res.error(403, "This discord account is already linked to a forum account.");
|
||||
|
||||
req.user.discordID = discord.id;
|
||||
req.user.discord_code = code;
|
||||
await req.user.save();
|
||||
return res.redirect(`/users/${req.user.id}`)
|
||||
}
|
||||
|
||||
|
||||
if (forum) {
|
||||
req.session.userID = forum.id;
|
||||
return res.redirect("/");
|
||||
}
|
||||
|
||||
let name = discord.username + discord.discriminator;
|
||||
while (await UserModel.findOne({ name }))
|
||||
name += Math.floor(Math.random() * 2);
|
||||
|
||||
const user2 = new UserModel({
|
||||
name, discordID: discord.id, discord_code: code,
|
||||
avatar: `https://cdn.discordapp.com/avatars/${discord.id}/${discord.avatar}.png?size=256`
|
||||
});
|
||||
|
||||
await user2.takeId();
|
||||
await user2.save();
|
||||
|
||||
req.session.userID = user2.id;
|
||||
|
||||
res.redirect("/");
|
||||
} catch (error) {
|
||||
res.error(500, "Something went wrong");
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/discord", async (req, res) => {
|
||||
if (!req.user) return res.error(403, "You are not logged in");
|
||||
if (!req.user.discordID) return res.error(403, "You don't have a discord account linked to your forum account.");
|
||||
req.user.discordID = undefined;
|
||||
req.user.discord_code = undefined;
|
||||
await req.user.save();
|
||||
res.send("Your discord account has been unlinked from your forum account.");
|
||||
});
|
||||
|
||||
|
||||
module.exports = app;
|
|
@ -1,61 +0,0 @@
|
|||
const { Router } = require("express")
|
||||
const { UserModel } = require("../models");
|
||||
const fetch = require("node-fetch");
|
||||
const app = Router();
|
||||
|
||||
app.use(async (req, res, next) =>
|
||||
req.app.get("discord_auth") ? next() : res.error(404,"Discord auth is disabled")
|
||||
)
|
||||
app.get("/hash", (req, res) => res.send('<script>location.href=location.href.replace("#","?").replace("discord_auth/hash","discord_auth");</script>'))
|
||||
|
||||
app.get("/", async (req, res) => {
|
||||
const { access_token, token_type } = req.query;
|
||||
if (!access_token) return;
|
||||
try {
|
||||
const discord = await fetch('https://discord.com/api/users/@me', {
|
||||
headers: { authorization: `${token_type} ${access_token}` }
|
||||
}).then(res => res.json());
|
||||
|
||||
const forum = await UserModel.findOne({ discordID: discord.id });
|
||||
|
||||
|
||||
if (req.user) {
|
||||
if (req.user.discordID)
|
||||
return res.error(403, "Your forum account is already linked to a discord account.");
|
||||
|
||||
if (forum)
|
||||
return res.error(403, "This discord account is already linked to a forum account.");
|
||||
|
||||
req.user.discordID = discord.id;
|
||||
await req.user.save();
|
||||
return res.send("Your discord account has been linked to your forum account.");
|
||||
}
|
||||
|
||||
|
||||
if (forum) {
|
||||
req.session.userID = forum.id;
|
||||
return res.redirect("/");
|
||||
}
|
||||
|
||||
let name = discord.username + discord.discriminator;
|
||||
while (await UserModel.findOne({ name }))
|
||||
name += Math.floor(Math.random() * 2);
|
||||
|
||||
const user2 = new UserModel({
|
||||
name, discordID: discord.id,
|
||||
avatar: `https://cdn.discordapp.com/avatars/${discord.id}/${discord.avatar}.png?size=256`
|
||||
});
|
||||
|
||||
await user2.takeId();
|
||||
await user2.save();
|
||||
|
||||
req.session.userID = user2.id;
|
||||
|
||||
res.redirect("/");
|
||||
} catch (error) {
|
||||
res.error(500, "Something went wrong");
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = app;
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
<div class="content">
|
||||
<% if (!member.discordID && discord && user?.id === member.id) { %>
|
||||
<a href="<%=discord%>" class="btn-outline-primary">Login with discord</a>
|
||||
<a href="<%=discord%>" class="btn-outline-primary">Auth with discord</a>
|
||||
<% } else if(member.discordID && user?.id === member.id) { %>
|
||||
<a class="btn-outline-primary" id="un_discord">Unauth with discord!</a>
|
||||
<% } %>
|
||||
<% if (user?.admin || user?.id === member.id) { %>
|
||||
<a href="/users/<%=member.id%>/avatar" class="btn-outline-primary">Upload avatar</a>
|
||||
|
@ -62,7 +64,12 @@
|
|||
if (response.deleted) return;
|
||||
alert("User is undeleted successfully!");
|
||||
location.reload()
|
||||
} else if (e.target.id == "toogle")
|
||||
} else if (e.target.id == "un_discord") {
|
||||
const response = await fetch("/auth/discord/", {method:"DELETE"});
|
||||
alert(await response.text());
|
||||
location.reload()
|
||||
}
|
||||
else if (e.target.id == "toogle")
|
||||
document.getElementById('user-edit').classList.toggle('no-active')
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue