nuxt-auth-utils 0.0.24 → 0.1.0
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 +72 -4
- package/dist/module.json +5 -1
- package/dist/module.mjs +7 -24
- package/dist/runtime/app/components/AuthState.vue +17 -0
- package/dist/runtime/{composables → app/composables}/session.d.ts +4 -0
- package/dist/runtime/{composables/session.mjs → app/composables/session.js} +7 -0
- package/dist/runtime/app/plugins/session.client.js +8 -0
- package/dist/runtime/app/plugins/session.server.js +11 -0
- package/dist/runtime/server/api/{session.delete.mjs → session.delete.js} +1 -1
- package/dist/runtime/server/api/session.get.d.ts +1 -1
- package/dist/runtime/server/api/{session.get.mjs → session.get.js} +1 -1
- package/dist/runtime/server/lib/oauth/auth0.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/battledotnet.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/cognito.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/discord.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/facebook.d.ts +8 -1
- package/dist/runtime/server/lib/oauth/{facebook.mjs → facebook.js} +3 -1
- package/dist/runtime/server/lib/oauth/github.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/google.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/keycloak.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/spotify.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/twitch.d.ts +1 -1
- package/dist/runtime/server/plugins/oauth.d.ts +2 -0
- package/dist/runtime/server/plugins/oauth.js +16 -0
- package/dist/runtime/server/utils/oauth.d.ts +12 -12
- package/dist/runtime/server/utils/oauth.js +26 -0
- package/dist/runtime/server/utils/session.d.ts +15 -3
- package/dist/runtime/types/index.d.ts +2 -2
- package/dist/runtime/types/oauth-config.js +0 -0
- package/dist/runtime/types/session.d.ts +19 -0
- package/dist/runtime/types/session.js +0 -0
- package/dist/types.d.mts +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +15 -14
- package/dist/runtime/plugins/session.server.d.ts +0 -2
- package/dist/runtime/plugins/session.server.mjs +0 -9
- package/dist/runtime/server/utils/oauth.mjs +0 -26
- /package/dist/runtime/{types/index.mjs → app/plugins/session.client.d.ts} +0 -0
- /package/dist/runtime/{types/oauth-config.mjs → app/plugins/session.server.d.ts} +0 -0
- /package/dist/runtime/server/lib/oauth/{auth0.mjs → auth0.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{battledotnet.mjs → battledotnet.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{cognito.mjs → cognito.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{discord.mjs → discord.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{github.mjs → github.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{google.mjs → google.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{keycloak.mjs → keycloak.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{linkedin.mjs → linkedin.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{microsoft.mjs → microsoft.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{spotify.mjs → spotify.js} +0 -0
- /package/dist/runtime/server/lib/oauth/{twitch.mjs → twitch.js} +0 -0
- /package/dist/runtime/server/utils/{session.mjs → session.js} +0 -0
- /package/dist/runtime/types/{session.mjs → index.js} +0 -0
package/README.md
CHANGED
|
@@ -14,12 +14,13 @@ Minimalist Authentication module for Nuxt exposing Vue composables and server ut
|
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
+
- Support for Hybrid Rendering (SSR / CSR / SWR / Prerendering)
|
|
17
18
|
- Secured & sealed cookies sessions
|
|
18
19
|
- [OAuth Providers](#supported-oauth-providers)
|
|
19
20
|
|
|
20
21
|
## Requirements
|
|
21
22
|
|
|
22
|
-
This module only works with
|
|
23
|
+
This module only works with the Nuxt server running as it uses server API routes. This means that you cannot use this module with `nuxt generate`.
|
|
23
24
|
|
|
24
25
|
## Quick Setup
|
|
25
26
|
|
|
@@ -72,7 +73,7 @@ The following helpers are auto-imported in your `server/` directory.
|
|
|
72
73
|
|
|
73
74
|
```ts
|
|
74
75
|
// Set a user session, note that this data is encrypted in the cookie but can be decrypted with an API call
|
|
75
|
-
// Only store the data that allow you to recognize
|
|
76
|
+
// Only store the data that allow you to recognize a user, but do not store sensitive data
|
|
76
77
|
// Merges new data with existing data using defu()
|
|
77
78
|
await setUserSession(event, {
|
|
78
79
|
user: {
|
|
@@ -118,7 +119,7 @@ All helpers are exposed from the `oauth` global variable and can be used in your
|
|
|
118
119
|
|
|
119
120
|
The pattern is `oauth.<provider>EventHandler({ onSuccess, config?, onError? })`, example: `oauth.githubEventHandler`.
|
|
120
121
|
|
|
121
|
-
The helper returns an event handler that automatically redirects to the provider authorization page and then
|
|
122
|
+
The helper returns an event handler that automatically redirects to the provider authorization page and then calls `onSuccess` or `onError` depending on the result.
|
|
122
123
|
|
|
123
124
|
The `config` can be defined directly from the `runtimeConfig` in your `nuxt.config.ts`:
|
|
124
125
|
|
|
@@ -186,7 +187,7 @@ Make sure to set the callback URL in your OAuth app settings as `<your-domain>/a
|
|
|
186
187
|
|
|
187
188
|
### Extend Session
|
|
188
189
|
|
|
189
|
-
We leverage hooks to let you extend the session data with your own data or
|
|
190
|
+
We leverage hooks to let you extend the session data with your own data or log when the user clears the session.
|
|
190
191
|
|
|
191
192
|
```ts
|
|
192
193
|
// server/plugins/session.ts
|
|
@@ -206,6 +207,69 @@ export default defineNitroPlugin(() => {
|
|
|
206
207
|
})
|
|
207
208
|
```
|
|
208
209
|
|
|
210
|
+
## Server-Side Rendering
|
|
211
|
+
|
|
212
|
+
You can make authenticated requests both from the client and the server. However, you must use `useRequestFetch()` to make authenticated requests during SSR if you are not using `useFetch()`
|
|
213
|
+
|
|
214
|
+
```vue
|
|
215
|
+
<script setup lang="ts">
|
|
216
|
+
// When using useAsyncData
|
|
217
|
+
const { data } = await useAsyncData('team', () => useRequestFetch()('/api/protected-endpoint'))
|
|
218
|
+
|
|
219
|
+
// useFetch will automatically use useRequestFetch during SSR
|
|
220
|
+
const { data } = await useFetch('/api/protected-endpoint')
|
|
221
|
+
</script>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
> There's [an open issue](https://github.com/nuxt/nuxt/issues/24813) to include credentials in `$fetch` in Nuxt.
|
|
225
|
+
|
|
226
|
+
## Hybrid Rendering
|
|
227
|
+
|
|
228
|
+
When using [Nuxt `routeRules`](https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering) to prerender or cache your pages, Nuxt Auth Utils will not fetch the user session during prerendering but instead fetch it on the client-side (after hydration).
|
|
229
|
+
|
|
230
|
+
This is because the user session is stored in a secure cookie and cannot be accessed during prerendering.
|
|
231
|
+
|
|
232
|
+
**This means that you should not rely on the user session during prerendering.**
|
|
233
|
+
|
|
234
|
+
### `<AuthState>` component
|
|
235
|
+
|
|
236
|
+
You can use the `<AuthState>` component to safely display auth-related data in your components without worrying about the rendering mode.
|
|
237
|
+
|
|
238
|
+
One common use case if the Login button in the header:
|
|
239
|
+
|
|
240
|
+
```vue
|
|
241
|
+
<template>
|
|
242
|
+
<header>
|
|
243
|
+
<AuthState v-slot="{ loggedIn, clear }">
|
|
244
|
+
<button v-if="loggedIn" @click="clear">Logout</button>
|
|
245
|
+
<NuxtLink v-else to="/login">Login</NuxtLink>
|
|
246
|
+
</AuthState>
|
|
247
|
+
</header>
|
|
248
|
+
</template>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
If the page is cached or prerendered, nothing will be rendered until the user session is fetched on the client-side.
|
|
252
|
+
|
|
253
|
+
You can use the `placeholder` slot to show a placeholder on server-side and while the user session is being fetched on client-side for the prerendered pages:
|
|
254
|
+
|
|
255
|
+
```vue
|
|
256
|
+
<template>
|
|
257
|
+
<header>
|
|
258
|
+
<AuthState>
|
|
259
|
+
<template #default="{ loggedIn, clear }">
|
|
260
|
+
<button v-if="loggedIn" @click="clear">Logout</button>
|
|
261
|
+
<NuxtLink v-else to="/login">Login</NuxtLink>
|
|
262
|
+
</template>
|
|
263
|
+
<template #placeholder>
|
|
264
|
+
<button disabled>Loading...</button>
|
|
265
|
+
</template>
|
|
266
|
+
</AuthState>
|
|
267
|
+
</header>
|
|
268
|
+
</template>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
If you are caching your routes with `routeRules`, please make sure to use [`nitro-nightly`](https://nitro.unjs.io/guide/nightly) or Nitro >= `2.10.0` to support the client-side fetching of the user session.
|
|
272
|
+
|
|
209
273
|
## Configuration
|
|
210
274
|
|
|
211
275
|
We leverage `runtimeConfig.session` to give the defaults option to [h3 `useSession`](https://h3.unjs.io/examples/handle-session).
|
|
@@ -237,6 +301,10 @@ Our defaults are:
|
|
|
237
301
|
|
|
238
302
|
Checkout the [`SessionConfig`](https://github.com/unjs/h3/blob/c04c458810e34eb15c1647e1369e7d7ef19f567d/src/utils/session.ts#L20) for all options.
|
|
239
303
|
|
|
304
|
+
## More
|
|
305
|
+
|
|
306
|
+
- [nuxt-authorization](https://github.com/barbapapazes/nuxt-authorization): Authorization module for managing permissions inside a Nuxt app, compatible with `nuxt-auth-utils`
|
|
307
|
+
|
|
240
308
|
## Development
|
|
241
309
|
|
|
242
310
|
```bash
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { defineNuxtModule, createResolver, addImportsDir, addPlugin, addServerHandler } from '@nuxt/kit';
|
|
2
|
+
import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir, addPlugin, addServerPlugin, addServerImportsDir, addServerHandler } from '@nuxt/kit';
|
|
3
3
|
import { join } from 'pathe';
|
|
4
4
|
import { defu } from 'defu';
|
|
5
5
|
import { randomUUID } from 'uncrypto';
|
|
@@ -14,29 +14,12 @@ const module = defineNuxtModule({
|
|
|
14
14
|
async setup(options, nuxt) {
|
|
15
15
|
const resolver = createResolver(import.meta.url);
|
|
16
16
|
nuxt.options.alias["#auth-utils"] = resolver.resolve("./runtime/types/index");
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
from: resolver.resolve("./runtime/server/utils/oauth"),
|
|
24
|
-
imports: ["oauth"]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
from: resolver.resolve("./runtime/server/utils/session"),
|
|
28
|
-
imports: [
|
|
29
|
-
"sessionHooks",
|
|
30
|
-
"getUserSession",
|
|
31
|
-
"setUserSession",
|
|
32
|
-
"replaceUserSession",
|
|
33
|
-
"clearUserSession",
|
|
34
|
-
"requireUserSession"
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
});
|
|
39
|
-
}
|
|
17
|
+
addComponentsDir({ path: resolver.resolve("./runtime/app/components") });
|
|
18
|
+
addImportsDir(resolver.resolve("./runtime/app/composables"));
|
|
19
|
+
addPlugin(resolver.resolve("./runtime/app/plugins/session.server"));
|
|
20
|
+
addPlugin(resolver.resolve("./runtime/app/plugins/session.client"));
|
|
21
|
+
addServerPlugin(resolver.resolve("./runtime/server/plugins/oauth"));
|
|
22
|
+
addServerImportsDir(resolver.resolve("./runtime/server/utils"));
|
|
40
23
|
addServerHandler({
|
|
41
24
|
handler: resolver.resolve("./runtime/server/api/session.delete"),
|
|
42
25
|
route: "/api/_auth/session",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useUserSession } from '#imports'
|
|
3
|
+
|
|
4
|
+
const userSession = useUserSession()
|
|
5
|
+
const { ready } = userSession
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<slot
|
|
10
|
+
v-if="ready"
|
|
11
|
+
v-bind="userSession"
|
|
12
|
+
/>
|
|
13
|
+
<slot
|
|
14
|
+
v-else
|
|
15
|
+
name="placeholder"
|
|
16
|
+
/>
|
|
17
|
+
</template>
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { useState, computed, useRequestFetch } from "#imports";
|
|
2
2
|
const useSessionState = () => useState("nuxt-session", () => ({}));
|
|
3
|
+
const useAuthReadyState = () => useState("nuxt-auth-ready", () => false);
|
|
3
4
|
export function useUserSession() {
|
|
4
5
|
const sessionState = useSessionState();
|
|
6
|
+
const authReadyState = useAuthReadyState();
|
|
5
7
|
return {
|
|
8
|
+
ready: computed(() => authReadyState.value),
|
|
6
9
|
loggedIn: computed(() => Boolean(sessionState.value.user)),
|
|
7
10
|
user: computed(() => sessionState.value.user || null),
|
|
8
11
|
session: sessionState,
|
|
@@ -11,12 +14,16 @@ export function useUserSession() {
|
|
|
11
14
|
};
|
|
12
15
|
}
|
|
13
16
|
async function fetch() {
|
|
17
|
+
const authReadyState = useAuthReadyState();
|
|
14
18
|
useSessionState().value = await useRequestFetch()("/api/_auth/session", {
|
|
15
19
|
headers: {
|
|
16
20
|
Accept: "text/json"
|
|
17
21
|
},
|
|
18
22
|
retry: false
|
|
19
23
|
}).catch(() => ({}));
|
|
24
|
+
if (!authReadyState.value) {
|
|
25
|
+
authReadyState.value = true;
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
28
|
async function clear() {
|
|
22
29
|
await $fetch("/api/_auth/session", { method: "DELETE" });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useUserSession } from "#imports";
|
|
2
|
+
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
3
|
+
if (!nuxtApp.payload.serverRendered || Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached)) {
|
|
4
|
+
nuxtApp.hook("app:mounted", async () => {
|
|
5
|
+
await useUserSession().fetch();
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRequestEvent, useUserSession } from "#imports";
|
|
2
|
+
export default defineNuxtPlugin({
|
|
3
|
+
name: "session-fetch-plugin",
|
|
4
|
+
enforce: "pre",
|
|
5
|
+
async setup(nuxtApp) {
|
|
6
|
+
nuxtApp.payload.isCached = Boolean(useRequestEvent()?.context.cache);
|
|
7
|
+
if (nuxtApp.payload.serverRendered && !nuxtApp.payload.prerenderedAt && !nuxtApp.payload.isCached) {
|
|
8
|
+
await useUserSession().fetch();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<UserSessionRequired>>;
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../types").UserSessionRequired>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { eventHandler } from "h3";
|
|
2
|
-
import { requireUserSession, sessionHooks } from "../utils/session.
|
|
2
|
+
import { requireUserSession, sessionHooks } from "../utils/session.js";
|
|
3
3
|
export default eventHandler(async (event) => {
|
|
4
4
|
const session = await requireUserSession(event);
|
|
5
5
|
await sessionHooks.callHookParallel("fetch", session, event);
|
|
@@ -52,4 +52,4 @@ export interface OAuthAuth0Config {
|
|
|
52
52
|
*/
|
|
53
53
|
authorizationParams?: Record<string, string>;
|
|
54
54
|
}
|
|
55
|
-
export declare function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
55
|
+
export declare function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -40,4 +40,4 @@ export interface OAuthBattledotnetConfig {
|
|
|
40
40
|
*/
|
|
41
41
|
authorizationParams?: Record<string, string>;
|
|
42
42
|
}
|
|
43
|
-
export declare function battledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
43
|
+
export declare function battledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -31,4 +31,4 @@ export interface OAuthCognitoConfig {
|
|
|
31
31
|
*/
|
|
32
32
|
authorizationParams?: Record<string, string>;
|
|
33
33
|
}
|
|
34
|
-
export declare function cognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
34
|
+
export declare function cognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -45,4 +45,4 @@ export interface OAuthDiscordConfig {
|
|
|
45
45
|
*/
|
|
46
46
|
authorizationParams?: Record<string, string>;
|
|
47
47
|
}
|
|
48
|
-
export declare function discordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
48
|
+
export declare function discordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -17,6 +17,13 @@ export interface OAuthFacebookConfig {
|
|
|
17
17
|
* @example [ 'email' ],
|
|
18
18
|
*/
|
|
19
19
|
scope?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Facebook OAuth User Fields
|
|
22
|
+
* @default [ 'id', 'name'],
|
|
23
|
+
* @see https://developers.facebook.com/docs/graph-api/guides/field-expansion
|
|
24
|
+
* @example [ 'id', 'name', 'email' ],
|
|
25
|
+
*/
|
|
26
|
+
fields?: string[];
|
|
20
27
|
/**
|
|
21
28
|
* Facebook OAuth Authorization URL
|
|
22
29
|
* @default 'https://www.facebook.com/v19.0/dialog/oauth'
|
|
@@ -33,4 +40,4 @@ export interface OAuthFacebookConfig {
|
|
|
33
40
|
*/
|
|
34
41
|
authorizationParams?: Record<string, string>;
|
|
35
42
|
}
|
|
36
|
-
export declare function facebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
43
|
+
export declare function facebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -72,8 +72,10 @@ export function facebookEventHandler({
|
|
|
72
72
|
return onError(event, error);
|
|
73
73
|
}
|
|
74
74
|
const accessToken = tokens.access_token;
|
|
75
|
+
config.fields = config.fields || ["id", "name"];
|
|
76
|
+
const fields = config.fields.join(",");
|
|
75
77
|
const user = await ofetch(
|
|
76
|
-
`https://graph.facebook.com/v19.0/me?fields
|
|
78
|
+
`https://graph.facebook.com/v19.0/me?fields=${fields}&access_token=${accessToken}`
|
|
77
79
|
);
|
|
78
80
|
if (!user) {
|
|
79
81
|
throw new Error("Facebook login failed: no user found");
|
|
@@ -39,4 +39,4 @@ export interface OAuthGitHubConfig {
|
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
41
|
}
|
|
42
|
-
export declare function githubEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthGitHubConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
42
|
+
export declare function githubEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthGitHubConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -39,4 +39,4 @@ export interface OAuthGoogleConfig {
|
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
41
|
}
|
|
42
|
-
export declare function googleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
42
|
+
export declare function googleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -33,4 +33,4 @@ export interface OAuthKeycloakConfig {
|
|
|
33
33
|
*/
|
|
34
34
|
authorizationParams?: Record<string, string>;
|
|
35
35
|
}
|
|
36
|
-
export declare function keycloakEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthKeycloakConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
36
|
+
export declare function keycloakEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthKeycloakConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -39,4 +39,4 @@ export interface OAuthSpotifyConfig {
|
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
41
|
}
|
|
42
|
-
export declare function spotifyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSpotifyConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
42
|
+
export declare function spotifyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSpotifyConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -39,4 +39,4 @@ export interface OAuthTwitchConfig {
|
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
41
|
}
|
|
42
|
-
export declare function twitchEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTwitchConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
42
|
+
export declare function twitchEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTwitchConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineNitroPlugin } from "nitropack/runtime";
|
|
2
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
3
|
+
if (process.env.NUXT_OAUTH_FACEBOOK_CLIENT_ID && process.env.NUXT_OAUTH_FACEBOOK_CLIENT_SECRET) {
|
|
4
|
+
nitroApp.hooks.hook("render:html", (html) => {
|
|
5
|
+
html.head.unshift(`
|
|
6
|
+
<script>
|
|
7
|
+
if (window.location.hash === "#_=_"){
|
|
8
|
+
history.replaceState
|
|
9
|
+
? history.replaceState(null, null, window.location.href.split("#")[0])
|
|
10
|
+
: window.location.hash = "";
|
|
11
|
+
}
|
|
12
|
+
<\/script>
|
|
13
|
+
`);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { githubEventHandler } from '../lib/oauth/github';
|
|
2
|
-
import { googleEventHandler } from '../lib/oauth/google';
|
|
3
|
-
import { spotifyEventHandler } from '../lib/oauth/spotify';
|
|
4
|
-
import { twitchEventHandler } from '../lib/oauth/twitch';
|
|
5
|
-
import { auth0EventHandler } from '../lib/oauth/auth0';
|
|
6
|
-
import { microsoftEventHandler } from '../lib/oauth/microsoft';
|
|
7
|
-
import { discordEventHandler } from '../lib/oauth/discord';
|
|
8
|
-
import { battledotnetEventHandler } from '../lib/oauth/battledotnet';
|
|
9
|
-
import { keycloakEventHandler } from '../lib/oauth/keycloak';
|
|
10
|
-
import { linkedinEventHandler } from '../lib/oauth/linkedin';
|
|
11
|
-
import { cognitoEventHandler } from '../lib/oauth/cognito';
|
|
12
|
-
import { facebookEventHandler } from '../lib/oauth/facebook';
|
|
1
|
+
import { githubEventHandler } from '../lib/oauth/github.js';
|
|
2
|
+
import { googleEventHandler } from '../lib/oauth/google.js';
|
|
3
|
+
import { spotifyEventHandler } from '../lib/oauth/spotify.js';
|
|
4
|
+
import { twitchEventHandler } from '../lib/oauth/twitch.js';
|
|
5
|
+
import { auth0EventHandler } from '../lib/oauth/auth0.js';
|
|
6
|
+
import { microsoftEventHandler } from '../lib/oauth/microsoft.js';
|
|
7
|
+
import { discordEventHandler } from '../lib/oauth/discord.js';
|
|
8
|
+
import { battledotnetEventHandler } from '../lib/oauth/battledotnet.js';
|
|
9
|
+
import { keycloakEventHandler } from '../lib/oauth/keycloak.js';
|
|
10
|
+
import { linkedinEventHandler } from '../lib/oauth/linkedin.js';
|
|
11
|
+
import { cognitoEventHandler } from '../lib/oauth/cognito.js';
|
|
12
|
+
import { facebookEventHandler } from '../lib/oauth/facebook.js';
|
|
13
13
|
export declare const oauth: {
|
|
14
14
|
githubEventHandler: typeof githubEventHandler;
|
|
15
15
|
spotifyEventHandler: typeof spotifyEventHandler;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { githubEventHandler } from "../lib/oauth/github.js";
|
|
2
|
+
import { googleEventHandler } from "../lib/oauth/google.js";
|
|
3
|
+
import { spotifyEventHandler } from "../lib/oauth/spotify.js";
|
|
4
|
+
import { twitchEventHandler } from "../lib/oauth/twitch.js";
|
|
5
|
+
import { auth0EventHandler } from "../lib/oauth/auth0.js";
|
|
6
|
+
import { microsoftEventHandler } from "../lib/oauth/microsoft.js";
|
|
7
|
+
import { discordEventHandler } from "../lib/oauth/discord.js";
|
|
8
|
+
import { battledotnetEventHandler } from "../lib/oauth/battledotnet.js";
|
|
9
|
+
import { keycloakEventHandler } from "../lib/oauth/keycloak.js";
|
|
10
|
+
import { linkedinEventHandler } from "../lib/oauth/linkedin.js";
|
|
11
|
+
import { cognitoEventHandler } from "../lib/oauth/cognito.js";
|
|
12
|
+
import { facebookEventHandler } from "../lib/oauth/facebook.js";
|
|
13
|
+
export const oauth = {
|
|
14
|
+
githubEventHandler,
|
|
15
|
+
spotifyEventHandler,
|
|
16
|
+
googleEventHandler,
|
|
17
|
+
twitchEventHandler,
|
|
18
|
+
auth0EventHandler,
|
|
19
|
+
microsoftEventHandler,
|
|
20
|
+
discordEventHandler,
|
|
21
|
+
battledotnetEventHandler,
|
|
22
|
+
keycloakEventHandler,
|
|
23
|
+
linkedinEventHandler,
|
|
24
|
+
cognitoEventHandler,
|
|
25
|
+
facebookEventHandler
|
|
26
|
+
};
|
|
@@ -13,26 +13,38 @@ export interface SessionHooks {
|
|
|
13
13
|
clear: (session: UserSession, event: H3Event) => void | Promise<void>;
|
|
14
14
|
}
|
|
15
15
|
export declare const sessionHooks: import("hookable").Hookable<SessionHooks, import("hookable").HookKeys<SessionHooks>>;
|
|
16
|
+
/**
|
|
17
|
+
* Get the user session from the current request
|
|
18
|
+
* @param event The Request (h3) event
|
|
19
|
+
* @returns The user session
|
|
20
|
+
*/
|
|
16
21
|
export declare function getUserSession(event: H3Event): Promise<UserSession>;
|
|
17
22
|
/**
|
|
18
23
|
* Set a user session
|
|
19
|
-
* @param event
|
|
24
|
+
* @param event The Request (h3) event
|
|
20
25
|
* @param data User session data, please only store public information since it can be decoded with API calls
|
|
26
|
+
* @see https://github.com/atinux/nuxt-auth-utils
|
|
21
27
|
*/
|
|
22
28
|
export declare function setUserSession(event: H3Event, data: UserSession): Promise<UserSession>;
|
|
23
29
|
/**
|
|
24
30
|
* Replace a user session
|
|
25
|
-
* @param event
|
|
31
|
+
* @param event The Request (h3) event
|
|
26
32
|
* @param data User session data, please only store public information since it can be decoded with API calls
|
|
27
33
|
*/
|
|
28
34
|
export declare function replaceUserSession(event: H3Event, data: UserSession): Promise<UserSession>;
|
|
35
|
+
/**
|
|
36
|
+
* Clear the user session and removing the session cookie
|
|
37
|
+
* @param event The Request (h3) event
|
|
38
|
+
* @returns true if the session was cleared
|
|
39
|
+
*/
|
|
29
40
|
export declare function clearUserSession(event: H3Event): Promise<boolean>;
|
|
30
41
|
/**
|
|
31
|
-
* Require a user session
|
|
42
|
+
* Require a user session, throw a 401 error if the user is not logged in
|
|
32
43
|
* @param event
|
|
33
44
|
* @param opts Options to customize the error message and status code
|
|
34
45
|
* @param opts.statusCode The status code to use for the error (defaults to 401)
|
|
35
46
|
* @param opts.message The message to use for the error (defaults to Unauthorized)
|
|
47
|
+
* @see https://github.com/atinux/nuxt-auth-utils
|
|
36
48
|
*/
|
|
37
49
|
export declare function requireUserSession(event: H3Event, opts?: {
|
|
38
50
|
statusCode?: number;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { User, UserSession, UserSessionRequired, UserSessionComposable } from './session';
|
|
2
|
-
export type { OAuthConfig } from './oauth-config';
|
|
1
|
+
export type { User, UserSession, UserSessionRequired, UserSessionComposable } from './session.js';
|
|
2
|
+
export type { OAuthConfig } from './oauth-config.js';
|
|
File without changes
|
|
@@ -8,9 +8,28 @@ export interface UserSessionRequired extends UserSession {
|
|
|
8
8
|
user: User;
|
|
9
9
|
}
|
|
10
10
|
export interface UserSessionComposable {
|
|
11
|
+
/**
|
|
12
|
+
* Computed indicating if the auth session is ready
|
|
13
|
+
*/
|
|
14
|
+
ready: ComputedRef<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Computed indicating if the user is logged in.
|
|
17
|
+
*/
|
|
11
18
|
loggedIn: ComputedRef<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* The user object if logged in, null otherwise.
|
|
21
|
+
*/
|
|
12
22
|
user: ComputedRef<User | null>;
|
|
23
|
+
/**
|
|
24
|
+
* The session object.
|
|
25
|
+
*/
|
|
13
26
|
session: Ref<UserSession>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch the user session from the server.
|
|
29
|
+
*/
|
|
14
30
|
fetch: () => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Clear the user session and remove the session cookie.
|
|
33
|
+
*/
|
|
15
34
|
clear: () => Promise<void>;
|
|
16
35
|
}
|
|
File without changes
|
package/dist/types.d.mts
CHANGED
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-auth-utils",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Minimalist Auth module for Nuxt with SSR",
|
|
5
5
|
"repository": "Atinux/nuxt-auth-utils",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"packageManager": "pnpm@9.1.3",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
11
|
"types": "./dist/types.d.ts",
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"test:watch": "vitest watch"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@nuxt/kit": "^3.
|
|
34
|
+
"@nuxt/kit": "^3.12.2",
|
|
34
35
|
"defu": "^6.1.4",
|
|
35
36
|
"hookable": "^5.5.3",
|
|
36
37
|
"ofetch": "^1.3.4",
|
|
@@ -39,20 +40,20 @@
|
|
|
39
40
|
"uncrypto": "^0.1.3"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@iconify-json/simple-icons": "^1.1.
|
|
43
|
+
"@iconify-json/simple-icons": "^1.1.106",
|
|
43
44
|
"@nuxt/devtools": "latest",
|
|
44
|
-
"@nuxt/eslint-config": "^0.3.
|
|
45
|
-
"@nuxt/module-builder": "^0.
|
|
46
|
-
"@nuxt/schema": "^3.
|
|
47
|
-
"@nuxt/test-utils": "^3.
|
|
48
|
-
"@nuxt/ui": "^2.
|
|
49
|
-
"@nuxt/ui-pro": "^1.
|
|
50
|
-
"@types/node": "^20.
|
|
45
|
+
"@nuxt/eslint-config": "^0.3.13",
|
|
46
|
+
"@nuxt/module-builder": "^0.7.1",
|
|
47
|
+
"@nuxt/schema": "^3.12.2",
|
|
48
|
+
"@nuxt/test-utils": "^3.13.1",
|
|
49
|
+
"@nuxt/ui": "^2.17.0",
|
|
50
|
+
"@nuxt/ui-pro": "^1.3.0",
|
|
51
|
+
"@types/node": "^20.14.4",
|
|
51
52
|
"changelogen": "^0.5.5",
|
|
52
|
-
"eslint": "^9.
|
|
53
|
-
"nuxt": "^3.
|
|
53
|
+
"eslint": "^9.5.0",
|
|
54
|
+
"nuxt": "^3.12.2",
|
|
54
55
|
"typescript": "^5.4.5",
|
|
55
|
-
"vitest": "^1.
|
|
56
|
-
"vue-tsc": "^2.0.
|
|
56
|
+
"vitest": "^1.6.0",
|
|
57
|
+
"vue-tsc": "^2.0.21"
|
|
57
58
|
}
|
|
58
59
|
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { githubEventHandler } from "../lib/oauth/github.mjs";
|
|
2
|
-
import { googleEventHandler } from "../lib/oauth/google.mjs";
|
|
3
|
-
import { spotifyEventHandler } from "../lib/oauth/spotify.mjs";
|
|
4
|
-
import { twitchEventHandler } from "../lib/oauth/twitch.mjs";
|
|
5
|
-
import { auth0EventHandler } from "../lib/oauth/auth0.mjs";
|
|
6
|
-
import { microsoftEventHandler } from "../lib/oauth/microsoft.mjs";
|
|
7
|
-
import { discordEventHandler } from "../lib/oauth/discord.mjs";
|
|
8
|
-
import { battledotnetEventHandler } from "../lib/oauth/battledotnet.mjs";
|
|
9
|
-
import { keycloakEventHandler } from "../lib/oauth/keycloak.mjs";
|
|
10
|
-
import { linkedinEventHandler } from "../lib/oauth/linkedin.mjs";
|
|
11
|
-
import { cognitoEventHandler } from "../lib/oauth/cognito.mjs";
|
|
12
|
-
import { facebookEventHandler } from "../lib/oauth/facebook.mjs";
|
|
13
|
-
export const oauth = {
|
|
14
|
-
githubEventHandler,
|
|
15
|
-
spotifyEventHandler,
|
|
16
|
-
googleEventHandler,
|
|
17
|
-
twitchEventHandler,
|
|
18
|
-
auth0EventHandler,
|
|
19
|
-
microsoftEventHandler,
|
|
20
|
-
discordEventHandler,
|
|
21
|
-
battledotnetEventHandler,
|
|
22
|
-
keycloakEventHandler,
|
|
23
|
-
linkedinEventHandler,
|
|
24
|
-
cognitoEventHandler,
|
|
25
|
-
facebookEventHandler
|
|
26
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|