Skip to content
This repository was archived by the owner on Dec 12, 2023. It is now read-only.

Commit 2b4cbb1

Browse files
authored
fix: allow unstorage drivers other than 'memory', add docs for redis-example (#7)
1 parent c050bae commit 2b4cbb1

File tree

6 files changed

+71
-17
lines changed

6 files changed

+71
-17
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,10 @@ Here's what the full _default_ module configuration looks like:
218218
// The session cookie same site policy is `lax`
219219
cookieSameSite: 'lax',
220220
// In-memory storage is used (these are `unjs/unstorage` options)
221-
storageOptions: {},
221+
storageOptions: {
222+
driver: 'memory',
223+
options: {}
224+
},
222225
// The request-domain is strictly used for the cookie, no sub-domains allowed
223226
domain: null,
224227
// Sessions aren't pinned to the user's IP address
@@ -235,6 +238,28 @@ Here's what the full _default_ module configuration looks like:
235238
}
236239
```
237240
241+
```
242+
#### Using a different storage driver
243+
244+
You can use any stroage driver supported by unstorage. For example, this will use the redis driver instead of the default memory driver.
245+
```ts
246+
//nuxt.config.ts
247+
{
248+
...,
249+
session: {
250+
session:{
251+
storageOptions:{
252+
driver: 'redis',
253+
options: {
254+
url: 'redis://localhost:6379'
255+
}
256+
}
257+
}
258+
}
259+
}
260+
261+
```
262+
238263
### Security
239264
240265
This section mostly contains a list of possible security problems and how to mitigate (some) of them. Note that the below flaws exist with many libraries and frameworks we use in our day-to-day when building and working with APIs. E.g., your vanilla-nuxt-app is not safe of some of them like the client sending malicious data. Missing in the below list are estimates of how likely it is that one of the list-items may occur and what impact it will have on your app. This is because that heavily depends on:

playground/nuxt.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ import { defineNuxtConfig } from 'nuxt/config'
22
import NuxtSession from '../src/module'
33

44
export default defineNuxtConfig({
5-
modules: [NuxtSession]
5+
modules: [NuxtSession],
6+
session: {}
67
})

src/module.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { addImportsDir, addServerHandler, createResolver, defineNuxtModule, useLogger } from '@nuxt/kit'
2-
import { CreateStorageOptions } from 'unstorage'
32
import { defu } from 'defu'
3+
import { builtinDrivers } from 'unstorage'
44
import type {
55
FilledModuleOptions,
66
ModuleOptions,
@@ -18,7 +18,10 @@ const defaults: FilledModuleOptions = {
1818
idLength: 64,
1919
storePrefix: 'sessions',
2020
cookieSameSite: 'lax',
21-
storageOptions: {} as CreateStorageOptions,
21+
storageOptions: {
22+
driver: 'memory',
23+
options: {}
24+
},
2225
domain: null,
2326
ipPinning: false as boolean|SessionIpPinningOptions
2427
},
@@ -59,6 +62,13 @@ export default defineNuxtModule<ModuleOptions>({
5962
const publicConfig: ModulePublicRuntimeConfig = { session: { api: options.api } }
6063
nuxt.options.runtimeConfig.public = defu(nuxt.options.runtimeConfig.public, publicConfig)
6164

65+
// setup unstorage
66+
nuxt.options.nitro.virtual = defu(nuxt.options.nitro.virtual, {
67+
'#session-driver': `export { default } from '${
68+
builtinDrivers[options.session.storageOptions.driver]
69+
}'`
70+
})
71+
6272
// 3. Locate runtime directory and transpile module
6373
const { resolve } = createResolver(import.meta.url)
6474

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { createStorage, prefixStorage } from 'unstorage'
2+
import { useRuntimeConfig } from '#imports'
3+
// @ts-ignore
4+
import sessionDriver from '#session-driver'
5+
const sessionConfig = useRuntimeConfig().session.session
6+
const driver = sessionDriver(sessionConfig.storageOptions.options)
7+
const storage = createStorage({ driver }).mount(sessionConfig.storePrefix, driver)
8+
export const sessionStorage = prefixStorage(storage, sessionConfig.storePrefix)
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import { createStorage, prefixStorage, StorageValue } from 'unstorage'
2-
import { useRuntimeConfig } from '#imports'
3-
4-
const storage = prefixStorage(createStorage(useRuntimeConfig().session.session.storageOptions), useRuntimeConfig().session.session.storePrefix)
5-
6-
export const getStorageSession = (sessionId: string) => storage.getItem(sessionId)
7-
export const setStorageSession = (sessionId: string, session: StorageValue) => storage.setItem(sessionId, session)
8-
export const dropStorageSession = (sessionId: string) => storage.removeItem(sessionId)
1+
import type { StorageValue } from 'unstorage'
2+
import { sessionStorage } from './sessionStorage'
3+
export const getStorageSession = (sessionId: string) => sessionStorage.getItem(sessionId)
4+
export const setStorageSession = (sessionId: string, session: StorageValue) => sessionStorage.setItem(sessionId, session)
5+
export const dropStorageSession = (sessionId: string) => sessionStorage.removeItem(sessionId)

src/types.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
import type { CreateStorageOptions } from 'unstorage'
1+
import type { BuiltinDriverName, CreateStorageOptions } from 'unstorage'
2+
import type { FSStorageOptions } from 'unstorage/dist/drivers/fs'
3+
import type { KVOptions } from 'unstorage/dist/drivers/cloudflare-kv-binding'
4+
import type { KVHTTPOptions } from 'unstorage/dist/drivers/cloudflare-kv-http'
5+
import type { GithubOptions } from 'unstorage/dist/drivers/github'
6+
import type { HTTPOptions } from 'unstorage/dist/drivers/http'
7+
import type { OverlayStorageOptions } from 'unstorage/dist/drivers/overlay'
8+
import type { LocalStorageOptions } from 'unstorage/dist/drivers/localstorage'
9+
import type { RedisOptions } from 'unstorage/dist/drivers/redis'
210

311
export type SameSiteOptions = 'lax' | 'strict' | 'none'
412
export type SupportedSessionApiMethods = 'patch' | 'delete' | 'get' | 'post'
513

14+
export type UnstorageDriverOption = FSStorageOptions | KVOptions | KVHTTPOptions | GithubOptions | HTTPOptions | OverlayStorageOptions | LocalStorageOptions | RedisOptions
15+
16+
export interface StorageOptions {
17+
driver: BuiltinDriverName,
18+
options?: UnstorageDriverOption
19+
}
620
export interface SessionIpPinningOptions {
721
/**
822
* The name of the HTTP header used to retrieve the forwarded (real) IP address of the user
@@ -45,12 +59,11 @@ export interface SessionOptions {
4559
cookieSameSite: SameSiteOptions
4660
/**
4761
* Driver configuration for session-storage. Per default in-memory storage is used
48-
* @default {}
49-
* @example { driver: redisDriver({ base: 'storage:' }) }
50-
* @type CreateStorageOptions
62+
* @default { driver: 'memory', options: {} }
63+
* @example { driver: 'redis', options: {url: 'redis://localhost:6739' } }
5164
* @docs https://github.com/unjs/unstorage
5265
*/
53-
storageOptions: CreateStorageOptions,
66+
storageOptions: StorageOptions,
5467
/**
5568
* Set the domain the session cookie will be receivable by. Setting `domain: null` results in setting the domain the cookie is initially set on. Specifying a domain will allow the domain and all its sub-domains.
5669
* @default null

0 commit comments

Comments
 (0)