diff --git a/public/assets/js/account.js b/public/assets/js/account.js index c27b927..2334a5f 100644 --- a/public/assets/js/account.js +++ b/public/assets/js/account.js @@ -1,26 +1,3 @@ - -document.getElementById('remove-discord-connection')?.addEventListener('click', () => { - // TODO: Refresh access token if expired (move this to the backend maybe?) - - const tokenType = document.cookie.split('; ').find(row => row.startsWith('token_type=')).split('=')[1]; - const accessToken = document.cookie.split('; ').find(row => row.startsWith('access_token=')).split('=')[1]; - - fetch('https://api.pretendo.cc/v1/connections/remove/discord', { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `${tokenType} ${decodeURIComponent(accessToken)}` - } - }) - .then(response => response.json()) - .then(({ status }) => { - if (status === 200) { - location.reload(); - } - }) - .catch(console.log); -}); - const onlineFilesModal = document.querySelector('.modal-wrapper#onlinefiles'); const onlineFilesModalButtonConfirm = document.getElementById('onlineFilesConfirmButton'); const onlineFilesModalButtonClose = document.getElementById('onlineFilesCloseButton'); diff --git a/src/routes/account.js b/src/routes/account.js index bb0efd5..71b8b87 100644 --- a/src/routes/account.js +++ b/src/routes/account.js @@ -147,6 +147,7 @@ router.get('/logout', async(_request, response) => { }); router.get('/connect/discord', requireLoginMiddleware, async (request, response) => { + const { pnid } = request; let tokens; try { // Attempt to get OAuth2 tokens @@ -166,8 +167,52 @@ router.get('/connect/discord', requireLoginMiddleware, async (request, response) try { await util.updateDiscordConnection(discordUser, request, response); + const priceId = pnid.get('connections.stripe.price_id'); + + if (priceId && priceId.trim() !== '') { + const price = await stripe.prices.retrieve(priceId); + const product = await stripe.products.retrieve(price.product); + const discordRoleId = product.metadata.discord_role_id; + const discordId = discordUser.id; + + await util.assignDiscordMemberSupporterRole(discordId, discordRoleId); + + if (product.metadata.beta === 'true') { + await util.assignDiscordMemberTesterRole(discordId); + } + } + response.cookie('success_message', 'Discord account linked successfully', { domain: '.pretendo.network' }); - response.redirect('/account'); + return response.redirect('/account'); + } catch (error) { + response.cookie('error_message', error.message, { domain: '.pretendo.network' }); + return response.redirect('/account'); + } +}); + +router.get('/remove/discord', requireLoginMiddleware, async (request, response) => { + const { account, pnid } = request; + + try { + await util.removeDiscordConnection(request, response); + + const priceId = pnid.get('connections.stripe.price_id'); + + if (priceId && priceId.trim() !== '') { + const price = await stripe.prices.retrieve(priceId); + const product = await stripe.products.retrieve(price.product); + const discordRoleId = product.metadata.discord_role_id; + const discordId = account.connections.discord.id; + + await util.removeDiscordMemberSupporterRole(discordId, discordRoleId); + + if (product.metadata.beta === 'true') { + await util.removeDiscordMemberTesterRole(discordId); + } + } + + response.cookie('success_message', 'Discord account removed successfully', { domain: '.pretendo.network' }); + return response.redirect('/account'); } catch (error) { response.cookie('error_message', error.message, { domain: '.pretendo.network' }); return response.redirect('/account'); diff --git a/src/util.js b/src/util.js index af4c42a..e6758c0 100644 --- a/src/util.js +++ b/src/util.js @@ -188,6 +188,22 @@ async function updateDiscordConnection(discordUser, request, response, fromRetry } } +async function removeDiscordConnection(request, response, fromRetry = false) { + const apiResponse = await apiDeleteRequest('/v1/connections/remove/discord', { + 'Authorization': `${request.cookies.token_type} ${request.cookies.access_token}` + }); + + if (apiResponse.statusCode !== 200 && fromRetry === true) { + // TODO: Error message + throw new Error('Bad'); + } + + if (apiResponse.statusCode !== 200) { + await refreshLogin(request, response); + await removeDiscordConnection(request, response, true); + } +} + function nintendoPasswordHash(password, pid) { const pidBuffer = Buffer.alloc(4); pidBuffer.writeUInt32LE(pid); @@ -444,6 +460,11 @@ module.exports = { refreshLogin, getUserAccountData, updateDiscordConnection, + removeDiscordConnection, nintendoPasswordHash, - handleStripeEvent + handleStripeEvent, + assignDiscordMemberSupporterRole, + assignDiscordMemberTesterRole, + removeDiscordMemberSupporterRole, + removeDiscordMemberTesterRole }; diff --git a/views/account/account.handlebars b/views/account/account.handlebars index 0110804..8cdf5d6 100644 --- a/views/account/account.handlebars +++ b/views/account/account.handlebars @@ -143,7 +143,9 @@
{{ localeHelper locale "account.settings.settingCards.connectedToDiscord" }} {{ discordUser.username }}#{{ discordUser.discriminator }}
- + + + {{else}}{{ localeHelper locale "account.settings.settingCards.noDiscordLinked" }} {{ localeHelper locale "account.settings.settingCards.linkDiscord" }}
{{/if}}