nuxt-auth-utils 0.5.8 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -0
- package/dist/runtime/server/plugins/ws.d.ts +2 -0
- package/dist/runtime/server/plugins/ws.js +7 -0
- package/dist/runtime/server/utils/session.d.ts +5 -2
- package/dist/runtime/server/utils/session.js +12 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ Add Authentication to Nuxt applications with secured & sealed cookies sessions.
|
|
|
23
23
|
- [Tree-shakable server utils](#server-utils)
|
|
24
24
|
- [`<AuthState>` component](#authstate-component)
|
|
25
25
|
- [Extendable with hooks](#extend-session)
|
|
26
|
+
- [WebSocket support](#websockets-support)
|
|
26
27
|
|
|
27
28
|
It has few dependencies (only from [UnJS](https://github.com/unjs)), run on multiple JS environments (Node, Deno, Workers) and is fully typed with TypeScript.
|
|
28
29
|
|
|
@@ -596,6 +597,65 @@ You can use the `placeholder` slot to show a placeholder on server-side and whil
|
|
|
596
597
|
|
|
597
598
|
If you are caching your routes with `routeRules`, please make sure to use [Nitro](https://github.com/unjs/nitro) >= `2.9.7` to support the client-side fetching of the user session.
|
|
598
599
|
|
|
600
|
+
## WebSockets Support
|
|
601
|
+
|
|
602
|
+
Nuxt Auth Utils is compatible with [Nitro WebSockets](https://nitro.build/guide/websocket).
|
|
603
|
+
|
|
604
|
+
Make sure to enable the `experimental.websocket` option in your `nuxt.config.ts`:
|
|
605
|
+
|
|
606
|
+
```ts
|
|
607
|
+
export default defineNuxtConfig({
|
|
608
|
+
nitro: {
|
|
609
|
+
experimental: {
|
|
610
|
+
websocket: true
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
})
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
You can use the `requireUserSession` function in the `upgrade` function to check if the user is authenticated before upgrading the WebSocket connection.
|
|
617
|
+
|
|
618
|
+
```ts
|
|
619
|
+
// server/routes/ws.ts
|
|
620
|
+
export default defineWebSocketHandler({
|
|
621
|
+
async upgrade(request) {
|
|
622
|
+
// Make sure the user is authenticated before upgrading the WebSocket connection
|
|
623
|
+
await requireUserSession(request)
|
|
624
|
+
},
|
|
625
|
+
async open(peer) {
|
|
626
|
+
const { user } = await requireUserSession(peer)
|
|
627
|
+
const username = Object.values(user).filter(Boolean).join(' ')
|
|
628
|
+
peer.send(`Hello, ${username}!`)
|
|
629
|
+
},
|
|
630
|
+
message(peer, message) {
|
|
631
|
+
peer.send(`Echo: ${message}`)
|
|
632
|
+
},
|
|
633
|
+
})
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Then, in your application, you can use the [useWebSocket](https://vueuse.org/core/useWebSocket/) composable to connect to the WebSocket:
|
|
637
|
+
|
|
638
|
+
```vue
|
|
639
|
+
<script setup>
|
|
640
|
+
const { status, data, send, open, close } = useWebSocket('/ws', { immediate: false })
|
|
641
|
+
|
|
642
|
+
// Only open the websocket after the page is hydrated (client-only)
|
|
643
|
+
onMounted(open)
|
|
644
|
+
</script>
|
|
645
|
+
|
|
646
|
+
<template>
|
|
647
|
+
<div>
|
|
648
|
+
<p>Status: {{ status }}</p>
|
|
649
|
+
<p>Data: {{ data }}</p>
|
|
650
|
+
<p>
|
|
651
|
+
<button @click="open">Open</button>
|
|
652
|
+
<button @click="close(1000, 'Closing')">Close</button>
|
|
653
|
+
<button @click="send('hello')">Send hello</button>
|
|
654
|
+
</p>
|
|
655
|
+
</div>
|
|
656
|
+
</template>
|
|
657
|
+
```
|
|
658
|
+
|
|
599
659
|
## Configuration
|
|
600
660
|
|
|
601
661
|
We leverage `runtimeConfig.session` to give the defaults option to [h3 `useSession`](https://h3.unjs.io/examples/handle-session).
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -33,6 +33,9 @@ const module = defineNuxtModule({
|
|
|
33
33
|
addPlugin(resolver.resolve("./runtime/app/plugins/session.client"));
|
|
34
34
|
addServerPlugin(resolver.resolve("./runtime/server/plugins/oauth"));
|
|
35
35
|
addServerImportsDir(resolver.resolve("./runtime/server/lib/oauth"));
|
|
36
|
+
if (nuxt.options.nitro?.experimental?.websocket) {
|
|
37
|
+
addServerPlugin(resolver.resolve("./runtime/server/plugins/ws"));
|
|
38
|
+
}
|
|
36
39
|
if (options.webAuthn) {
|
|
37
40
|
const missingDeps = [];
|
|
38
41
|
const peerDeps = ["@simplewebauthn/server", "@simplewebauthn/browser"];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { H3Event, SessionConfig } from 'h3';
|
|
2
|
+
import { useSession } from 'h3';
|
|
2
3
|
import type { UserSession, UserSessionRequired } from '#auth-utils';
|
|
4
|
+
type UseSessionEvent = Parameters<typeof useSession>[0];
|
|
3
5
|
export interface SessionHooks {
|
|
4
6
|
/**
|
|
5
7
|
* Called when fetching the session from the API
|
|
@@ -18,7 +20,7 @@ export declare const sessionHooks: import("hookable").Hookable<SessionHooks, imp
|
|
|
18
20
|
* @param event The Request (h3) event
|
|
19
21
|
* @returns The user session
|
|
20
22
|
*/
|
|
21
|
-
export declare function getUserSession(event:
|
|
23
|
+
export declare function getUserSession(event: UseSessionEvent): Promise<UserSession>;
|
|
22
24
|
/**
|
|
23
25
|
* Set a user session
|
|
24
26
|
* @param event The Request (h3) event
|
|
@@ -46,7 +48,8 @@ export declare function clearUserSession(event: H3Event, config?: Partial<Sessio
|
|
|
46
48
|
* @param opts.message The message to use for the error (defaults to Unauthorized)
|
|
47
49
|
* @see https://github.com/atinux/nuxt-auth-utils
|
|
48
50
|
*/
|
|
49
|
-
export declare function requireUserSession(event:
|
|
51
|
+
export declare function requireUserSession(event: UseSessionEvent, opts?: {
|
|
50
52
|
statusCode?: number;
|
|
51
53
|
message?: string;
|
|
52
54
|
}): Promise<UserSessionRequired>;
|
|
55
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useSession, createError } from "h3";
|
|
1
|
+
import { useSession, createError, isEvent } from "h3";
|
|
2
2
|
import { defu } from "defu";
|
|
3
3
|
import { createHooks } from "hookable";
|
|
4
4
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -26,17 +26,23 @@ export async function clearUserSession(event, config) {
|
|
|
26
26
|
export async function requireUserSession(event, opts = {}) {
|
|
27
27
|
const userSession = await getUserSession(event);
|
|
28
28
|
if (!userSession.user) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
if (isEvent(event)) {
|
|
30
|
+
throw createError({
|
|
31
|
+
statusCode: opts.statusCode || 401,
|
|
32
|
+
message: opts.message || "Unauthorized"
|
|
33
|
+
});
|
|
34
|
+
} else {
|
|
35
|
+
throw new Response(opts.message || "Unauthorized", {
|
|
36
|
+
status: opts.statusCode || 401
|
|
37
|
+
});
|
|
38
|
+
}
|
|
33
39
|
}
|
|
34
40
|
return userSession;
|
|
35
41
|
}
|
|
36
42
|
let sessionConfig;
|
|
37
43
|
function _useSession(event, config = {}) {
|
|
38
44
|
if (!sessionConfig) {
|
|
39
|
-
const runtimeConfig = useRuntimeConfig(event);
|
|
45
|
+
const runtimeConfig = useRuntimeConfig(isEvent(event) ? event : void 0);
|
|
40
46
|
const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || "NUXT_"}SESSION_PASSWORD`;
|
|
41
47
|
sessionConfig = defu({ password: process.env[envSessionPassword] }, runtimeConfig.session);
|
|
42
48
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-auth-utils",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"description": "Add Authentication to Nuxt applications with secured & sealed cookies sessions.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@adonisjs/hash": "^9.0.5",
|
|
39
39
|
"@nuxt/kit": "^3.15.2",
|
|
40
40
|
"defu": "^6.1.4",
|
|
41
|
-
"h3": "^1.
|
|
41
|
+
"h3": "^1.14.0",
|
|
42
42
|
"hookable": "^5.5.3",
|
|
43
43
|
"ofetch": "^1.4.1",
|
|
44
44
|
"ohash": "^1.1.4",
|