mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 00:03:09 +02:00
Add authentication
This commit is contained in:
parent
425e7ab151
commit
a1823a750e
@ -1,5 +1,7 @@
|
||||
CONFIG_PATH=./user/config.yml
|
||||
DISCORD_SECRET=
|
||||
DISCORD_TOKEN=
|
||||
DB_ENCRYPTION_KEY=
|
||||
DB_CONNECTION_URL=""
|
||||
HTTP_BIND=3000
|
||||
HTTP_BIND=3000
|
||||
HTTP_EXTERNAL=
|
@ -32,6 +32,9 @@
|
||||
"dependencies": {
|
||||
"@eartharoid/dbf": "^0.0.1",
|
||||
"@eartharoid/dtf": "^2.0.1",
|
||||
"@fastify/cookie": "^6.0.0",
|
||||
"@fastify/jwt": "^5.0.1",
|
||||
"@fastify/oauth2": "^5.0.0",
|
||||
"@prisma/client": "^3.13.0",
|
||||
"discord.js": "^13.6.0",
|
||||
"dotenv": "^16.0.0",
|
||||
@ -40,6 +43,7 @@
|
||||
"leeks.js": "^0.2.4",
|
||||
"leekslazylogger": "^4.1.7",
|
||||
"node-dir": "^0.1.17",
|
||||
"node-fetch": "2",
|
||||
"semver": "^7.3.7",
|
||||
"terminal-link": "^2.1.1",
|
||||
"yaml": "^1.10.2"
|
||||
|
52
src/http.js
52
src/http.js
@ -1,9 +1,50 @@
|
||||
const fastify = require('fastify')();
|
||||
const oauth = require('@fastify/oauth2');
|
||||
const { randomBytes } = require('crypto');
|
||||
const { short } = require('leeks.js');
|
||||
const { join } = require('path');
|
||||
const { readFiles } = require('node-dir');
|
||||
|
||||
module.exports = client => {
|
||||
|
||||
// oauth2 plugin
|
||||
fastify.register(oauth, {
|
||||
callbackUri: `${process.env.HTTP_EXTERNAL}/auth/callback`,
|
||||
credentials: {
|
||||
auth: oauth.DISCORD_CONFIGURATION,
|
||||
client: {
|
||||
id: client.user.id,
|
||||
secret: process.env.DISCORD_SECRET,
|
||||
},
|
||||
},
|
||||
name: 'discord',
|
||||
scope: ['identify'],
|
||||
startRedirectPath: '/auth/login',
|
||||
});
|
||||
|
||||
// cookies plugin
|
||||
fastify.register(require('@fastify/cookie'));
|
||||
|
||||
// jwt plugin
|
||||
fastify.register(require('@fastify/jwt'), {
|
||||
cookie: {
|
||||
cookieName: 'token',
|
||||
signed: false,
|
||||
},
|
||||
secret: randomBytes(16).toString('hex'),
|
||||
});
|
||||
|
||||
// auth
|
||||
fastify.decorate('authenticate', async (req, res) => {
|
||||
try {
|
||||
const data = await req.jwtVerify();
|
||||
if (data.payload.expiresAt < Date.now()) res.redirect('/auth/login');
|
||||
} catch (err) {
|
||||
res.send(err);
|
||||
}
|
||||
});
|
||||
|
||||
// logging
|
||||
fastify.addHook('onResponse', (req, res, done) => {
|
||||
done();
|
||||
const status = (res.statusCode >= 500
|
||||
@ -22,8 +63,12 @@ module.exports = client => {
|
||||
? '&e'
|
||||
: '&a') + response_time + 'ms';
|
||||
client.log.info.http(short(`${req.ip} ${req.method} ${req.routerPath ?? '*'} &m-+>&r ${status}&b in ${response_time}`));
|
||||
done();
|
||||
});
|
||||
|
||||
fastify.addHook('onError', async (req, res, err) => client.log.error.http(err));
|
||||
|
||||
// route loading
|
||||
const dir = join(__dirname, '/routes');
|
||||
|
||||
readFiles(dir,
|
||||
@ -43,12 +88,15 @@ module.exports = client => {
|
||||
.replace('/index', '') || '/'; // remove index
|
||||
const route = require(file);
|
||||
|
||||
Object.keys(route).forEach(method => fastify[method](path, {
|
||||
Object.keys(route).forEach(method => fastify.route({
|
||||
config: { client },
|
||||
...route[method],
|
||||
method: method.toUpperCase(),
|
||||
path,
|
||||
...route[method](fastify),
|
||||
})); // register route
|
||||
}
|
||||
|
||||
// start server
|
||||
fastify.listen(process.env.HTTP_BIND, (err, addr) => {
|
||||
if (err) client.log.error.http(err);
|
||||
else client.log.success.http(`Listening at ${addr}`);
|
||||
|
1
src/lib/http.js
Normal file
1
src/lib/http.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports.domain = process.env.HTTP_EXTERNAL.match(/http(s?):\/\/(?<domain>[a-zA-Z0-9\-_.]+)(:\d+)?/).groups.domain;
|
@ -0,0 +1,7 @@
|
||||
module.exports.get = fastify => ({
|
||||
handler: (req, res) => {
|
||||
const { client } = res.context.config;
|
||||
return client.guilds.cache.get(req.params.guild);
|
||||
},
|
||||
onRequest: [fastify.authenticate],
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
module.exports.get = fastify => ({
|
||||
handler: async (req, res) => {
|
||||
const { client } = res.context.config;
|
||||
const user = await client.users.fetch(req.user.payload.id);
|
||||
console.log(req.user.payload.username, user?.tag);
|
||||
res.send(client.guilds.cache);
|
||||
},
|
||||
onRequest: [fastify.authenticate],
|
||||
});
|
29
src/routes/auth/callback.js
Normal file
29
src/routes/auth/callback.js
Normal file
@ -0,0 +1,29 @@
|
||||
const fetch = require('node-fetch');
|
||||
const { domain } = require('../../lib/http');
|
||||
|
||||
module.exports.get = () => ({
|
||||
handler: async function (req, res) { // must NOT use arrow function syntax
|
||||
const {
|
||||
access_token, expires_in,
|
||||
} = await this.discord.getAccessTokenFromAuthorizationCodeFlow(req);
|
||||
const user = await (await fetch('https://discordapp.com/api/users/@me', { headers: { 'Authorization': `Bearer ${access_token}` } })).json();
|
||||
const payload = {
|
||||
avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`,
|
||||
discriminator: user.discriminator,
|
||||
expiresAt: Date.now() + (expires_in * 1000),
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
|
||||
};
|
||||
const token = this.jwt.sign({ payload });
|
||||
res
|
||||
.setCookie('token', token, {
|
||||
domain: domain,
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
sameSite: true,
|
||||
secure: false,
|
||||
})
|
||||
.redirect('/');
|
||||
},
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
module.exports.get = {
|
||||
module.exports.get = () => ({
|
||||
handler: (req, res) => {
|
||||
const { client } = res.context.config;
|
||||
return `Hello, I am ${client.user.username}!`;
|
||||
},
|
||||
};
|
||||
});
|
Loading…
Reference in New Issue
Block a user