From 55b184f2265272231af6a1f9b129d7d0a55e68c5 Mon Sep 17 00:00:00 2001 From: Isaac Date: Sun, 9 Feb 2025 02:31:25 +0000 Subject: [PATCH] feat: login when adding to guild, then redirect to its settings --- src/http.js | 3 ++- src/routes/auth/callback.js | 8 ++++++-- src/routes/invite.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/routes/invite.js diff --git a/src/http.js b/src/http.js index a158fd0..4283c8d 100644 --- a/src/http.js +++ b/src/http.js @@ -40,11 +40,12 @@ module.exports = async client => { }, }, generateStateFunction: req => { - const state = randomBytes(12).toString('hex'); + const state = randomBytes(8).toString('hex'); fastify.states.set(state, req.query.r); return state; }, name: 'discord', + redirectStateCookieName: 'oauth2-redirect-state', scope: ['applications.commands.permissions.update', 'guilds', 'identify'], startRedirectPath: '/auth/login', }); diff --git a/src/routes/auth/callback.js b/src/routes/auth/callback.js index 361a317..e453544 100644 --- a/src/routes/auth/callback.js +++ b/src/routes/auth/callback.js @@ -13,8 +13,7 @@ module.exports.get = () => ({ headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, method: 'POST', })).json(); - const redirect = this.states.get(req.query.state) || '/'; - this.states.delete(req.query.state); + const user = await (await fetch('https://discordapp.com/api/users/@me', { headers: { 'Authorization': `Bearer ${data.access_token}` } })).json(); const token = this.jwt.sign({ accessToken: data.access_token, @@ -24,6 +23,11 @@ module.exports.get = () => ({ locale: user.locale, username: user.username, }); + + // note: if data.guild is present, guild_id and permissions should also be in req.query + const redirect = this.states.get(req.query.state) || (data.guild?.id && `/settings/${data.guild?.id}`) || '/'; + this.states.delete(req.query.state); + res.setCookie('token', token, { domain, httpOnly: true, diff --git a/src/routes/invite.js b/src/routes/invite.js new file mode 100644 index 0000000..286af8f --- /dev/null +++ b/src/routes/invite.js @@ -0,0 +1,29 @@ +const { randomBytes } = require('crypto'); + +module.exports.get = () => ({ + handler: async function (req, res) { + const { client } = req.routeOptions.config; + + const state = randomBytes(8).toString('hex'); + this.states.set(state, null); + + const url = new URL('https://discord.com/oauth2/authorize'); + url.searchParams.set('response_type', 'code'); + url.searchParams.set('client_id', client.user.id); + url.searchParams.set('prompt', 'none'); + url.searchParams.set('redirect_uri', `${process.env.HTTP_EXTERNAL}/auth/callback`); // window.location.origin + url.searchParams.set('scope', 'applications.commands applications.commands.permissions.update bot guilds identify'); + url.searchParams.set('permissions', '268561488'); + + if (req.query.guild) { + url.searchParams.set('guild_id', req.query.guild); + url.searchParams.set('disable_guild_select', 'true'); + } + + res.setCookie('oauth2-redirect-state', state, { + httpOnly: true, + sameSite: 'lax', + }); + res.redirect(url.toString()); + }, +});