shelve icon indicating copy to clipboard operation
shelve copied to clipboard

feat: Make OAuth optional and define it at runtime of the app

Open HugoRCD opened this issue 1 year ago • 6 comments

Description

This issue aims to simplify self-hosting further by enabling OAuth with minimal configuration. For instance, to activate GitHub OAuth, one need only provide the following environment variables:

  • NUXT_OAUTH_GITHUB_CLIENT_ID
  • NUXT_OAUTH_GITHUB_CLIENT_SECRET

To facilitate this, Shelve will now support a default authentication system utilizing a one-time password (OTP) mechanism. This update will decrease the number of required environment variables and shorten the setup time.

CleanShot 2024-11-18 at 11 59 49

HugoRCD avatar Nov 11 '24 13:11 HugoRCD

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Jan 05 '25 02:01 github-actions[bot]

What if rework https://github.com/atinux/nuxt-auth-utils/issues/277#issuecomment-2468559614 into api route which returns available oauth methods based on provided envs?

Kinda like that:

// server/routes/auth/providers.get.ts
const providers = ['github', 'google', 'gitlab']

export default defineEventHandler((event) => {
  const configured = []
  const oauthProviders = useRuntimeConfig(event).oauth
  for (const provider of providers) {
    const providerConfig = oauthProviders[provider as keyof typeof oauthProviders]
    if (providerConfig.clientId && providerConfig.clientSecret) {
      configured.push(provider)
    }
  }

  return configured
})

Or, as we know that nuxt-auth-utils propagate variables in runtimeConfig:

export default defineEventHandler((event) => {
  const configured = []
  const oauthProviders = useRuntimeConfig(event).oauth
  for (const provider in oauthProviders) {
    const providerConfig = oauthProviders[provider as keyof typeof oauthProviders]
    if (providerConfig.clientId && providerConfig.clientSecret) {
      configured.push(provider)
    }
  }

  return configured
})

The only reason not to do that it is we also need to define a loader for each oauth provider existing or find a way to locally extract it, like:

// warning! uses internals
import { handlersMeta } from '#nitro-internal-virtual/server-handlers-meta'

const currentRoute = 'providers'
const authPrefix = '/auth/'

const definedProviders = handlersMeta.reduce((acc, { route }) => {
  if (route && route.startsWith(authPrefix) && route !== authPrefix + currentRoute) {
    acc.push(route.replace(authPrefix, ''))
  }
  return acc
}, [] as string[])

export default defineEventHandler((event) => {
  const nitroApp = useNitroApp()
  console.log(nitroApp.router.get)
  const configured = []
  const oauthProviders = useRuntimeConfig(event).oauth
  for (const provider of definedProviders) {
    const providerConfig = oauthProviders[provider as keyof typeof oauthProviders]
    if (providerConfig?.clientId && providerConfig?.clientSecret) {
      configured.push(provider)
    }
  }

  return configured
})

and also this example doesn't count bluesky, which doesn't follow oauth by default: https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#at-protocol

Image

Image

AndreyYolkin avatar Feb 24 '25 13:02 AndreyYolkin

@AndreyYolkin I think I'll refactor this as a route api (something like your first example) as Atinux suggested and I'll standardize this endpoint to more simply define a provider 🤔

HugoRCD avatar Feb 24 '25 13:02 HugoRCD

@AndreyYolkin And nothing to see but I pushed in prod most of what you suggested if you want to give me feedback on it or what to see if it's what you're thinking of!

HugoRCD avatar Feb 24 '25 13:02 HugoRCD

@AndreyYolkin And nothing to see but I pushed in prod most of what you suggested if you want to give me feedback on it or what to see if it's what you're thinking of!

I've already tried the changes you applied, thanks! I'll left some comments on dedicated issues, but generally speaking that's a great work

AndreyYolkin avatar Feb 24 '25 14:02 AndreyYolkin

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Apr 29 '25 02:04 github-actions[bot]