Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for private data & config argument #171

Merged
merged 1 commit into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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