Skip to content

Commit

Permalink
feat: add support for private data & config argument (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
atinux authored Sep 11, 2024
1 parent 7e381dc commit 875dd5b
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 10 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,18 @@ The following helpers are auto-imported in your `server/` directory.
```ts
// Set a user session, note that this data is encrypted in the cookie but can be decrypted with an API call
// Only store the data that allow you to recognize a user, but do not store sensitive data
// Merges new data with existing data using defu()
// Merges new data with existing data using unjs/defu library
await setUserSession(event, {
// User data
user: {
// ... user data
login: 'atinux'
},
// Private data accessible on server/ routes
secure: {
apiToken: '1234567890'
},
// Any extra fields for the session data
loggedInAt: new Date()
// Any extra fields
})

// Replace a user session. Same behaviour as setUserSession, except it does not merge data with existing data
Expand Down Expand Up @@ -359,6 +364,14 @@ Our defaults are:
}
```

You can also overwrite the session config by passing it as 3rd argument of the `setUserSession` and `replaceUserSession` functions:

```ts
await setUserSession(event, { ... } , {
maxAge: 60 * 60 * 24 * 7 // 1 week
})
```

Checkout the [`SessionConfig`](https://github.com/unjs/h3/blob/c04c458810e34eb15c1647e1369e7d7ef19f567d/src/utils/session.ts#L20) for all options.

## More
Expand Down
1 change: 1 addition & 0 deletions playground/auth.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ declare module '#auth-utils' {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extended?: any
loggedInAt: number
secure?: Record<string, unknown>
}
}

Expand Down
5 changes: 5 additions & 0 deletions playground/server/api/session.put.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default eventHandler(async (event) => {
const { session, config } = await readBody(event)

return setUserSession(event, session || {}, config)
})
4 changes: 3 additions & 1 deletion src/runtime/server/api/session.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ export default eventHandler(async (event) => {
await sessionHooks.callHookParallel('fetch', session as UserSessionRequired, event)
}

return session
const { secure, ...data } = session

return data
})
13 changes: 7 additions & 6 deletions src/runtime/server/utils/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export async function getUserSession(event: H3Event) {
* @param data User session data, please only store public information since it can be decoded with API calls
* @see https://github.com/atinux/nuxt-auth-utils
*/
export async function setUserSession(event: H3Event, data: UserSession) {
const session = await _useSession(event)
export async function setUserSession(event: H3Event, data: UserSession, config?: Partial<SessionConfig>) {
const session = await _useSession(event, config)

await session.update(defu(data, session.data))

Expand All @@ -47,8 +47,8 @@ export async function setUserSession(event: H3Event, data: UserSession) {
* @param event The Request (h3) event
* @param data User session data, please only store public information since it can be decoded with API calls
*/
export async function replaceUserSession(event: H3Event, data: UserSession) {
const session = await _useSession(event)
export async function replaceUserSession(event: H3Event, data: UserSession, config?: Partial<SessionConfig>) {
const session = await _useSession(event, config)

await session.clear()
await session.update(data)
Expand Down Expand Up @@ -93,13 +93,14 @@ export async function requireUserSession(event: H3Event, opts: { statusCode?: nu

let sessionConfig: SessionConfig

function _useSession(event: H3Event) {
function _useSession(event: H3Event, config: Partial<SessionConfig> = {}) {
if (!sessionConfig) {
const runtimeConfig = useRuntimeConfig(event)
const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || 'NUXT_'}SESSION_PASSWORD`

// @ts-expect-error hard to define with defu
sessionConfig = defu({ password: process.env[envSessionPassword] }, runtimeConfig.session)
}
return useSession<UserSession>(event, sessionConfig)
const finalConfig = defu(config, sessionConfig) as SessionConfig
return useSession<UserSession>(event, finalConfig)
}
11 changes: 11 additions & 0 deletions src/runtime/types/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ export interface User {
}

export interface UserSession {
/**
* User session data, available on client and server
*/
user?: User
/**
* Private session data, only available on server/ code
*/
secure?: Record<string, unknown>
/**
* Extra session data, available on client and server
*/
[key: string]: unknown
}

export interface UserSessionRequired extends UserSession {
Expand Down

0 comments on commit 875dd5b

Please sign in to comment.