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()); + }, +});