mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 08:13:09 +02:00
Add authentication
This commit is contained in:
parent
425e7ab151
commit
a1823a750e
@ -1,5 +1,7 @@
|
|||||||
CONFIG_PATH=./user/config.yml
|
CONFIG_PATH=./user/config.yml
|
||||||
|
DISCORD_SECRET=
|
||||||
DISCORD_TOKEN=
|
DISCORD_TOKEN=
|
||||||
DB_ENCRYPTION_KEY=
|
DB_ENCRYPTION_KEY=
|
||||||
DB_CONNECTION_URL=""
|
DB_CONNECTION_URL=""
|
||||||
HTTP_BIND=3000
|
HTTP_BIND=3000
|
||||||
|
HTTP_EXTERNAL=
|
@ -32,6 +32,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eartharoid/dbf": "^0.0.1",
|
"@eartharoid/dbf": "^0.0.1",
|
||||||
"@eartharoid/dtf": "^2.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",
|
"@prisma/client": "^3.13.0",
|
||||||
"discord.js": "^13.6.0",
|
"discord.js": "^13.6.0",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
@ -40,6 +43,7 @@
|
|||||||
"leeks.js": "^0.2.4",
|
"leeks.js": "^0.2.4",
|
||||||
"leekslazylogger": "^4.1.7",
|
"leekslazylogger": "^4.1.7",
|
||||||
"node-dir": "^0.1.17",
|
"node-dir": "^0.1.17",
|
||||||
|
"node-fetch": "2",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"terminal-link": "^2.1.1",
|
"terminal-link": "^2.1.1",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.2"
|
||||||
|
52
src/http.js
52
src/http.js
@ -1,9 +1,50 @@
|
|||||||
const fastify = require('fastify')();
|
const fastify = require('fastify')();
|
||||||
|
const oauth = require('@fastify/oauth2');
|
||||||
|
const { randomBytes } = require('crypto');
|
||||||
const { short } = require('leeks.js');
|
const { short } = require('leeks.js');
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
const { readFiles } = require('node-dir');
|
const { readFiles } = require('node-dir');
|
||||||
|
|
||||||
module.exports = client => {
|
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) => {
|
fastify.addHook('onResponse', (req, res, done) => {
|
||||||
done();
|
done();
|
||||||
const status = (res.statusCode >= 500
|
const status = (res.statusCode >= 500
|
||||||
@ -22,8 +63,12 @@ module.exports = client => {
|
|||||||
? '&e'
|
? '&e'
|
||||||
: '&a') + response_time + 'ms';
|
: '&a') + response_time + 'ms';
|
||||||
client.log.info.http(short(`${req.ip} ${req.method} ${req.routerPath ?? '*'} &m-+>&r ${status}&b in ${response_time}`));
|
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');
|
const dir = join(__dirname, '/routes');
|
||||||
|
|
||||||
readFiles(dir,
|
readFiles(dir,
|
||||||
@ -43,12 +88,15 @@ module.exports = client => {
|
|||||||
.replace('/index', '') || '/'; // remove index
|
.replace('/index', '') || '/'; // remove index
|
||||||
const route = require(file);
|
const route = require(file);
|
||||||
|
|
||||||
Object.keys(route).forEach(method => fastify[method](path, {
|
Object.keys(route).forEach(method => fastify.route({
|
||||||
config: { client },
|
config: { client },
|
||||||
...route[method],
|
method: method.toUpperCase(),
|
||||||
|
path,
|
||||||
|
...route[method](fastify),
|
||||||
})); // register route
|
})); // register route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start server
|
||||||
fastify.listen(process.env.HTTP_BIND, (err, addr) => {
|
fastify.listen(process.env.HTTP_BIND, (err, addr) => {
|
||||||
if (err) client.log.error.http(err);
|
if (err) client.log.error.http(err);
|
||||||
else client.log.success.http(`Listening at ${addr}`);
|
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) => {
|
handler: (req, res) => {
|
||||||
const { client } = res.context.config;
|
const { client } = res.context.config;
|
||||||
return `Hello, I am ${client.user.username}!`;
|
return `Hello, I am ${client.user.username}!`;
|
||||||
},
|
},
|
||||||
};
|
});
|
Loading…
Reference in New Issue
Block a user