nuxt-auth-utils 0.0.25 → 0.2.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 +87 -8
- package/dist/module.json +2 -2
- package/dist/module.mjs +22 -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.mjs → session.get.js} +1 -1
- package/dist/runtime/server/lib/oauth/{auth0.mjs → auth0.js} +2 -3
- package/dist/runtime/server/lib/oauth/{battledotnet.mjs → battledotnet.js} +1 -2
- package/dist/runtime/server/lib/oauth/{cognito.mjs → cognito.js} +2 -3
- package/dist/runtime/server/lib/oauth/{discord.mjs → discord.js} +2 -3
- package/dist/runtime/server/lib/oauth/{facebook.mjs → facebook.js} +1 -2
- package/dist/runtime/server/lib/oauth/{github.mjs → github.js} +2 -3
- package/dist/runtime/server/lib/oauth/{google.mjs → google.js} +2 -3
- package/dist/runtime/server/lib/oauth/{keycloak.mjs → keycloak.js} +2 -3
- package/dist/runtime/server/lib/oauth/{linkedin.mjs → linkedin.js} +2 -3
- package/dist/runtime/server/lib/oauth/{microsoft.mjs → microsoft.js} +2 -3
- package/dist/runtime/server/lib/oauth/paypal.d.ts +47 -0
- package/dist/runtime/server/lib/oauth/paypal.js +104 -0
- package/dist/runtime/server/lib/oauth/{spotify.mjs → spotify.js} +2 -3
- package/dist/runtime/server/lib/oauth/steam.d.ts +15 -0
- package/dist/runtime/server/lib/oauth/steam.js +54 -0
- package/dist/runtime/server/lib/oauth/{twitch.mjs → twitch.js} +2 -3
- package/dist/runtime/server/lib/oauth/x.d.ts +41 -0
- package/dist/runtime/server/lib/oauth/x.js +98 -0
- package/dist/runtime/server/lib/oauth/xsuaa.d.ts +26 -0
- package/dist/runtime/server/lib/oauth/xsuaa.js +73 -0
- package/dist/runtime/server/utils/oauth.d.ts +20 -12
- package/dist/runtime/server/utils/oauth.js +34 -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/plugins/{oauth.mjs → oauth.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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[![License][license-src]][license-href]
|
|
6
6
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Add Authentication to Nuxt applications with secured & sealed cookies sessions.
|
|
9
9
|
|
|
10
10
|
- [Release Notes](/CHANGELOG.md)
|
|
11
11
|
- [Demo](https://github.com/atinux/nuxt-todos-edge)
|
|
@@ -14,12 +14,20 @@ Minimalist Authentication module for Nuxt exposing Vue composables and server ut
|
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
-
|
|
18
|
-
- [OAuth Providers](#supported-oauth-providers)
|
|
17
|
+
- [Hybrid Rendering](#hybrid-rendering) support (SSR / CSR / SWR / Prerendering)
|
|
18
|
+
- [15+ OAuth Providers](#supported-oauth-providers)
|
|
19
|
+
- [Vue composable](#vue-composable)
|
|
20
|
+
- [Server utils](#server-utils)
|
|
21
|
+
- [`<AuthState>` component](#authstate-component)
|
|
22
|
+
- [Extendable with hooks](#extend-session)
|
|
19
23
|
|
|
20
24
|
## Requirements
|
|
21
25
|
|
|
22
|
-
This module only works with
|
|
26
|
+
This module only works with a Nuxt server running as it uses server API routes (`nuxt build`).
|
|
27
|
+
|
|
28
|
+
This means that you cannot use this module with `nuxt generate`.
|
|
29
|
+
|
|
30
|
+
You can anyway use [Hybrid Rendering](#hybrid-rendering) to pre-render pages of your application or disable server-side rendering completely.
|
|
23
31
|
|
|
24
32
|
## Quick Setup
|
|
25
33
|
|
|
@@ -40,7 +48,7 @@ Nuxt Auth Utils generates one for you when running Nuxt in development the first
|
|
|
40
48
|
|
|
41
49
|
3. That's it! You can now add authentication to your Nuxt app ✨
|
|
42
50
|
|
|
43
|
-
## Vue
|
|
51
|
+
## Vue Composable
|
|
44
52
|
|
|
45
53
|
Nuxt Auth Utils automatically adds some plugins to fetch the current user session to let you access it from your Vue components.
|
|
46
54
|
|
|
@@ -72,7 +80,7 @@ The following helpers are auto-imported in your `server/` directory.
|
|
|
72
80
|
|
|
73
81
|
```ts
|
|
74
82
|
// 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
|
|
83
|
+
// Only store the data that allow you to recognize a user, but do not store sensitive data
|
|
76
84
|
// Merges new data with existing data using defu()
|
|
77
85
|
await setUserSession(event, {
|
|
78
86
|
user: {
|
|
@@ -118,7 +126,7 @@ All helpers are exposed from the `oauth` global variable and can be used in your
|
|
|
118
126
|
|
|
119
127
|
The pattern is `oauth.<provider>EventHandler({ onSuccess, config?, onError? })`, example: `oauth.githubEventHandler`.
|
|
120
128
|
|
|
121
|
-
The helper returns an event handler that automatically redirects to the provider authorization page and then
|
|
129
|
+
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
130
|
|
|
123
131
|
The `config` can be defined directly from the `runtimeConfig` in your `nuxt.config.ts`:
|
|
124
132
|
|
|
@@ -152,8 +160,12 @@ It can also be set using environment variables:
|
|
|
152
160
|
- Keycloak
|
|
153
161
|
- LinkedIn
|
|
154
162
|
- Microsoft
|
|
163
|
+
- PayPal
|
|
155
164
|
- Spotify
|
|
165
|
+
- Steam
|
|
156
166
|
- Twitch
|
|
167
|
+
- X (Twitter)
|
|
168
|
+
- XSUAA
|
|
157
169
|
|
|
158
170
|
You can add your favorite provider by creating a new file in [src/runtime/server/lib/oauth/](./src/runtime/server/lib/oauth/).
|
|
159
171
|
|
|
@@ -186,7 +198,7 @@ Make sure to set the callback URL in your OAuth app settings as `<your-domain>/a
|
|
|
186
198
|
|
|
187
199
|
### Extend Session
|
|
188
200
|
|
|
189
|
-
We leverage hooks to let you extend the session data with your own data or
|
|
201
|
+
We leverage hooks to let you extend the session data with your own data or log when the user clears the session.
|
|
190
202
|
|
|
191
203
|
```ts
|
|
192
204
|
// server/plugins/session.ts
|
|
@@ -206,6 +218,69 @@ export default defineNitroPlugin(() => {
|
|
|
206
218
|
})
|
|
207
219
|
```
|
|
208
220
|
|
|
221
|
+
## Server-Side Rendering
|
|
222
|
+
|
|
223
|
+
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()`
|
|
224
|
+
|
|
225
|
+
```vue
|
|
226
|
+
<script setup lang="ts">
|
|
227
|
+
// When using useAsyncData
|
|
228
|
+
const { data } = await useAsyncData('team', () => useRequestFetch()('/api/protected-endpoint'))
|
|
229
|
+
|
|
230
|
+
// useFetch will automatically use useRequestFetch during SSR
|
|
231
|
+
const { data } = await useFetch('/api/protected-endpoint')
|
|
232
|
+
</script>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
> There's [an open issue](https://github.com/nuxt/nuxt/issues/24813) to include credentials in `$fetch` in Nuxt.
|
|
236
|
+
|
|
237
|
+
## Hybrid Rendering
|
|
238
|
+
|
|
239
|
+
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).
|
|
240
|
+
|
|
241
|
+
This is because the user session is stored in a secure cookie and cannot be accessed during prerendering.
|
|
242
|
+
|
|
243
|
+
**This means that you should not rely on the user session during prerendering.**
|
|
244
|
+
|
|
245
|
+
### `<AuthState>` component
|
|
246
|
+
|
|
247
|
+
You can use the `<AuthState>` component to safely display auth-related data in your components without worrying about the rendering mode.
|
|
248
|
+
|
|
249
|
+
One common use case if the Login button in the header:
|
|
250
|
+
|
|
251
|
+
```vue
|
|
252
|
+
<template>
|
|
253
|
+
<header>
|
|
254
|
+
<AuthState v-slot="{ loggedIn, clear }">
|
|
255
|
+
<button v-if="loggedIn" @click="clear">Logout</button>
|
|
256
|
+
<NuxtLink v-else to="/login">Login</NuxtLink>
|
|
257
|
+
</AuthState>
|
|
258
|
+
</header>
|
|
259
|
+
</template>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
If the page is cached or prerendered, nothing will be rendered until the user session is fetched on the client-side.
|
|
263
|
+
|
|
264
|
+
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:
|
|
265
|
+
|
|
266
|
+
```vue
|
|
267
|
+
<template>
|
|
268
|
+
<header>
|
|
269
|
+
<AuthState>
|
|
270
|
+
<template #default="{ loggedIn, clear }">
|
|
271
|
+
<button v-if="loggedIn" @click="clear">Logout</button>
|
|
272
|
+
<NuxtLink v-else to="/login">Login</NuxtLink>
|
|
273
|
+
</template>
|
|
274
|
+
<template #placeholder>
|
|
275
|
+
<button disabled>Loading...</button>
|
|
276
|
+
</template>
|
|
277
|
+
</AuthState>
|
|
278
|
+
</header>
|
|
279
|
+
</template>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
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.
|
|
283
|
+
|
|
209
284
|
## Configuration
|
|
210
285
|
|
|
211
286
|
We leverage `runtimeConfig.session` to give the defaults option to [h3 `useSession`](https://h3.unjs.io/examples/handle-session).
|
|
@@ -237,6 +312,10 @@ Our defaults are:
|
|
|
237
312
|
|
|
238
313
|
Checkout the [`SessionConfig`](https://github.com/unjs/h3/blob/c04c458810e34eb15c1647e1369e7d7ef19f567d/src/utils/session.ts#L20) for all options.
|
|
239
314
|
|
|
315
|
+
## More
|
|
316
|
+
|
|
317
|
+
- [nuxt-authorization](https://github.com/barbapapazes/nuxt-authorization): Authorization module for managing permissions inside a Nuxt app, compatible with `nuxt-auth-utils`
|
|
318
|
+
|
|
240
319
|
## Development
|
|
241
320
|
|
|
242
321
|
```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, addServerPlugin, 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,30 +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
|
-
presets: [
|
|
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"));
|
|
40
21
|
addServerPlugin(resolver.resolve("./runtime/server/plugins/oauth"));
|
|
22
|
+
addServerImportsDir(resolver.resolve("./runtime/server/utils"));
|
|
41
23
|
addServerHandler({
|
|
42
24
|
handler: resolver.resolve("./runtime/server/api/session.delete"),
|
|
43
25
|
route: "/api/_auth/session",
|
|
@@ -124,6 +106,22 @@ const module = defineNuxtModule({
|
|
|
124
106
|
clientId: "",
|
|
125
107
|
clientSecret: ""
|
|
126
108
|
});
|
|
109
|
+
runtimeConfig.oauth.paypal = defu(runtimeConfig.oauth.paypal, {
|
|
110
|
+
clientId: "",
|
|
111
|
+
clientSecret: ""
|
|
112
|
+
});
|
|
113
|
+
runtimeConfig.oauth.steam = defu(runtimeConfig.oauth.steam, {
|
|
114
|
+
apiKey: ""
|
|
115
|
+
});
|
|
116
|
+
runtimeConfig.oauth.x = defu(runtimeConfig.oauth.x, {
|
|
117
|
+
clientId: "",
|
|
118
|
+
clientSecret: ""
|
|
119
|
+
});
|
|
120
|
+
runtimeConfig.oauth.xsuaa = defu(runtimeConfig.oauth.xsuaa, {
|
|
121
|
+
clientId: "",
|
|
122
|
+
clientSecret: "",
|
|
123
|
+
domain: ""
|
|
124
|
+
});
|
|
127
125
|
}
|
|
128
126
|
});
|
|
129
127
|
|
|
@@ -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,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);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parsePath } from "ufo";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
6
5
|
export function auth0EventHandler({ config, onSuccess, onError }) {
|
|
@@ -40,7 +39,7 @@ export function auth0EventHandler({ config, onSuccess, onError }) {
|
|
|
40
39
|
})
|
|
41
40
|
);
|
|
42
41
|
}
|
|
43
|
-
const tokens = await
|
|
42
|
+
const tokens = await $fetch(
|
|
44
43
|
tokenURL,
|
|
45
44
|
{
|
|
46
45
|
method: "POST",
|
|
@@ -70,7 +69,7 @@ export function auth0EventHandler({ config, onSuccess, onError }) {
|
|
|
70
69
|
}
|
|
71
70
|
const tokenType = tokens.token_type;
|
|
72
71
|
const accessToken = tokens.access_token;
|
|
73
|
-
const user = await
|
|
72
|
+
const user = await $fetch(`https://${config.domain}/userinfo`, {
|
|
74
73
|
headers: {
|
|
75
74
|
Authorization: `${tokenType} ${accessToken}`
|
|
76
75
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { withQuery, parsePath } from "ufo";
|
|
5
4
|
import { defu } from "defu";
|
|
6
5
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -88,7 +87,7 @@ export function battledotnetEventHandler({ config, onSuccess, onError }) {
|
|
|
88
87
|
return onError(event, error);
|
|
89
88
|
}
|
|
90
89
|
const accessToken = tokens.access_token;
|
|
91
|
-
const user = await
|
|
90
|
+
const user = await $fetch("https://oauth.battle.net/userinfo", {
|
|
92
91
|
headers: {
|
|
93
92
|
"User-Agent": `Battledotnet-OAuth-${config.clientId}`,
|
|
94
93
|
"Authorization": `Bearer ${accessToken}`
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parsePath } from "ufo";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
6
5
|
export function cognitoEventHandler({ config, onSuccess, onError }) {
|
|
@@ -34,7 +33,7 @@ export function cognitoEventHandler({ config, onSuccess, onError }) {
|
|
|
34
33
|
})
|
|
35
34
|
);
|
|
36
35
|
}
|
|
37
|
-
const tokens = await
|
|
36
|
+
const tokens = await $fetch(
|
|
38
37
|
tokenURL,
|
|
39
38
|
{
|
|
40
39
|
method: "POST",
|
|
@@ -58,7 +57,7 @@ export function cognitoEventHandler({ config, onSuccess, onError }) {
|
|
|
58
57
|
}
|
|
59
58
|
const tokenType = tokens.token_type;
|
|
60
59
|
const accessToken = tokens.access_token;
|
|
61
|
-
const user = await
|
|
60
|
+
const user = await $fetch(`https://${config.userPoolId}.auth.${config.region}.amazoncognito.com/oauth2/userInfo`, {
|
|
62
61
|
headers: {
|
|
63
62
|
Authorization: `${tokenType} ${accessToken}`
|
|
64
63
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parseURL, stringifyParsedURL } from "ufo";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
6
5
|
export function discordEventHandler({ config, onSuccess, onError }) {
|
|
@@ -43,7 +42,7 @@ export function discordEventHandler({ config, onSuccess, onError }) {
|
|
|
43
42
|
}
|
|
44
43
|
const parsedRedirectUrl = parseURL(redirectUrl);
|
|
45
44
|
parsedRedirectUrl.search = "";
|
|
46
|
-
const tokens = await
|
|
45
|
+
const tokens = await $fetch(
|
|
47
46
|
config.tokenURL,
|
|
48
47
|
{
|
|
49
48
|
method: "POST",
|
|
@@ -72,7 +71,7 @@ export function discordEventHandler({ config, onSuccess, onError }) {
|
|
|
72
71
|
return onError(event, error);
|
|
73
72
|
}
|
|
74
73
|
const accessToken = tokens.access_token;
|
|
75
|
-
const user = await
|
|
74
|
+
const user = await $fetch("https://discord.com/api/users/@me", {
|
|
76
75
|
headers: {
|
|
77
76
|
"user-agent": "Nuxt Auth Utils",
|
|
78
77
|
"Authorization": `Bearer ${accessToken}`
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
getRequestURL,
|
|
6
6
|
sendRedirect
|
|
7
7
|
} from "h3";
|
|
8
|
-
import { ofetch } from "ofetch";
|
|
9
8
|
import { withQuery } from "ufo";
|
|
10
9
|
import { defu } from "defu";
|
|
11
10
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -74,7 +73,7 @@ export function facebookEventHandler({
|
|
|
74
73
|
const accessToken = tokens.access_token;
|
|
75
74
|
config.fields = config.fields || ["id", "name"];
|
|
76
75
|
const fields = config.fields.join(",");
|
|
77
|
-
const user = await
|
|
76
|
+
const user = await $fetch(
|
|
78
77
|
`https://graph.facebook.com/v19.0/me?fields=${fields}&access_token=${accessToken}`
|
|
79
78
|
);
|
|
80
79
|
if (!user) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
|
-
import { ofetch } from "ofetch";
|
|
3
2
|
import { withQuery } from "ufo";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -68,14 +67,14 @@ export function githubEventHandler({ config, onSuccess, onError }) {
|
|
|
68
67
|
return onError(event, error);
|
|
69
68
|
}
|
|
70
69
|
const accessToken = tokens.access_token;
|
|
71
|
-
const user = await
|
|
70
|
+
const user = await $fetch("https://api.github.com/user", {
|
|
72
71
|
headers: {
|
|
73
72
|
"User-Agent": `Github-OAuth-${config.clientId}`,
|
|
74
73
|
"Authorization": `token ${accessToken}`
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
76
|
if (!user.email && config.emailRequired) {
|
|
78
|
-
const emails = await
|
|
77
|
+
const emails = await $fetch("https://api.github.com/user/emails", {
|
|
79
78
|
headers: {
|
|
80
79
|
"User-Agent": `Github-OAuth-${config.clientId}`,
|
|
81
80
|
"Authorization": `token ${accessToken}`
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
sendRedirect
|
|
7
7
|
} from "h3";
|
|
8
8
|
import { withQuery, parsePath } from "ufo";
|
|
9
|
-
import { ofetch } from "ofetch";
|
|
10
9
|
import { defu } from "defu";
|
|
11
10
|
import { useRuntimeConfig } from "#imports";
|
|
12
11
|
export function googleEventHandler({
|
|
@@ -52,7 +51,7 @@ export function googleEventHandler({
|
|
|
52
51
|
client_secret: config.clientSecret,
|
|
53
52
|
code
|
|
54
53
|
};
|
|
55
|
-
const tokens = await
|
|
54
|
+
const tokens = await $fetch(config.tokenURL, {
|
|
56
55
|
method: "POST",
|
|
57
56
|
body
|
|
58
57
|
}).catch((error) => {
|
|
@@ -69,7 +68,7 @@ export function googleEventHandler({
|
|
|
69
68
|
return onError(event, error);
|
|
70
69
|
}
|
|
71
70
|
const accessToken = tokens.access_token;
|
|
72
|
-
const user = await
|
|
71
|
+
const user = await $fetch(
|
|
73
72
|
config.userURL,
|
|
74
73
|
{
|
|
75
74
|
headers: {
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
getRequestURL,
|
|
6
6
|
sendRedirect
|
|
7
7
|
} from "h3";
|
|
8
|
-
import { ofetch } from "ofetch";
|
|
9
8
|
import { withQuery, parsePath } from "ufo";
|
|
10
9
|
import { defu } from "defu";
|
|
11
10
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -60,7 +59,7 @@ export function keycloakEventHandler({
|
|
|
60
59
|
if (!config.scope.includes("openid")) {
|
|
61
60
|
config.scope.push("openid");
|
|
62
61
|
}
|
|
63
|
-
const tokens = await
|
|
62
|
+
const tokens = await $fetch(tokenURL, {
|
|
64
63
|
method: "POST",
|
|
65
64
|
headers: {
|
|
66
65
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
@@ -86,7 +85,7 @@ export function keycloakEventHandler({
|
|
|
86
85
|
return onError(event, error);
|
|
87
86
|
}
|
|
88
87
|
const accessToken = tokens.access_token;
|
|
89
|
-
const user = await
|
|
88
|
+
const user = await $fetch(
|
|
90
89
|
`${realmURL}/protocol/openid-connect/userinfo`,
|
|
91
90
|
{
|
|
92
91
|
headers: {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parseURL, stringifyParsedURL } from "ufo";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
6
5
|
export function linkedinEventHandler({ config, onSuccess, onError }) {
|
|
@@ -42,7 +41,7 @@ export function linkedinEventHandler({ config, onSuccess, onError }) {
|
|
|
42
41
|
}
|
|
43
42
|
const parsedRedirectUrl = parseURL(redirectUrl);
|
|
44
43
|
parsedRedirectUrl.search = "";
|
|
45
|
-
const tokens = await
|
|
44
|
+
const tokens = await $fetch(
|
|
46
45
|
config.tokenURL,
|
|
47
46
|
{
|
|
48
47
|
method: "POST",
|
|
@@ -71,7 +70,7 @@ export function linkedinEventHandler({ config, onSuccess, onError }) {
|
|
|
71
70
|
return onError(event, error);
|
|
72
71
|
}
|
|
73
72
|
const accessToken = tokens.access_token;
|
|
74
|
-
const user = await
|
|
73
|
+
const user = await $fetch("https://api.linkedin.com/v2/userinfo", {
|
|
75
74
|
headers: {
|
|
76
75
|
"user-agent": "Nuxt Auth Utils",
|
|
77
76
|
"Authorization": `Bearer ${accessToken}`
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parsePath } from "ufo";
|
|
3
|
-
import { ofetch } from "ofetch";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { useRuntimeConfig } from "#imports";
|
|
6
5
|
export function microsoftEventHandler({ config, onSuccess, onError }) {
|
|
@@ -40,7 +39,7 @@ export function microsoftEventHandler({ config, onSuccess, onError }) {
|
|
|
40
39
|
data.append("client_secret", config.clientSecret);
|
|
41
40
|
data.append("redirect_uri", parsePath(redirectUrl).pathname);
|
|
42
41
|
data.append("code", String(code));
|
|
43
|
-
const tokens = await
|
|
42
|
+
const tokens = await $fetch(
|
|
44
43
|
tokenURL,
|
|
45
44
|
{
|
|
46
45
|
method: "POST",
|
|
@@ -65,7 +64,7 @@ export function microsoftEventHandler({ config, onSuccess, onError }) {
|
|
|
65
64
|
const tokenType = tokens.token_type;
|
|
66
65
|
const accessToken = tokens.access_token;
|
|
67
66
|
const userURL = config.userURL || "https://graph.microsoft.com/v1.0/me";
|
|
68
|
-
const user = await
|
|
67
|
+
const user = await $fetch(userURL, {
|
|
69
68
|
headers: {
|
|
70
69
|
Authorization: `${tokenType} ${accessToken}`
|
|
71
70
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { OAuthConfig } from '#auth-utils';
|
|
2
|
+
export interface OAuthPaypalConfig {
|
|
3
|
+
/**
|
|
4
|
+
* PayPal Client ID
|
|
5
|
+
* @default process.env.NUXT_OAUTH_PAYPAL_CLIENT_ID
|
|
6
|
+
*/
|
|
7
|
+
clientId?: string;
|
|
8
|
+
/**
|
|
9
|
+
* PayPal OAuth Client Secret
|
|
10
|
+
* @default process.env.NUXT_OAUTH_PAYPAL_CLIENT_SECRET
|
|
11
|
+
*/
|
|
12
|
+
clientSecret?: string;
|
|
13
|
+
/**
|
|
14
|
+
* PayPal OAuth Scope
|
|
15
|
+
* @default []
|
|
16
|
+
* @see https://developer.paypal.com/docs/log-in-with-paypal/integrate/reference/#scope-attributes
|
|
17
|
+
* @example ['email', 'profile']
|
|
18
|
+
*/
|
|
19
|
+
scope?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Require email from user, adds the ['email'] scope if not present
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
emailRequired?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Use PayPal sandbox environment
|
|
27
|
+
* @default import.meta.dev // true in development, false in production
|
|
28
|
+
*/
|
|
29
|
+
sandbox?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* PayPal OAuth Authorization URL
|
|
32
|
+
* @default 'https://www.paypal.com/signin/authorize'
|
|
33
|
+
*/
|
|
34
|
+
authorizationURL?: string;
|
|
35
|
+
/**
|
|
36
|
+
* PayPal OAuth Token URL
|
|
37
|
+
* @default 'https://api-m.paypal.com/v1/oauth2/token'
|
|
38
|
+
*/
|
|
39
|
+
tokenURL?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Extra authorization parameters to provide to the authorization URL
|
|
42
|
+
* @see https://developer.paypal.com/docs/log-in-with-paypal/integrate/build-button/#link-constructauthorizationendpoint
|
|
43
|
+
* @example { flowEntry: 'static' }
|
|
44
|
+
*/
|
|
45
|
+
authorizationParams?: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
export declare function paypalEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPaypalConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|