nuxt-auth-utils 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Sébastien Chopin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # Nuxt Auth Utils
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![Nuxt][nuxt-src]][nuxt-href]
7
+
8
+ Minimalist Authentication module for Nuxt exposing Vue composables and server utils.
9
+
10
+ - [✨  Release Notes](/CHANGELOG.md)
11
+ <!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/nuxt-auth-utils?file=playground%2Fapp.vue) -->
12
+ <!-- - [📖 &nbsp;Documentation](https://example.com) -->
13
+
14
+ ## Features
15
+
16
+ - Secured & sealed cookies sessions
17
+ - OAuth Providers
18
+
19
+ ## Requirements
20
+
21
+ This module only works with SSR (server-side rendering) enabled as it uses server API routes. You cannot use this module with `nuxt generate`.
22
+
23
+ ## Quick Setup
24
+
25
+ 1. Add `nuxt-auth-utils` dependency to your project
26
+
27
+ ```bash
28
+ # Using pnpm
29
+ pnpm add -D nuxt-auth-utils
30
+
31
+ # Using yarn
32
+ yarn add --dev nuxt-auth-utils
33
+
34
+ # Using npm
35
+ npm install --save-dev nuxt-auth-utils
36
+ ```
37
+
38
+ 2. Add `nuxt-auth-utils` to the `modules` section of `nuxt.config.ts`
39
+
40
+ ```js
41
+ export default defineNuxtConfig({
42
+ modules: [
43
+ 'nuxt-auth-utils'
44
+ ]
45
+ })
46
+ ```
47
+
48
+ 3. Add a `NUXT_SESSION_PASSWORD` env variable with at least 32 characters in the `.env`.
49
+
50
+ ```bash
51
+ # .env
52
+ NUXT_SESSION_PASSWORD=password-with-at-least-32-characters
53
+ ```
54
+
55
+ Nuxt Auth Core can generate one for you when running Nuxt in development the first time when no `NUXT_SESSION_PASSWORD` is set.
56
+
57
+ 4. That's it! You can now add authentication to your Nuxt app ✨
58
+
59
+ ## Vue Composables
60
+
61
+ Nuxt Neo automatically add some plugins to fetch the current user session to let you access it from your Vue components.
62
+
63
+ ### User Session
64
+
65
+ ```vue
66
+ <script setup>
67
+ const { loggedIn, user, session, clear } = useUserSession()
68
+ </script>
69
+
70
+ <template>
71
+ <div v-if="loggedIn">
72
+ <h1>Welcome {{ user.login }}!</h1>
73
+ <p>Logged in since {{ session.loggedInAt }}</p>
74
+ <button @click="clear">Logout</button>
75
+ </div>
76
+ <div v-else>
77
+ <h1>Not logged in</h1>
78
+ <a href="/api/auth/github">Login with GitHub</a>
79
+ </div>
80
+ </template>
81
+ ```
82
+
83
+ ## Server Utils
84
+
85
+ The following helpers are auto-imported in your `server/` directory.
86
+
87
+ ### Session Management
88
+
89
+ ```ts
90
+ // Set a user session, note that this data is encrypted in the cookie but can be decrypted with an API call
91
+ // Only store the data that allow you to recognize an user, but do not store sensitive data
92
+ await setUserSession(event, {
93
+ user: {
94
+ // ... user data
95
+ },
96
+ loggedInAt: new Date()
97
+ // Any extra fields
98
+ })
99
+
100
+ // Get the current user session
101
+ const session = await getUserSession(event)
102
+
103
+ // Clear the current user session
104
+ await clearUserSession(event)
105
+
106
+ // Require a user session (send back 401 if no `user` key in session)
107
+ const session = await requireUserSession(event)
108
+ ```
109
+
110
+ ### OAuth Event Handlers
111
+
112
+ All helpers are exposed from the `oauth` global variable and can be used in your server routes or API routes.
113
+
114
+ The pattern is `oauth.<provider>EventHandler({ onSuccess, config?, onError? })`, example: `oauth.githubEventHandler`.
115
+
116
+ The helper returns an event handler that automatically redirects to the provider authorization page and then call `onSuccess` or `onError` depending on the result.
117
+
118
+ The `config` can be defined directly from the `runtimeConfig` in your `nuxt.config.ts`:
119
+
120
+ ```ts
121
+ export default defineNuxtConfig({
122
+ runtimeConfig: {
123
+ oauth: {
124
+ <provider>: {
125
+ clientId: '...',
126
+ clientSecret: '...'
127
+ }
128
+ }
129
+ }
130
+ })
131
+ ```
132
+
133
+ It can also be set using environment variables:
134
+ - `NUXT_OAUTH_<PROVIDER>_CLIENT_ID`
135
+ - `NUXT_OAUTH_<PROVIDER>_CLIENT_SECRET`
136
+
137
+ Supported providers:
138
+ - GitHub
139
+ - Spotify
140
+
141
+ ### Example
142
+
143
+ Example: `~/server/routes/auth/github.get.ts`
144
+
145
+ ```ts
146
+ export default oauth.githubEventHandler({
147
+ async onSuccess(event, { user, tokens }) {
148
+ await setUserSession(event, {
149
+ user: {
150
+ githubId: user.id
151
+ }
152
+ })
153
+ return sendRedirect(event, '/')
154
+ },
155
+ // Optional, will return a json error and 401 status code by default
156
+ onError(event, error) {
157
+ console.error('GitHub OAuth error:', error)
158
+ return sendRedirect(event, '/')
159
+ },
160
+ })
161
+ ```
162
+
163
+ Make sure to set the callback URL in your OAuth app settings as `<your-domain>/auth/github`.
164
+
165
+
166
+ ## Development
167
+
168
+ ```bash
169
+ # Install dependencies
170
+ npm install
171
+
172
+ # Generate type stubs
173
+ npm run dev:prepare
174
+
175
+ # Develop with the playground
176
+ npm run dev
177
+
178
+ # Build the playground
179
+ npm run dev:build
180
+
181
+ # Run ESLint
182
+ npm run lint
183
+
184
+ # Run Vitest
185
+ npm run test
186
+ npm run test:watch
187
+
188
+ # Release new version
189
+ npm run release
190
+ ```
191
+
192
+ <!-- Badges -->
193
+ [npm-version-src]: https://img.shields.io/npm/v/nuxt-auth-utils/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
194
+ [npm-version-href]: https://npmjs.com/package/nuxt-auth-utils
195
+
196
+ [npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-auth-utils.svg?style=flat&colorA=18181B&colorB=28CF8D
197
+ [npm-downloads-href]: https://npmjs.com/package/nuxt-auth-utils
198
+
199
+ [license-src]: https://img.shields.io/npm/l/nuxt-auth-utils.svg?style=flat&colorA=18181B&colorB=28CF8D
200
+ [license-href]: https://npmjs.com/package/nuxt-auth-utils
201
+
202
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
203
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
@@ -0,0 +1,7 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
6
+
7
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,7 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
6
+
7
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "auth-core",
3
+ "configKey": "auth",
4
+ "version": "0.0.2"
5
+ }
@@ -0,0 +1,52 @@
1
+ import { defineNuxtModule, createResolver, addImportsDir, addPlugin, addServerHandler } from '@nuxt/kit';
2
+ import { sha256 } from 'ohash';
3
+ import { defu } from 'defu';
4
+
5
+ const module = defineNuxtModule({
6
+ meta: {
7
+ name: "auth-core",
8
+ configKey: "auth"
9
+ },
10
+ // Default configuration options of the Nuxt module
11
+ defaults: {},
12
+ setup(options, nuxt) {
13
+ const resolver = createResolver(import.meta.url);
14
+ if (!process.env.NUXT_SESSION_PASSWORD) {
15
+ console.warn("No session password set, using a random password, please set NUXT_SESSION_PASSWORD in your .env file with at least 32 chars");
16
+ const randomPassword = sha256(`${Date.now()}${Math.random()}`).slice(0, 32);
17
+ console.log(`NUXT_SESSION_PASSWORD=${randomPassword}`);
18
+ process.env.NUXT_SESSION_PASSWORD = randomPassword;
19
+ }
20
+ addImportsDir(resolver.resolve("./runtime/composables"));
21
+ addPlugin(resolver.resolve("./runtime/plugins/session.server"));
22
+ nuxt.options.nitro.imports = nuxt.options.nitro.imports || {};
23
+ nuxt.options.nitro.imports.dirs = nuxt.options.nitro.imports.dirs || [];
24
+ nuxt.options.nitro.imports.dirs.push(resolver.resolve("./runtime/server/utils"));
25
+ addServerHandler({
26
+ handler: resolver.resolve("./runtime/server/api/session.delete"),
27
+ route: "/api/_auth/session",
28
+ method: "delete"
29
+ });
30
+ addServerHandler({
31
+ handler: resolver.resolve("./runtime/server/api/session.get"),
32
+ route: "/api/_auth/session",
33
+ method: "get"
34
+ });
35
+ const runtimeConfig = nuxt.options.runtimeConfig;
36
+ runtimeConfig.session = defu(runtimeConfig.session, {
37
+ name: "nuxt-session",
38
+ password: ""
39
+ });
40
+ runtimeConfig.oauth = defu(runtimeConfig.oauth, {});
41
+ runtimeConfig.oauth.github = defu(runtimeConfig.oauth.github, {
42
+ clientId: "",
43
+ clientSecret: ""
44
+ });
45
+ runtimeConfig.oauth.spotify = defu(runtimeConfig.oauth.spotify, {
46
+ clientId: "",
47
+ clientSecret: ""
48
+ });
49
+ }
50
+ });
51
+
52
+ export { module as default };
@@ -0,0 +1,10 @@
1
+ export declare const useUserSession: () => {
2
+ loggedIn: any;
3
+ user: any;
4
+ session: any;
5
+ fetch: typeof fetch;
6
+ clear: typeof clear;
7
+ };
8
+ declare function fetch(): Promise<void>;
9
+ declare function clear(): Promise<void>;
10
+ export {};
@@ -0,0 +1,19 @@
1
+ import { useState, computed, useRequestFetch } from "#imports";
2
+ const useSessionState = () => useState("nuxt-session", () => ({}));
3
+ export const useUserSession = () => {
4
+ const sessionState = useSessionState();
5
+ return {
6
+ loggedIn: computed(() => Boolean(sessionState.value.user)),
7
+ user: computed(() => sessionState.value.user || null),
8
+ session: sessionState,
9
+ fetch,
10
+ clear
11
+ };
12
+ };
13
+ async function fetch() {
14
+ useSessionState().value = await useRequestFetch()("/api/_auth/session").catch(() => ({}));
15
+ }
16
+ async function clear() {
17
+ await $fetch("/api/_auth/session", { method: "DELETE" });
18
+ useSessionState().value = {};
19
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ import { useUserSession } from "#imports";
3
+ export default defineNuxtPlugin({
4
+ name: "session-fetch-plugin",
5
+ enforce: "pre",
6
+ async setup() {
7
+ await useUserSession().fetch();
8
+ }
9
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ loggedOut: boolean;
3
+ }>>;
4
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { eventHandler } from "h3";
2
+ import { clearUserSession } from "../utils/session.mjs";
3
+ export default eventHandler(async (event) => {
4
+ await clearUserSession(event);
5
+ return { loggedOut: true };
6
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../utils/session").UserSession>>;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { eventHandler } from "h3";
2
+ import { requireUserSession } from "../utils/session.mjs";
3
+ export default eventHandler(async (event) => {
4
+ return await requireUserSession(event);
5
+ });
@@ -0,0 +1,45 @@
1
+ import type { H3Event, H3Error } from 'h3';
2
+ export interface OAuthGitHubConfig {
3
+ /**
4
+ * GitHub OAuth Client ID
5
+ * @default process.env.NUXT_OAUTH_GITHUB_CLIENT_ID
6
+ */
7
+ clientId?: string;
8
+ /**
9
+ * GitHub OAuth Client Secret
10
+ * @default process.env.NUXT_OAUTH_GITHUB_CLIENT_SECRET
11
+ */
12
+ clientSecret?: string;
13
+ /**
14
+ * GitHub OAuth Scope
15
+ * @default []
16
+ * @see https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
17
+ * @example ['user:email']
18
+ */
19
+ scope?: string[];
20
+ /**
21
+ * Require email from user, adds the ['user:email'] scope if not present
22
+ * @default false
23
+ */
24
+ emailRequired?: boolean;
25
+ /**
26
+ * GitHub OAuth Authorization URL
27
+ * @default 'https://github.com/login/oauth/authorize'
28
+ */
29
+ authorizationURL?: string;
30
+ /**
31
+ * GitHub OAuth Token URL
32
+ * @default 'https://github.com/login/oauth/access_token'
33
+ */
34
+ tokenURL?: string;
35
+ }
36
+ interface OAuthConfig {
37
+ config?: OAuthGitHubConfig;
38
+ onSuccess: (event: H3Event, result: {
39
+ user: any;
40
+ tokens: any;
41
+ }) => Promise<void> | void;
42
+ onError?: (event: H3Event, error: H3Error) => Promise<void> | void;
43
+ }
44
+ export declare function githubEventHandler({ config, onSuccess, onError }: OAuthConfig): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
45
+ export {};
@@ -0,0 +1,82 @@
1
+ import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
2
+ import { ofetch } from "ofetch";
3
+ import { withQuery } from "ufo";
4
+ import { defu } from "defu";
5
+ export function githubEventHandler({ config, onSuccess, onError }) {
6
+ return eventHandler(async (event) => {
7
+ config = defu(config, useRuntimeConfig(event).oauth?.github, {
8
+ authorizationURL: "https://github.com/login/oauth/authorize",
9
+ tokenURL: "https://github.com/login/oauth/access_token"
10
+ });
11
+ const { code } = getQuery(event);
12
+ if (!config.clientId || !config.clientSecret) {
13
+ const error = createError({
14
+ statusCode: 500,
15
+ message: "Missing NUXT_OAUTH_GITHUB_CLIENT_ID or NUXT_OAUTH_GITHUB_CLIENT_SECRET env variables."
16
+ });
17
+ if (!onError)
18
+ throw error;
19
+ return onError(event, error);
20
+ }
21
+ if (!code) {
22
+ config.scope = config.scope || [];
23
+ if (config.emailRequired && !config.scope.includes("user:email")) {
24
+ config.scope.push("user:email");
25
+ }
26
+ const redirectUrl = getRequestURL(event).href;
27
+ return sendRedirect(
28
+ event,
29
+ withQuery(config.authorizationURL, {
30
+ client_id: config.clientId,
31
+ redirect_uri: redirectUrl,
32
+ scope: config.scope.join("%20")
33
+ })
34
+ );
35
+ }
36
+ const tokens = await $fetch(
37
+ config.tokenURL,
38
+ {
39
+ method: "POST",
40
+ body: {
41
+ client_id: config.clientId,
42
+ client_secret: config.clientSecret,
43
+ code
44
+ }
45
+ }
46
+ );
47
+ if (tokens.error) {
48
+ const error = createError({
49
+ statusCode: 401,
50
+ message: `GitHub login failed: ${tokens.error || "Unknown error"}`,
51
+ data: tokens
52
+ });
53
+ if (!onError)
54
+ throw error;
55
+ return onError(event, error);
56
+ }
57
+ const accessToken = tokens.access_token;
58
+ const user = await ofetch("https://api.github.com/user", {
59
+ headers: {
60
+ "User-Agent": `Github-OAuth-${config.clientId}`,
61
+ Authorization: `token ${accessToken}`
62
+ }
63
+ });
64
+ if (!user.email && config.emailRequired) {
65
+ const emails = await ofetch("https://api.github.com/user/emails", {
66
+ headers: {
67
+ "User-Agent": `Github-OAuth-${config.clientId}`,
68
+ Authorization: `token ${accessToken}`
69
+ }
70
+ });
71
+ const primaryEmail = emails.find((email) => email.primary);
72
+ if (!primaryEmail) {
73
+ throw new Error("GitHub login failed: no user email found");
74
+ }
75
+ user.email = primaryEmail.email;
76
+ }
77
+ return onSuccess(event, {
78
+ user,
79
+ tokens
80
+ });
81
+ });
82
+ }
@@ -0,0 +1,45 @@
1
+ import type { H3Event, H3Error } from 'h3';
2
+ export interface OAuthSpotifyConfig {
3
+ /**
4
+ * Spotify OAuth Client ID
5
+ * @default process.env.NUXT_OAUTH_SPOTIFY_CLIENT_ID
6
+ */
7
+ clientId?: string;
8
+ /**
9
+ * Spotify OAuth Client Secret
10
+ * @default process.env.NUXT_OAUTH_SPOTIFY_CLIENT_SECRET
11
+ */
12
+ clientSecret?: string;
13
+ /**
14
+ * Spotify OAuth Scope
15
+ * @default []
16
+ * @see https://developer.spotify.com/documentation/web-api/concepts/scopes
17
+ * @example ['user-read-email']
18
+ */
19
+ scope?: string[];
20
+ /**
21
+ * Require email from user, adds the ['user-read-email'] scope if not present
22
+ * @default false
23
+ */
24
+ emailRequired?: boolean;
25
+ /**
26
+ * Spotify OAuth Authorization URL
27
+ * @default 'https://accounts.spotify.com/authorize'
28
+ */
29
+ authorizationURL?: string;
30
+ /**
31
+ * Spotify OAuth Token URL
32
+ * @default 'https://accounts.spotify.com/api/token'
33
+ */
34
+ tokenURL?: string;
35
+ }
36
+ interface OAuthConfig {
37
+ config?: OAuthSpotifyConfig;
38
+ onSuccess: (event: H3Event, result: {
39
+ user: any;
40
+ tokens: any;
41
+ }) => Promise<void> | void;
42
+ onError?: (event: H3Event, error: H3Error) => Promise<void> | void;
43
+ }
44
+ export declare function spotifyEventHandler({ config, onSuccess, onError }: OAuthConfig): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
45
+ export {};
@@ -0,0 +1,76 @@
1
+ import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
2
+ import { withQuery, parsePath } from "ufo";
3
+ import { ofetch } from "ofetch";
4
+ import { defu } from "defu";
5
+ export function spotifyEventHandler({ config, onSuccess, onError }) {
6
+ return eventHandler(async (event) => {
7
+ config = defu(config, useRuntimeConfig(event).oauth?.spotify, {
8
+ authorizationURL: "https://accounts.spotify.com/authorize",
9
+ tokenURL: "https://accounts.spotify.com/api/token"
10
+ });
11
+ const { code } = getQuery(event);
12
+ if (!config.clientId || !config.clientSecret) {
13
+ const error = createError({
14
+ statusCode: 500,
15
+ message: "Missing NUXT_OAUTH_SPOTIFY_CLIENT_ID or NUXT_OAUTH_SPOTIFY_CLIENT_SECRET env variables."
16
+ });
17
+ if (!onError)
18
+ throw error;
19
+ return onError(event, error);
20
+ }
21
+ const redirectUrl = getRequestURL(event).href;
22
+ if (!code) {
23
+ config.scope = config.scope || [];
24
+ if (config.emailRequired && !config.scope.includes("user-read-email")) {
25
+ config.scope.push("user-read-email");
26
+ }
27
+ return sendRedirect(
28
+ event,
29
+ withQuery(config.authorizationURL, {
30
+ response_type: "code",
31
+ client_id: config.clientId,
32
+ redirect_uri: redirectUrl,
33
+ scope: config.scope.join("%20")
34
+ })
35
+ );
36
+ }
37
+ const authCode = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64");
38
+ const tokens = await ofetch(
39
+ config.tokenURL,
40
+ {
41
+ method: "POST",
42
+ headers: {
43
+ Authorization: `Basic ${authCode}`,
44
+ "Content-Type": "application/x-www-form-urlencoded"
45
+ },
46
+ params: {
47
+ grant_type: "authorization_code",
48
+ redirect_uri: parsePath(redirectUrl).pathname,
49
+ code
50
+ }
51
+ }
52
+ ).catch((error) => {
53
+ return { error };
54
+ });
55
+ if (tokens.error) {
56
+ const error = createError({
57
+ statusCode: 401,
58
+ message: `Spotify login failed: ${tokens.error?.data?.error_description || "Unknown error"}`,
59
+ data: tokens
60
+ });
61
+ if (!onError)
62
+ throw error;
63
+ return onError(event, error);
64
+ }
65
+ const accessToken = tokens.access_token;
66
+ const user = await ofetch("https://api.spotify.com/v1/me", {
67
+ headers: {
68
+ Authorization: `Bearer ${accessToken}`
69
+ }
70
+ });
71
+ return onSuccess(event, {
72
+ tokens,
73
+ user
74
+ });
75
+ });
76
+ }
@@ -0,0 +1,6 @@
1
+ import { githubEventHandler } from '../lib/oauth/github';
2
+ import { spotifyEventHandler } from '../lib/oauth/spotify';
3
+ export declare const oauth: {
4
+ githubEventHandler: typeof githubEventHandler;
5
+ spotifyEventHandler: typeof spotifyEventHandler;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { githubEventHandler } from "../lib/oauth/github.mjs";
2
+ import { spotifyEventHandler } from "../lib/oauth/spotify.mjs";
3
+ export const oauth = {
4
+ githubEventHandler,
5
+ spotifyEventHandler
6
+ };
@@ -0,0 +1,14 @@
1
+ import type { H3Event } from 'h3';
2
+ export interface UserSession {
3
+ user?: any;
4
+ [key: string]: any;
5
+ }
6
+ export declare function getUserSession(event: H3Event): Promise<UserSession>;
7
+ /**
8
+ * Set a user session
9
+ * @param event
10
+ * @param data User session data, please only store public information since it can be decoded with API calls
11
+ */
12
+ export declare function setUserSession(event: H3Event, data: UserSession): Promise<UserSession>;
13
+ export declare function clearUserSession(event: H3Event): Promise<boolean>;
14
+ export declare function requireUserSession(event: H3Event): Promise<UserSession>;
@@ -0,0 +1,33 @@
1
+ import { useSession, createError } from "h3";
2
+ import { defu } from "defu";
3
+ import { useRuntimeConfig } from "#imports";
4
+ export async function getUserSession(event) {
5
+ return (await _useSession(event)).data;
6
+ }
7
+ export async function setUserSession(event, data) {
8
+ const session = await _useSession(event);
9
+ await session.update(defu(data, session.data));
10
+ return session.data;
11
+ }
12
+ export async function clearUserSession(event) {
13
+ const session = await _useSession(event);
14
+ await session.clear();
15
+ return true;
16
+ }
17
+ export async function requireUserSession(event) {
18
+ const userSession = await getUserSession(event);
19
+ if (!userSession.user) {
20
+ throw createError({
21
+ statusCode: 401,
22
+ message: "Unauthorized"
23
+ });
24
+ }
25
+ return userSession;
26
+ }
27
+ let sessionConfig;
28
+ function _useSession(event) {
29
+ if (!sessionConfig) {
30
+ sessionConfig = defu({ password: process.env.NUXT_SESSION_PASSWORD }, useRuntimeConfig(event).session);
31
+ }
32
+ return useSession(event, sessionConfig);
33
+ }
@@ -0,0 +1,15 @@
1
+
2
+ import { ModuleOptions } from './module'
3
+
4
+ declare module '@nuxt/schema' {
5
+ interface NuxtConfig { ['auth']?: Partial<ModuleOptions> }
6
+ interface NuxtOptions { ['auth']?: ModuleOptions }
7
+ }
8
+
9
+ declare module 'nuxt/schema' {
10
+ interface NuxtConfig { ['auth']?: Partial<ModuleOptions> }
11
+ interface NuxtOptions { ['auth']?: ModuleOptions }
12
+ }
13
+
14
+
15
+ export { ModuleOptions, default } from './module'
@@ -0,0 +1,15 @@
1
+
2
+ import { ModuleOptions } from './module'
3
+
4
+ declare module '@nuxt/schema' {
5
+ interface NuxtConfig { ['auth']?: Partial<ModuleOptions> }
6
+ interface NuxtOptions { ['auth']?: ModuleOptions }
7
+ }
8
+
9
+ declare module 'nuxt/schema' {
10
+ interface NuxtConfig { ['auth']?: Partial<ModuleOptions> }
11
+ interface NuxtOptions { ['auth']?: ModuleOptions }
12
+ }
13
+
14
+
15
+ export { ModuleOptions, default } from './module'
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "nuxt-auth-utils",
3
+ "version": "0.0.2",
4
+ "description": "Minimalist Auth module for Nuxt with SSR",
5
+ "repository": "Atinux/nuxt-auth-utils",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types.d.ts",
11
+ "import": "./dist/module.mjs",
12
+ "require": "./dist/module.cjs"
13
+ }
14
+ },
15
+ "main": "./dist/module.cjs",
16
+ "types": "./dist/types.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "prepack": "nuxt-module-build build",
22
+ "dev": "nuxi dev playground",
23
+ "dev:build": "nuxi build playground",
24
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
25
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
26
+ "lint": "eslint .",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest watch"
29
+ },
30
+ "dependencies": {
31
+ "@nuxt/kit": "^3.8.0",
32
+ "defu": "^6.1.3",
33
+ "ohash": "^1.1.3"
34
+ },
35
+ "devDependencies": {
36
+ "@iconify-json/simple-icons": "^1.1.76",
37
+ "@nuxt/devtools": "latest",
38
+ "@nuxt/eslint-config": "^0.2.0",
39
+ "@nuxt/module-builder": "^0.5.2",
40
+ "@nuxt/schema": "^3.8.0",
41
+ "@nuxt/test-utils": "^3.8.0",
42
+ "@nuxt/ui": "^2.10.0",
43
+ "@nuxt/ui-pro": "^0.4.2",
44
+ "@types/node": "^20.8.9",
45
+ "changelogen": "^0.5.5",
46
+ "eslint": "^8.52.0",
47
+ "nuxt": "^3.8.0",
48
+ "vitest": "^0.33.0"
49
+ }
50
+ }