From a7efae054016254402ebcd45db6a2e41ce11cd6a Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 13 Jul 2023 11:22:21 +0100 Subject: [PATCH] refactor: extract invite code handling into module (#1233) --- src/modules/invites.ts | 51 +++++++++++++++++++ .../runtime/server/auth/github/[slug].ts} | 10 ++-- src/modules/runtime/server/tsconfig.json | 3 ++ src/server/routes/vueconf.get.ts | 10 ---- src/server/utils/auth.ts | 4 +- test/unit/bundle.spec.ts | 2 +- 6 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/modules/invites.ts rename src/{server/routes/auth/github/vueconf.ts => modules/runtime/server/auth/github/[slug].ts} (89%) create mode 100644 src/modules/runtime/server/tsconfig.json delete mode 100644 src/server/routes/vueconf.get.ts diff --git a/src/modules/invites.ts b/src/modules/invites.ts new file mode 100644 index 00000000..11d41557 --- /dev/null +++ b/src/modules/invites.ts @@ -0,0 +1,51 @@ +import { + addServerHandler, + createResolver, + defineNuxtModule, + useNuxt, +} from 'nuxt/kit' +import { defu } from 'defu' + +export default defineNuxtModule({ + meta: { + name: 'invites', + }, + defaults: { + map: { + // vueconf: 'danielroe/nailing-it-vueconf-us-2023', + } satisfies Record, + }, + setup(options) { + const nuxt = useNuxt() + const resolver = createResolver(import.meta.url) + const gitHubClientId = + process.env.NUXT_PUBLIC_GITHUB_CLIENT_ID || + nuxt.options.runtimeConfig.public.githubClientId + + nuxt.options.runtimeConfig.invites = { + map: options.map, + } + + nuxt.options.nitro.typescript = defu(nuxt.options.nitro.typescript, { + include: ['../src/modules/runtime/server/**/*'], + }) + + if (!gitHubClientId || Object.values(options.map).length === 0) return + + const redirect = nuxt.options.dev + ? '&redirect_uri=http://localhost:3000/auth/github' + : '&redirect_uri=https://roe.dev/auth/github' + + nuxt.options.nitro.routeRules ||= {} + for (const slug in options.map) { + nuxt.options.nitro.routeRules['/' + slug] = { + redirect: `https://github.com/login/oauth/authorize?client_id=${gitHubClientId}${redirect}/${slug}`, + } + } + + addServerHandler({ + route: '/auth/github/:slug', + handler: resolver.resolve('./runtime/server/auth/github/[slug]'), + }) + }, +}) diff --git a/src/server/routes/auth/github/vueconf.ts b/src/modules/runtime/server/auth/github/[slug].ts similarity index 89% rename from src/server/routes/auth/github/vueconf.ts rename to src/modules/runtime/server/auth/github/[slug].ts index 937bd9fe..7ac14f80 100644 --- a/src/server/routes/auth/github/vueconf.ts +++ b/src/modules/runtime/server/auth/github/[slug].ts @@ -1,8 +1,12 @@ /* eslint-disable camelcase */ -const repo = 'danielroe/nailing-it-vueconf-us-2023' - export default defineEventHandler(async event => { + const config = useRuntimeConfig() + const slug = getRouterParam(event, 'slug') + if (!slug || !config.invites?.map || !(slug in config.invites.map)) { + throw createError({ statusCode: 404 }) + } + const { code } = getQuery(event) if (!code) { @@ -12,7 +16,6 @@ export default defineEventHandler(async event => { }) } - const config = useRuntimeConfig() const { access_token } = await $fetch<{ access_token: string }>( 'https://github.com/login/oauth/access_token', { @@ -50,6 +53,7 @@ export default defineEventHandler(async event => { }) } + const repo = config.invites.map[slug] try { const res = await $fetch( `https://api.github.com/repos/${repo}/collaborators/${username}`, diff --git a/src/modules/runtime/server/tsconfig.json b/src/modules/runtime/server/tsconfig.json new file mode 100644 index 00000000..e7988a98 --- /dev/null +++ b/src/modules/runtime/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../../../.nuxt/tsconfig.server.json", +} diff --git a/src/server/routes/vueconf.get.ts b/src/server/routes/vueconf.get.ts deleted file mode 100644 index d0e3aec0..00000000 --- a/src/server/routes/vueconf.get.ts +++ /dev/null @@ -1,10 +0,0 @@ -const redirect = process.dev - ? '&redirect_uri=http://localhost:3000/auth/github/vueconf' - : '&redirect_uri=https://roe.dev/auth/github/vueconf' - -const config = useRuntimeConfig() -const loginURL = `https://github.com/login/oauth/authorize?client_id=${config.public.githubClientId}${redirect}` - -export default defineEventHandler(async event => { - await sendRedirect(event, loginURL) -}) diff --git a/src/server/utils/auth.ts b/src/server/utils/auth.ts index c4db72a3..15b89e97 100644 --- a/src/server/utils/auth.ts +++ b/src/server/utils/auth.ts @@ -1,7 +1,7 @@ import type { H3Event } from 'h3' import * as jose from 'jose' -export async function verifyUser (event: H3Event) { +export async function verifyUser(event: H3Event) { const token = getCookie(event, 'token') if (!token) return null @@ -13,7 +13,7 @@ export async function verifyUser (event: H3Event) { return payload } -export async function loginUser ( +export async function loginUser( event: H3Event, claims: Record ) { diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index 65155328..825ca440 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -77,7 +77,7 @@ describe('project sizes', () => { stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) expect .soft(roundToKilobytes(stats.server.totalBytes)) - .toMatchInlineSnapshot('"212k"') + .toMatchInlineSnapshot('"207k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) expect -- 2.51.2