Skip to content

Commit

Permalink
refactor(secret-defaults): ♻️ Refactored logic to provide default sec…
Browse files Browse the repository at this point in the history
…rets
  • Loading branch information
itpropro committed Mar 25, 2024
1 parent 74cadf8 commit 45dd1da
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 36 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ This module's session implementation is based on [nuxt-auth-utils](https://githu

<!--- [Playground Demo](https://stackblitz.com/github/itpropro/nuxt-oidc-auth/tree/main/playground) -->

## ⚠️ Disclaimer

This module is still in development and contributions are welcome!

## Features

- Secured & sealed cookies sessions
Expand Down Expand Up @@ -222,7 +218,7 @@ const { logout, currentProvider } = useOidcAuth()
The above composable functions grant access to a user object with the following properties:
| Name | Type | Description |
|---|---|---|---|
|---|---|---|
| provider | `string` | Name of provider used to login the current session |
| canRefresh | `boolean` | If the current session exposed a refresh token |
| loggedInAt | `number` | Login timestamp in second precision |
Expand Down Expand Up @@ -346,6 +342,8 @@ You can theoretically register a hook that overwrites internal session fields li
| [providers](#providers) | `<provider>` | - | Configuration entries for each configured provider. For provider specific config see *Provider specific configurations* |
| [session](#session) | `AuthSessionConfig` | - | Optional session specific configuration |
| [middleware](#middleware) | `MiddlewareConfig` | - | Optional middleware specific configuration |
| [devMode](#dev-mode) | `DevModeConfig` | - | Configuration for local dev mode |
| provideDefaultSecrets | `boolean` | `true` | Provide defaults for NUXT_OIDC_SESSION_SECRET, NUXT_OIDC_TOKEN_KEY and NUXT_OIDC_AUTH_SESSION_SECRET using a Nitro plugin. Turning this off can lead to the app not working if no secrets are provided |
#### `providers`
Expand Down Expand Up @@ -467,7 +465,7 @@ To enable the dev mode, you have to make sure at least the following settings ar
### Token generation
If needed, the dev mode can generate a valid signed access token if the settting `devMode` -> `generateAccessToken` is set to `true`. This token will be exposed in the `user.accessToken` property.
The default properties on the generated token are
The properties on the generated token are
- `iat` (issued at): current DateTime,
- `iss` (issuer): `devMode.issuer` setting, default `nuxt:oidc:auth:issuer`
Expand Down Expand Up @@ -496,6 +494,10 @@ pnpm run dev:build
pnpm run lint
```
## ⚠️ Disclaimer
This module is still in development, feedback and contributions are welcome! Use at your own risk.
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/nuxt-oidc-auth?labelColor=18181B&color=28CF8D
[npm-version-href]: https://npmjs.com/package/nuxt-oidc-auth
Expand Down
46 changes: 16 additions & 30 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { defineNuxtModule, addPlugin, createResolver, addImportsDir, addServerHandler, useLogger, extendRouteRules, addRouteMiddleware } from '@nuxt/kit'
import { defineNuxtModule, addPlugin, createResolver, addImportsDir, addServerHandler, useLogger, extendRouteRules, addRouteMiddleware, addServerPlugin } from '@nuxt/kit'
import { defu } from 'defu'
import { subtle } from 'uncrypto'
import { genBase64FromBytes, generateRandomUrlSafeString } from './runtime/server/utils/security'
import * as providerPresets from './runtime/providers'
import type { OidcProviderConfig, ProviderConfigs, ProviderKeys } from './runtime/types/oidc'
import type { AuthSessionConfig } from './runtime/types/session'
Expand Down Expand Up @@ -94,6 +92,11 @@ export interface ModuleOptions {
* Dev mode configuration
*/
devMode?: DevModeConfig
/**
* Provide defaults for NUXT_OIDC_SESSION_SECRET, NUXT_OIDC_TOKEN_KEY and NUXT_OIDC_AUTH_SESSION_SECRET using a Nitro plugin. Turning this off can lead to the app not working if no secrets are provided.
* @default true
*/
provideDefaultSecrets?: boolean
}

declare module '@nuxt/schema' {
Expand Down Expand Up @@ -128,41 +131,24 @@ export default defineNuxtModule<ModuleOptions>({
globalMiddlewareEnabled: true,
customLoginPage: false,
},
provideDefaultSecrets: true,
},
async setup(options, nuxt) {
setup(options, nuxt) {
const logger = useLogger('nuxt-oidc-auth')

if (!options.enabled) { return }

// TODO: Find a better place to do the optional init to make setup sync again
if (!nuxt.options._prepare) {
if (!process.env.NUXT_OIDC_SESSION_SECRET || process.env.NUXT_OIDC_SESSION_SECRET.length < 48) {
const randomSecret = generateRandomUrlSafeString()
process.env.NUXT_OIDC_SESSION_SECRET = randomSecret
logger.warn('No session secret set, using a random secret. Please set NUXT_OIDC_SESSION_SECRET in your .env file with at least 48 chars.')
logger.info(`NUXT_OIDC_SESSION_SECRET=${randomSecret}`)
}
if (!process.env.NUXT_OIDC_TOKEN_KEY) {
const randomKey = genBase64FromBytes(new Uint8Array(await subtle.exportKey('raw', await subtle.generateKey({ name: 'AES-GCM', length: 256, }, true, ['encrypt', 'decrypt']))))
process.env.NUXT_OIDC_TOKEN_KEY = randomKey
logger.warn('No refresh token key set, using a random key. Please set NUXT_OIDC_TOKEN_KEY in your .env file. Refresh tokens saved in this session will be inaccessible after a server restart.')
logger.info(`NUXT_OIDC_TOKEN_KEY=${randomKey}`)
}
if (!process.env.NUXT_OIDC_AUTH_SESSION_SECRET) {
const randomKey = generateRandomUrlSafeString()
process.env.NUXT_OIDC_AUTH_SESSION_SECRET = randomKey
logger.warn('No auth session secret set, using a random secret. Please set NUXT_OIDC_AUTH_SESSION_SECRET in your .env file.')
logger.info(`NUXT_OIDC_AUTH_SESSION_SECRET=${randomKey}`)
}
}

// App
addImportsDir(resolve('./runtime/composables'))
addPlugin(resolve('./runtime/plugins/session.server'))

// Server
// Server (nitro) plugins
if (options.provideDefaultSecrets) {
addServerPlugin(resolve('./runtime/server/plugins/provideDefaults'))
}

// Server imports
if (nuxt.options.nitro.imports !== false) {
// TODO: address https://github.com/Atinux/nuxt-auth-utils/issues/1 upstream in unimport
nuxt.options.nitro.imports = defu(nuxt.options.nitro.imports, {
presets: [
{
Expand Down Expand Up @@ -201,7 +187,7 @@ export default defineNuxtModule<ModuleOptions>({
}

// Add default provider routes
if (import.meta.env['NODE_ENV'] === 'development' && options.devMode?.enabled) {
if (process.env['NODE_ENV'] && process.env['NODE_ENV'] === 'development' && options.devMode?.enabled) {
extendRouteRules('/auth/login', {
redirect: {
to: '/auth/dev/login',
Expand Down Expand Up @@ -232,7 +218,7 @@ export default defineNuxtModule<ModuleOptions>({
}

// Dev mode handler
if (import.meta.env['NODE_ENV'] === 'development' && options.devMode?.enabled) {
if (process.env['NODE_ENV'] && process.env['NODE_ENV'] === 'development' && options.devMode?.enabled) {
addServerHandler({
handler: resolve('./runtime/server/handler/dev'),
route: '/auth/dev/login',
Expand Down
23 changes: 23 additions & 0 deletions src/runtime/server/plugins/provideDefaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { genBase64FromBytes, generateRandomUrlSafeString } from '../utils/security'
import { subtle } from 'uncrypto'

export default defineNitroPlugin(async () => {
if (!process.env.NUXT_OIDC_SESSION_SECRET || process.env.NUXT_OIDC_SESSION_SECRET.length < 48) {
const randomSecret = generateRandomUrlSafeString()
process.env.NUXT_OIDC_SESSION_SECRET = randomSecret
console.warn('[nuxt-oidc-auth]: No session secret set, using a random secret. Please set NUXT_OIDC_SESSION_SECRET in your environment with at least 48 chars.')
console.info(`[nuxt-oidc-auth]: NUXT_OIDC_SESSION_SECRET=${randomSecret}`)
}
if (!process.env.NUXT_OIDC_TOKEN_KEY) {
const randomKey = genBase64FromBytes(new Uint8Array(await subtle.exportKey('raw', await subtle.generateKey({ name: 'AES-GCM', length: 256, }, true, ['encrypt', 'decrypt']))))
process.env.NUXT_OIDC_TOKEN_KEY = randomKey
console.warn('[nuxt-oidc-auth]: No refresh token key set, using a random key. Please set NUXT_OIDC_TOKEN_KEY in your environment. Refresh tokens saved in this session will be inaccessible after a server restart.')
console.info(`[nuxt-oidc-auth]: NUXT_OIDC_TOKEN_KEY=${randomKey}`)
}
if (!process.env.NUXT_OIDC_AUTH_SESSION_SECRET) {
const randomKey = generateRandomUrlSafeString()
process.env.NUXT_OIDC_AUTH_SESSION_SECRET = randomKey
console.warn('[nuxt-oidc-auth]: No auth session secret set, using a random secret. Please set NUXT_OIDC_AUTH_SESSION_SECRET in your environment.')
console.info(`[nuxt-oidc-auth]: NUXT_OIDC_AUTH_SESSION_SECRET=${randomKey}`)
}
})

0 comments on commit 45dd1da

Please sign in to comment.