From 0f5da1dba1e97b321b68a68621f6ada319409d25 Mon Sep 17 00:00:00 2001 From: niko <57009359+hauntii@users.noreply.github.com> Date: Tue, 27 May 2025 04:20:02 -0400 Subject: [PATCH] feat: basic discord connection support --- nuxt.config.ts | 17 +++++ package-lock.json | 26 +++++++ package.json | 6 ++ src/pages/account/index.vue | 70 ++++++++++++++--- .../account/connections/discord/add/index.ts | 49 ++++++++++++ .../account/connections/discord/info/index.ts | 76 +++++++++++++++++++ .../connections/discord/remove/index.ts | 24 ++++++ 7 files changed, 256 insertions(+), 12 deletions(-) create mode 100644 src/server/api/account/connections/discord/add/index.ts create mode 100644 src/server/api/account/connections/discord/info/index.ts create mode 100644 src/server/api/account/connections/discord/remove/index.ts diff --git a/nuxt.config.ts b/nuxt.config.ts index 9d1a71a..6790fed 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -26,11 +26,28 @@ export default defineNuxtConfig({ runtimeConfig: { apiBase: 'https://api.pretendo.cc', + discord: { + botToken: '', + clientID: '', + clientSecret: '' + }, + public: { hCaptchaSitekey: '' } }, + hooks: { + 'pages:extend'(pages) { + // add a route + pages.push({ + name: 'connect', + path: '/account/connect/:connection', + file: '~/pages/account/index.vue' + }); + } + }, + css: ['~/assets/css/main.css'], fonts: { diff --git a/package-lock.json b/package-lock.json index 2ba3f8b..05e2499 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,8 @@ "@nuxt/fonts": "^0.11.1", "@nuxt/icon": "^1.11.0", "@nuxtjs/i18n": "^9.5.3", + "discord-api-types": "^0.38.8", + "discord-oauth2": "^2.12.1", "eslint": "^9.24.0", "feed": "^4.2.2", "nuxt": "^3.16.2", @@ -24,6 +26,7 @@ }, "devDependencies": { "@pretendonetwork/eslint-config": "^0.0.8", + "@types/node": "^22.15.21", "eslint-plugin-vue": "^10.0.0", "sass-embedded": "^1.86.3" } @@ -3913,6 +3916,16 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" }, + "node_modules/@types/node": { + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", @@ -6449,6 +6462,12 @@ "scripts/actions/documentation" ] }, + "node_modules/discord-oauth2": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/discord-oauth2/-/discord-oauth2-2.12.1.tgz", + "integrity": "sha512-/Um39bRxVjcGHUu1YaTLangZvZveXjsX4BNsa1Iyd6OQG0jL972IBQGKD0mYqQswxC3bT+hqWSouabfI2RdaZA==", + "license": "MIT" + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -15046,6 +15065,13 @@ "node": ">=18.17" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/unenv": { "version": "2.0.0-rc.15", "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.15.tgz", diff --git a/package.json b/package.json index 3685a9e..104244f 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,20 @@ "@nuxt/fonts": "^0.11.1", "@nuxt/icon": "^1.11.0", "@nuxtjs/i18n": "^9.5.3", + "discord-api-types": "^0.38.8", + "discord-oauth2": "^2.12.1", "eslint": "^9.24.0", "feed": "^4.2.2", "nuxt": "^3.16.2", "vue": "^3.5.13", "vue-router": "^4.5.0" }, + "browser": { + "crypto": false + }, "devDependencies": { "@pretendonetwork/eslint-config": "^0.0.8", + "@types/node": "^22.15.21", "eslint-plugin-vue": "^10.0.0", "sass-embedded": "^1.86.3" } diff --git a/src/pages/account/index.vue b/src/pages/account/index.vue index bc0b6ac..e5ae314 100644 --- a/src/pages/account/index.vue +++ b/src/pages/account/index.vue @@ -24,9 +24,49 @@ interface InfoCCResponse { }; } +interface DiscordInfoResponse { + username?: string; + authLink?: string; +} + +const route = useRoute(); +const router = useRouter(); const account = await useFetch('/api/account/info'); // TODO: easy way to share this between navbar and account page? is that a good idea? + const showingEditingDisabledModal = ref(false); +if (route.params.connection) { // my nightmares are made of this logic + if (import.meta.server) { + switch (route.params.connection) { // future proofing for more connections? + case 'discord': { + if (route.query.code) { + await useFetch('/api/account/connections/discord/add', { + method: 'POST', + body: { + code: route.query.code + } + }); + } + break; + } + default: + break; + } + } + router.replace('/account'); +} + +const discordInfo = await useFetch('/api/account/connections/discord/info'); + +async function handleUnlinkDiscord() { + try { + await $fetch('/api/account/connections/discord/remove', { method: 'DELETE' }); + discordInfo.refresh(); + } catch { + console.log('uhoh'); + } +} +