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 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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "auth-utils",
3
3
  "configKey": "auth",
4
- "version": "0.5.8",
4
+ "version": "0.5.9",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
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"];
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nitropack/types").NitroAppPlugin;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineNitroPlugin } from "nitropack/runtime";
2
+ import { getUserSession } from "../utils/session.js";
3
+ export default defineNitroPlugin((nitroApp) => {
4
+ nitroApp.hooks.hook("request", async (event) => {
5
+ await getUserSession(event);
6
+ });
7
+ });
@@ -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: H3Event): Promise<UserSession>;
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: H3Event, opts?: {
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
- throw createError({
30
- statusCode: opts.statusCode || 401,
31
- message: opts.message || "Unauthorized"
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.8",
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.13.1",
41
+ "h3": "^1.14.0",
42
42
  "hookable": "^5.5.3",
43
43
  "ofetch": "^1.4.1",
44
44
  "ohash": "^1.1.4",