nuxt-auth-utils 0.5.22 → 0.5.24
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 +14 -1
- package/dist/module.d.mts +12 -1
- package/dist/module.json +3 -3
- package/dist/module.mjs +25 -5
- package/dist/runtime/app/components/AuthState.vue +3 -4
- package/dist/runtime/app/components/AuthState.vue.d.ts +19 -0
- package/dist/runtime/app/plugins/session.client.js +1 -1
- package/dist/runtime/app/plugins/session.server.js +1 -1
- package/dist/runtime/server/api/session.get.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/authentik.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/authentik.js +1 -1
- package/dist/runtime/server/lib/oauth/github.js +6 -1
- package/dist/runtime/server/lib/oauth/ory.d.ts +51 -0
- package/dist/runtime/server/lib/oauth/ory.js +101 -0
- package/dist/runtime/server/lib/oauth/roblox.d.ts +126 -0
- package/dist/runtime/server/lib/oauth/roblox.js +64 -0
- package/dist/runtime/server/lib/webauthn/authenticate.d.ts +2 -4
- package/dist/runtime/server/lib/webauthn/authenticate.js +1 -1
- package/dist/runtime/server/lib/webauthn/register.d.ts +2 -5
- package/dist/runtime/server/lib/webauthn/register.js +2 -2
- package/dist/runtime/server/plugins/oauth.d.ts +1 -1
- package/dist/runtime/server/plugins/ws.d.ts +1 -1
- package/dist/runtime/server/utils/session.js +3 -0
- package/dist/runtime/types/oauth-config.d.ts +1 -1
- package/dist/runtime/utils/atproto.js +6 -5
- package/dist/types.d.mts +3 -1
- package/package.json +34 -30
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -39
- package/dist/types.d.ts +0 -1
package/README.md
CHANGED
|
@@ -240,6 +240,7 @@ It can also be set using environment variables:
|
|
|
240
240
|
- LiveChat
|
|
241
241
|
- Microsoft
|
|
242
242
|
- Okta
|
|
243
|
+
- Ory
|
|
243
244
|
- PayPal
|
|
244
245
|
- Polar
|
|
245
246
|
- Salesforce
|
|
@@ -599,6 +600,18 @@ This is because the user session is stored in a secure cookie and cannot be acce
|
|
|
599
600
|
|
|
600
601
|
**This means that you should not rely on the user session during prerendering.**
|
|
601
602
|
|
|
603
|
+
You may also choose to instruct Nuxt AUth Utils to fetch the user session only on the client side, with the `loadStrategy` option in your `nuxt.config.ts`:
|
|
604
|
+
|
|
605
|
+
```ts
|
|
606
|
+
export default defineNuxtConfig({
|
|
607
|
+
auth: {
|
|
608
|
+
loadStrategy: 'client-only'
|
|
609
|
+
}
|
|
610
|
+
})
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
When using the `client-only` load strategy, the user session can still be manually fetched on the server side by calling `fetch` from the `useUserSession` composable.
|
|
614
|
+
|
|
602
615
|
### `<AuthState>` component
|
|
603
616
|
|
|
604
617
|
You can use the `<AuthState>` component to safely display auth-related data in your components without worrying about the rendering mode.
|
|
@@ -616,7 +629,7 @@ One common use case if the Login button in the header:
|
|
|
616
629
|
</template>
|
|
617
630
|
```
|
|
618
631
|
|
|
619
|
-
If the page is cached or prerendered
|
|
632
|
+
If the page is cached or prerendered or the load strategy set as `client-only`, nothing will be rendered until the user session is fetched on the client-side.
|
|
620
633
|
|
|
621
634
|
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:
|
|
622
635
|
|
package/dist/module.d.mts
CHANGED
|
@@ -22,6 +22,11 @@ interface ModuleOptions {
|
|
|
22
22
|
*/
|
|
23
23
|
scrypt?: ScryptConfig;
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Session load strategy
|
|
27
|
+
* @default 'server-first'
|
|
28
|
+
*/
|
|
29
|
+
loadStrategy?: 'server-first' | 'client-only';
|
|
25
30
|
}
|
|
26
31
|
declare module 'nuxt/schema' {
|
|
27
32
|
interface RuntimeConfig {
|
|
@@ -33,7 +38,13 @@ declare module 'nuxt/schema' {
|
|
|
33
38
|
*/
|
|
34
39
|
session: SessionConfig;
|
|
35
40
|
}
|
|
41
|
+
interface PublicRuntimeConfig {
|
|
42
|
+
auth: {
|
|
43
|
+
loadStrategy: 'server-first' | 'client-only';
|
|
44
|
+
};
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
38
48
|
|
|
39
|
-
export {
|
|
49
|
+
export { _default as default };
|
|
50
|
+
export type { ModuleOptions };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -16,7 +16,8 @@ const module = defineNuxtModule({
|
|
|
16
16
|
atproto: false,
|
|
17
17
|
hash: {
|
|
18
18
|
scrypt: {}
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
|
+
loadStrategy: "server-first"
|
|
20
21
|
},
|
|
21
22
|
async setup(options, nuxt) {
|
|
22
23
|
const resolver = createResolver(import.meta.url);
|
|
@@ -74,7 +75,7 @@ const module = defineNuxtModule({
|
|
|
74
75
|
const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || "NUXT_"}SESSION_PASSWORD`;
|
|
75
76
|
runtimeConfig.session = defu(runtimeConfig.session, {
|
|
76
77
|
name: "nuxt-session",
|
|
77
|
-
password:
|
|
78
|
+
password: "",
|
|
78
79
|
cookie: {
|
|
79
80
|
sameSite: "lax"
|
|
80
81
|
}
|
|
@@ -82,18 +83,21 @@ const module = defineNuxtModule({
|
|
|
82
83
|
runtimeConfig.hash = defu(runtimeConfig.hash, {
|
|
83
84
|
scrypt: options.hash?.scrypt
|
|
84
85
|
});
|
|
85
|
-
if (nuxt.options.dev && !
|
|
86
|
-
|
|
86
|
+
if (nuxt.options.dev && !process.env[envSessionPassword]) {
|
|
87
|
+
const password = process.env[envSessionPassword] = randomUUID().replace(/-/g, "");
|
|
87
88
|
const envPath = join(nuxt.options.rootDir, ".env");
|
|
88
89
|
const envContent = await readFile(envPath, "utf-8").catch(() => "");
|
|
89
90
|
if (!envContent.includes(envSessionPassword)) {
|
|
90
91
|
await writeFile(
|
|
91
92
|
envPath,
|
|
92
|
-
`${envContent ? envContent + "\n" : envContent}${envSessionPassword}=${
|
|
93
|
+
`${envContent ? envContent + "\n" : envContent}${envSessionPassword}=${password}`,
|
|
93
94
|
"utf-8"
|
|
94
95
|
);
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
runtimeConfig.public.auth = defu(runtimeConfig.public.auth, {
|
|
99
|
+
loadStrategy: options.loadStrategy ?? "server-first"
|
|
100
|
+
});
|
|
97
101
|
runtimeConfig.webauthn = defu(runtimeConfig.webauthn, {
|
|
98
102
|
register: {},
|
|
99
103
|
authenticate: {}
|
|
@@ -353,6 +357,12 @@ const module = defineNuxtModule({
|
|
|
353
357
|
redirectURL: "",
|
|
354
358
|
scope: ""
|
|
355
359
|
});
|
|
360
|
+
runtimeConfig.oauth.roblox = defu(runtimeConfig.oauth.roblox, {
|
|
361
|
+
clientId: "",
|
|
362
|
+
clientSecret: "",
|
|
363
|
+
redirectURL: "",
|
|
364
|
+
scope: ""
|
|
365
|
+
});
|
|
356
366
|
runtimeConfig.oauth.okta = defu(runtimeConfig.oauth.okta, {
|
|
357
367
|
clientId: "",
|
|
358
368
|
clientSecret: "",
|
|
@@ -361,6 +371,16 @@ const module = defineNuxtModule({
|
|
|
361
371
|
scope: [],
|
|
362
372
|
redirectURL: ""
|
|
363
373
|
});
|
|
374
|
+
runtimeConfig.oauth.ory = defu(runtimeConfig.oauth.ory, {
|
|
375
|
+
clientId: "",
|
|
376
|
+
clientSecret: "",
|
|
377
|
+
sdkURL: "",
|
|
378
|
+
redirectURL: "",
|
|
379
|
+
scope: [],
|
|
380
|
+
authorizationURL: "",
|
|
381
|
+
tokenURL: "",
|
|
382
|
+
userURL: ""
|
|
383
|
+
});
|
|
364
384
|
}
|
|
365
385
|
});
|
|
366
386
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import { useUserSession } from
|
|
3
|
-
|
|
4
|
-
const { loggedIn, user, session, clear, ready } = useUserSession()
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useUserSession } from "#imports";
|
|
3
|
+
const { loggedIn, user, session, clear, ready } = useUserSession();
|
|
5
4
|
</script>
|
|
6
5
|
|
|
7
6
|
<template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare var __VLS_1: {
|
|
2
|
+
loggedIn: boolean;
|
|
3
|
+
user: import("../../types/index.js").User | null;
|
|
4
|
+
session: import("../../types/index.js").UserSession | null;
|
|
5
|
+
clear: () => Promise<void>;
|
|
6
|
+
}, __VLS_3: {};
|
|
7
|
+
type __VLS_Slots = {} & {
|
|
8
|
+
default?: (props: typeof __VLS_1) => any;
|
|
9
|
+
} & {
|
|
10
|
+
placeholder?: (props: typeof __VLS_3) => any;
|
|
11
|
+
};
|
|
12
|
+
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
13
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
14
|
+
export default _default;
|
|
15
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
16
|
+
new (): {
|
|
17
|
+
$slots: S;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -2,7 +2,7 @@ import { defineNuxtPlugin, useUserSession, useError } from "#imports";
|
|
|
2
2
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
3
3
|
if (!nuxtApp.payload.serverRendered) {
|
|
4
4
|
await useUserSession().fetch();
|
|
5
|
-
} else if (Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached)) {
|
|
5
|
+
} else if (Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached) || nuxtApp.$config.public.auth.loadStrategy === "client-only") {
|
|
6
6
|
nuxtApp.hook("app:mounted", async () => {
|
|
7
7
|
await useUserSession().fetch();
|
|
8
8
|
});
|
|
@@ -4,7 +4,7 @@ export default defineNuxtPlugin({
|
|
|
4
4
|
enforce: "pre",
|
|
5
5
|
async setup(nuxtApp) {
|
|
6
6
|
nuxtApp.payload.isCached = Boolean(useRequestEvent()?.context.cache);
|
|
7
|
-
if (nuxtApp.payload.serverRendered && !nuxtApp.payload.prerenderedAt && !nuxtApp.payload.isCached) {
|
|
7
|
+
if (nuxtApp.payload.serverRendered && !nuxtApp.payload.prerenderedAt && !nuxtApp.payload.isCached && nuxtApp.$config.public.auth.loadStrategy !== "client-only") {
|
|
8
8
|
await useUserSession().fetch();
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -21,5 +21,10 @@ export interface OAuthAuthentikConfig {
|
|
|
21
21
|
* @default process.env.NUXT_OAUTH_AUTHENTIK_REDIRECT_URL or current URL
|
|
22
22
|
*/
|
|
23
23
|
redirectURL?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Authentik Scope
|
|
26
|
+
* @default ['openid', 'profile', 'email']
|
|
27
|
+
*/
|
|
28
|
+
scope?: string[];
|
|
24
29
|
}
|
|
25
30
|
export declare function defineOAuthAuthentikEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuthentikConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -29,7 +29,7 @@ export function defineOAuthAuthentikEventHandler({ config, onSuccess, onError })
|
|
|
29
29
|
response_type: "code",
|
|
30
30
|
client_id: config.clientId,
|
|
31
31
|
redirect_uri: redirectURL,
|
|
32
|
-
scope: ["openid", "profile", "email"].join(" ")
|
|
32
|
+
scope: (config.scope || ["openid", "profile", "email"]).join(" ")
|
|
33
33
|
})
|
|
34
34
|
);
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect, createError } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import {
|
|
4
|
+
import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleInvalidState, handleMissingConfiguration, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -25,6 +25,7 @@ export function defineOAuthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
|
25
25
|
return handleMissingConfiguration(event, "github", ["clientId", "clientSecret"], onError);
|
|
26
26
|
}
|
|
27
27
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
28
|
+
const state = await handleState(event);
|
|
28
29
|
if (!query.code) {
|
|
29
30
|
config.scope = config.scope || [];
|
|
30
31
|
if (config.emailRequired && !config.scope.includes("user:email")) {
|
|
@@ -36,10 +37,14 @@ export function defineOAuthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
|
36
37
|
client_id: config.clientId,
|
|
37
38
|
redirect_uri: redirectURL,
|
|
38
39
|
scope: config.scope.join(" "),
|
|
40
|
+
state,
|
|
39
41
|
...config.authorizationParams
|
|
40
42
|
})
|
|
41
43
|
);
|
|
42
44
|
}
|
|
45
|
+
if (query.state !== state) {
|
|
46
|
+
return handleInvalidState(event, "github", onError);
|
|
47
|
+
}
|
|
43
48
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
44
49
|
body: {
|
|
45
50
|
grant_type: "authorization_code",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { OAuthConfig } from '#auth-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Ory OAuth2
|
|
4
|
+
* @see https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow
|
|
5
|
+
*/
|
|
6
|
+
export interface OAuthOryConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Ory OAuth Client ID
|
|
9
|
+
* @default process.env.NUXT_OAUTH_ORY_CLIENT_ID
|
|
10
|
+
*/
|
|
11
|
+
clientId?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Ory OAuth Client Secret
|
|
14
|
+
* @default process.env.NUXT_OAUTH_ORY_CLIENT_SECRET
|
|
15
|
+
*/
|
|
16
|
+
clientSecret?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Ory OAuth SDK URL
|
|
19
|
+
* @default "https://playground.projects.oryapis.com" || process.env.NUXT_OAUTH_ORY_SDK_URL
|
|
20
|
+
*/
|
|
21
|
+
sdkURL?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Ory OAuth Scope
|
|
24
|
+
* @default ['openid', 'offline']
|
|
25
|
+
* @see https://www.ory.sh/docs/oauth2-oidc/openid-connect-claims-scope-custom
|
|
26
|
+
* @example ['openid', 'offline', 'email']
|
|
27
|
+
*/
|
|
28
|
+
scope?: string[] | string;
|
|
29
|
+
/**
|
|
30
|
+
* Ory OAuth Authorization URL
|
|
31
|
+
* @default '/oauth2/auth'
|
|
32
|
+
*/
|
|
33
|
+
authorizationURL?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Ory OAuth Token URL
|
|
36
|
+
* @default '/oauth2/token'
|
|
37
|
+
*/
|
|
38
|
+
tokenURL?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Extra authorization parameters to provide to the authorization URL
|
|
41
|
+
* @example { allow_signup: 'true' }
|
|
42
|
+
*/
|
|
43
|
+
authorizationParams?: Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Ory OAuth Userinfo URL
|
|
46
|
+
* @see https://www.ory.sh/docs/oauth2-oidc/userinfo-oidc
|
|
47
|
+
* @default '/userinfo'
|
|
48
|
+
*/
|
|
49
|
+
userURL?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function defineOAuthOryEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthOryConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
|
+
import { withQuery } from "ufo";
|
|
3
|
+
import { defu } from "defu";
|
|
4
|
+
import {
|
|
5
|
+
getOAuthRedirectURL,
|
|
6
|
+
handleAccessTokenErrorResponse,
|
|
7
|
+
handleInvalidState,
|
|
8
|
+
handleMissingConfiguration,
|
|
9
|
+
handlePkceVerifier,
|
|
10
|
+
handleState,
|
|
11
|
+
requestAccessToken
|
|
12
|
+
} from "../utils.js";
|
|
13
|
+
import { createError, useRuntimeConfig } from "#imports";
|
|
14
|
+
export function defineOAuthOryEventHandler({ config, onSuccess, onError }) {
|
|
15
|
+
return eventHandler(async (event) => {
|
|
16
|
+
config = defu(config, useRuntimeConfig(event).oauth?.ory, {
|
|
17
|
+
scope: ["openid", "offline"],
|
|
18
|
+
sdkURL: "https://playground.projects.oryapis.com",
|
|
19
|
+
authorizationURL: "/oauth2/auth",
|
|
20
|
+
tokenURL: "/oauth2/token",
|
|
21
|
+
userURL: "/userinfo",
|
|
22
|
+
authorizationParams: {}
|
|
23
|
+
});
|
|
24
|
+
const query = getQuery(event);
|
|
25
|
+
if (query.error) {
|
|
26
|
+
const error = createError({
|
|
27
|
+
statusCode: 401,
|
|
28
|
+
message: `Ory login failed: ${query.error || "Unknown error"}`,
|
|
29
|
+
data: query
|
|
30
|
+
});
|
|
31
|
+
if (!onError) throw error;
|
|
32
|
+
return onError(event, error);
|
|
33
|
+
}
|
|
34
|
+
if (!config.clientId || !config.sdkURL) {
|
|
35
|
+
return handleMissingConfiguration(event, "ory", ["clientId", "sdkURL"], onError);
|
|
36
|
+
}
|
|
37
|
+
const redirectURL = getOAuthRedirectURL(event);
|
|
38
|
+
if (Array.isArray(config.scope)) {
|
|
39
|
+
config.scope = Array.from(new Set(config.scope)).join(" ");
|
|
40
|
+
}
|
|
41
|
+
const verifier = await handlePkceVerifier(event);
|
|
42
|
+
const state = await handleState(event);
|
|
43
|
+
if (!query.code) {
|
|
44
|
+
const authorizationURL = `${config.sdkURL}${config.authorizationURL}`;
|
|
45
|
+
return sendRedirect(
|
|
46
|
+
event,
|
|
47
|
+
withQuery(authorizationURL, {
|
|
48
|
+
client_id: config.clientId,
|
|
49
|
+
response_type: "code",
|
|
50
|
+
redirect_uri: redirectURL,
|
|
51
|
+
scope: config.scope,
|
|
52
|
+
state,
|
|
53
|
+
code_challenge: verifier.code_challenge,
|
|
54
|
+
code_challenge_method: verifier.code_challenge_method,
|
|
55
|
+
...config.authorizationParams
|
|
56
|
+
})
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (query.state !== state) {
|
|
60
|
+
handleInvalidState(event, "ory", onError);
|
|
61
|
+
}
|
|
62
|
+
const tokenURL = `${config.sdkURL}${config.tokenURL}`;
|
|
63
|
+
const tokens = await requestAccessToken(tokenURL, {
|
|
64
|
+
body: {
|
|
65
|
+
grant_type: "authorization_code",
|
|
66
|
+
client_id: config.clientId,
|
|
67
|
+
code: query.code,
|
|
68
|
+
redirect_uri: redirectURL,
|
|
69
|
+
scope: config.scope,
|
|
70
|
+
code_verifier: verifier.code_verifier
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (tokens.error) {
|
|
74
|
+
return handleAccessTokenErrorResponse(event, "ory", tokens, onError);
|
|
75
|
+
}
|
|
76
|
+
const tokenType = tokens.token_type;
|
|
77
|
+
const accessToken = tokens.access_token;
|
|
78
|
+
const userURL = `${config.sdkURL}${config.userURL}`;
|
|
79
|
+
const user = await $fetch(userURL, {
|
|
80
|
+
headers: {
|
|
81
|
+
"User-Agent": `Ory-${config.clientId}`,
|
|
82
|
+
"Authorization": `${tokenType} ${accessToken}`
|
|
83
|
+
}
|
|
84
|
+
}).catch((error) => {
|
|
85
|
+
return { error };
|
|
86
|
+
});
|
|
87
|
+
if (user.error) {
|
|
88
|
+
const error = createError({
|
|
89
|
+
statusCode: 401,
|
|
90
|
+
message: `Ory userinfo failed: ${user.error || "Unknown error"}`,
|
|
91
|
+
data: user
|
|
92
|
+
});
|
|
93
|
+
if (!onError) throw error;
|
|
94
|
+
return onError(event, error);
|
|
95
|
+
}
|
|
96
|
+
return onSuccess(event, {
|
|
97
|
+
tokens,
|
|
98
|
+
user
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { OAuthConfig } from '#auth-utils';
|
|
2
|
+
export interface OAuthRobloxConfig {
|
|
3
|
+
/**
|
|
4
|
+
* Roblox OAuth Client ID
|
|
5
|
+
* @default process.env.NUXT_OAUTH_ROBLOX_CLIENT_ID
|
|
6
|
+
*/
|
|
7
|
+
clientId?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Roblox OAuth Client Secret
|
|
10
|
+
* @default process.env.NUXT_OAUTH_ROBLOX_CLIENT_SECRET
|
|
11
|
+
*/
|
|
12
|
+
clientSecret?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Roblox OAuth Scope
|
|
15
|
+
* Some scopes and claims listed are only available to official Roblox apps, e.g. email
|
|
16
|
+
* @default ['openid', 'profile']
|
|
17
|
+
* @see https://apis.roblox.com/oauth/.well-known/openid-configuration
|
|
18
|
+
* @example ['openid', 'profile', 'asset:read', 'universe-messaging-service:publish']
|
|
19
|
+
*/
|
|
20
|
+
scope?: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Roblox OAuth Authorization URL
|
|
23
|
+
* @default 'https://apis.roblox.com/oauth/v1/authorize'
|
|
24
|
+
*/
|
|
25
|
+
authorizationURL?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Roblox OAuth Token URL
|
|
28
|
+
* @default 'https://apis.roblox.com/oauth/v1/token'
|
|
29
|
+
*/
|
|
30
|
+
tokenURL?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Extra authorization parameters to provide to the authorization URL
|
|
33
|
+
* @see https://create.roblox.com/docs/cloud/auth/oauth2-reference#get-v1authorize
|
|
34
|
+
*/
|
|
35
|
+
authorizationParams?: Record<string, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Redirect URL to allow overriding for situations like prod failing to determine public hostname
|
|
38
|
+
* @default process.env.NUXT_OAUTH_ROBLOX_REDIRECT_URL or current URL
|
|
39
|
+
*/
|
|
40
|
+
redirectURL?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface OAuthRobloxUser {
|
|
43
|
+
/**
|
|
44
|
+
* The resource path of the user
|
|
45
|
+
* @example "users/123"
|
|
46
|
+
*/
|
|
47
|
+
path: string;
|
|
48
|
+
/**
|
|
49
|
+
* The timestamp at which the user was created
|
|
50
|
+
* @readonly
|
|
51
|
+
* @example "2023-07-05T12:34:56Z"
|
|
52
|
+
*/
|
|
53
|
+
createTime: string;
|
|
54
|
+
/**
|
|
55
|
+
* Unique ID that identifies a user in Roblox
|
|
56
|
+
* @readonly
|
|
57
|
+
* @example "123456"
|
|
58
|
+
*/
|
|
59
|
+
id: string;
|
|
60
|
+
/**
|
|
61
|
+
* Unique username for a user in Roblox
|
|
62
|
+
* @example "exampleUser"
|
|
63
|
+
*/
|
|
64
|
+
name: string;
|
|
65
|
+
/**
|
|
66
|
+
* Display name for the user
|
|
67
|
+
* @example "userDefinedName"
|
|
68
|
+
*/
|
|
69
|
+
displayName: string;
|
|
70
|
+
/**
|
|
71
|
+
* User-defined information about themselves
|
|
72
|
+
* @example "Example User's bio"
|
|
73
|
+
*/
|
|
74
|
+
about: string;
|
|
75
|
+
/**
|
|
76
|
+
* Current locale selected by the user as an IETF language code
|
|
77
|
+
* @example "en-US"
|
|
78
|
+
*/
|
|
79
|
+
locale: string;
|
|
80
|
+
/**
|
|
81
|
+
* Whether the user is a premium user
|
|
82
|
+
* @readonly
|
|
83
|
+
* @example true
|
|
84
|
+
*/
|
|
85
|
+
premium: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Specifies if the user is identity-verified
|
|
88
|
+
* Verification includes, but isn't limited to, non-VoIP phone numbers or government IDs
|
|
89
|
+
* Available only with the user.advanced:read scope
|
|
90
|
+
* @readonly
|
|
91
|
+
* @example true
|
|
92
|
+
*/
|
|
93
|
+
idVerified: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* User's social network profiles and visibility.
|
|
96
|
+
*/
|
|
97
|
+
socialNetworkProfiles: {
|
|
98
|
+
/**
|
|
99
|
+
* Facebook profile URI.
|
|
100
|
+
*/
|
|
101
|
+
facebook?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Twitter profile URI.
|
|
104
|
+
*/
|
|
105
|
+
twitter?: string;
|
|
106
|
+
/**
|
|
107
|
+
* YouTube profile URI.
|
|
108
|
+
*/
|
|
109
|
+
youtube?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Twitch profile URI.
|
|
112
|
+
*/
|
|
113
|
+
twitch?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Guilded profile URI.
|
|
116
|
+
*/
|
|
117
|
+
guilded?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Visibility of the social network profiles.
|
|
120
|
+
* Available only with the user.social:read scope
|
|
121
|
+
* @example "SOCIAL_NETWORK_VISIBILITY_UNSPECIFIED"
|
|
122
|
+
*/
|
|
123
|
+
visibility: 'SOCIAL_NETWORK_VISIBILITY_UNSPECIFIED' | 'NO_ONE' | 'FRIENDS' | 'FRIENDS_AND_FOLLOWING' | 'FRIENDS_FOLLOWING_AND_FOLLOWERS' | 'EVERYONE';
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export declare function defineOAuthRobloxEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthRobloxConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
|
+
import { withQuery } from "ufo";
|
|
3
|
+
import { defu } from "defu";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
5
|
+
import { useRuntimeConfig } from "#imports";
|
|
6
|
+
export function defineOAuthRobloxEventHandler({ config, onSuccess, onError }) {
|
|
7
|
+
return eventHandler(async (event) => {
|
|
8
|
+
config = defu(config, useRuntimeConfig(event).oauth?.roblox, {
|
|
9
|
+
authorizationURL: "https://apis.roblox.com/oauth/v1/authorize",
|
|
10
|
+
tokenURL: "https://apis.roblox.com/oauth/v1/token",
|
|
11
|
+
authorizationParams: {}
|
|
12
|
+
});
|
|
13
|
+
const query = getQuery(event);
|
|
14
|
+
if (!config.clientId || !config.clientSecret) {
|
|
15
|
+
return handleMissingConfiguration(event, "roblox", ["clientId", "clientSecret"], onError);
|
|
16
|
+
}
|
|
17
|
+
if (query.error) {
|
|
18
|
+
return handleAccessTokenErrorResponse(event, "roblox", query, onError);
|
|
19
|
+
}
|
|
20
|
+
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
21
|
+
if (!query.code) {
|
|
22
|
+
config.scope = config.scope || [];
|
|
23
|
+
return sendRedirect(
|
|
24
|
+
event,
|
|
25
|
+
withQuery(config.authorizationURL, {
|
|
26
|
+
response_type: "code",
|
|
27
|
+
client_id: config.clientId,
|
|
28
|
+
redirect_uri: redirectURL,
|
|
29
|
+
scope: config.scope.join(" "),
|
|
30
|
+
...config.authorizationParams
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
const tokens = await requestAccessToken(config.tokenURL, {
|
|
35
|
+
body: {
|
|
36
|
+
client_id: config.clientId,
|
|
37
|
+
client_secret: config.clientSecret,
|
|
38
|
+
grant_type: "authorization_code",
|
|
39
|
+
redirect_uri: redirectURL,
|
|
40
|
+
code: query.code
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (tokens.error) {
|
|
44
|
+
return handleAccessTokenErrorResponse(event, "roblox", tokens, onError);
|
|
45
|
+
}
|
|
46
|
+
const accessToken = tokens.access_token;
|
|
47
|
+
const userInfo = await $fetch("https://apis.roblox.com/oauth/userinfo", {
|
|
48
|
+
headers: {
|
|
49
|
+
"user-agent": "Nuxt Auth Utils",
|
|
50
|
+
"Authorization": `Bearer ${accessToken}`
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const user = await $fetch(`https://apis.roblox.com/cloud/v2/users/${userInfo.sub}`, {
|
|
54
|
+
headers: {
|
|
55
|
+
"user-agent": "Nuxt Auth Utils",
|
|
56
|
+
"Authorization": `Bearer ${accessToken}`
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return onSuccess(event, {
|
|
60
|
+
tokens,
|
|
61
|
+
user
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
+
import type { EventHandler } from 'h3';
|
|
1
2
|
import type { WebAuthnAuthenticateEventHandlerOptions, WebAuthnCredential } from '#auth-utils';
|
|
2
|
-
export declare function defineWebAuthnAuthenticateEventHandler<T extends WebAuthnCredential>({ storeChallenge, getChallenge, getCredential, allowCredentials, getOptions, onSuccess, onError, }: WebAuthnAuthenticateEventHandlerOptions<T>):
|
|
3
|
-
requestOptions: import("@simplewebauthn/types").PublicKeyCredentialRequestOptionsJSON;
|
|
4
|
-
attemptId: string;
|
|
5
|
-
}>>;
|
|
3
|
+
export declare function defineWebAuthnAuthenticateEventHandler<T extends WebAuthnCredential>({ storeChallenge, getChallenge, getCredential, allowCredentials, getOptions, onSuccess, onError, }: WebAuthnAuthenticateEventHandlerOptions<T>): EventHandler;
|
|
@@ -28,7 +28,7 @@ export function defineWebAuthnAuthenticateEventHandler({
|
|
|
28
28
|
_config.allowCredentials = await allowCredentials(event, body.userName);
|
|
29
29
|
}
|
|
30
30
|
const options = await generateAuthenticationOptions(_config);
|
|
31
|
-
const attemptId = bufferToBase64URLString(getRandomValues(new Uint8Array(32)));
|
|
31
|
+
const attemptId = bufferToBase64URLString(getRandomValues(new Uint8Array(32)).buffer);
|
|
32
32
|
if (storeChallenge) {
|
|
33
33
|
await storeChallenge(event, options.challenge, attemptId);
|
|
34
34
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import type { H3Event } from 'h3';
|
|
1
|
+
import type { H3Event, EventHandler } from 'h3';
|
|
2
2
|
import type { ValidateUserFunction } from '../../../types/webauthn.js';
|
|
3
3
|
import type { WebAuthnUser, WebAuthnRegisterEventHandlerOptions } from '#auth-utils';
|
|
4
|
-
export declare function defineWebAuthnRegisterEventHandler<T extends WebAuthnUser>({ storeChallenge, getChallenge, getOptions, validateUser, excludeCredentials, onSuccess, onError, }: WebAuthnRegisterEventHandlerOptions<T>):
|
|
5
|
-
creationOptions: import("@simplewebauthn/types").PublicKeyCredentialCreationOptionsJSON;
|
|
6
|
-
attemptId: string;
|
|
7
|
-
}>>;
|
|
4
|
+
export declare function defineWebAuthnRegisterEventHandler<T extends WebAuthnUser>({ storeChallenge, getChallenge, getOptions, validateUser, excludeCredentials, onSuccess, onError, }: WebAuthnRegisterEventHandlerOptions<T>): EventHandler;
|
|
8
5
|
export declare function validateUserData<T>(userBody: WebAuthnUser, event: H3Event, fn: ValidateUserFunction<T>): Promise<T>;
|
|
@@ -43,7 +43,7 @@ export function defineWebAuthnRegisterEventHandler({
|
|
|
43
43
|
_config.excludeCredentials = await excludeCredentials(event, user.userName);
|
|
44
44
|
}
|
|
45
45
|
const options = await generateRegistrationOptions(_config);
|
|
46
|
-
const attemptId = bufferToBase64URLString(getRandomValues(new Uint8Array(32)));
|
|
46
|
+
const attemptId = bufferToBase64URLString(getRandomValues(new Uint8Array(32)).buffer);
|
|
47
47
|
if (storeChallenge) {
|
|
48
48
|
await storeChallenge(event, options.challenge, attemptId);
|
|
49
49
|
}
|
|
@@ -81,7 +81,7 @@ export function defineWebAuthnRegisterEventHandler({
|
|
|
81
81
|
user,
|
|
82
82
|
credential: {
|
|
83
83
|
id: verification.registrationInfo.credential.id,
|
|
84
|
-
publicKey: bufferToBase64URLString(verification.registrationInfo.credential.publicKey),
|
|
84
|
+
publicKey: bufferToBase64URLString(verification.registrationInfo.credential.publicKey.buffer),
|
|
85
85
|
counter: verification.registrationInfo.credential.counter,
|
|
86
86
|
backedUp: verification.registrationInfo.credentialBackedUp,
|
|
87
87
|
transports: verification.registrationInfo.credential.transports
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("nitropack
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("nitropack
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -49,6 +49,9 @@ function _useSession(event, config = {}) {
|
|
|
49
49
|
const runtimeConfig = useRuntimeConfig(isEvent(event) ? event : void 0);
|
|
50
50
|
const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || "NUXT_"}SESSION_PASSWORD`;
|
|
51
51
|
sessionConfig = defu({ password: process.env[envSessionPassword] }, runtimeConfig.session);
|
|
52
|
+
if (!sessionConfig.password) {
|
|
53
|
+
console.error(`[nuxt-auth-utils] ${envSessionPassword} environment variable or runtimeConfig.session.password was not set.`);
|
|
54
|
+
}
|
|
52
55
|
}
|
|
53
56
|
const finalConfig = defu(config, sessionConfig);
|
|
54
57
|
return useSession(event, finalConfig);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { H3Event, H3Error } from 'h3';
|
|
2
2
|
export type ATProtoProvider = 'bluesky';
|
|
3
|
-
export type OAuthProvider = ATProtoProvider | 'atlassian' | 'auth0' | 'authentik' | 'azureb2c' | 'battledotnet' | 'cognito' | 'discord' | 'dropbox' | 'facebook' | 'gitea' | 'github' | 'gitlab' | 'google' | 'hubspot' | 'instagram' | 'kick' | 'keycloak' | 'line' | 'linear' | 'linkedin' | 'microsoft' | 'paypal' | 'polar' | 'spotify' | 'seznam' | 'steam' | 'strava' | 'tiktok' | 'twitch' | 'vk' | 'workos' | 'x' | 'xsuaa' | 'yandex' | 'zitadel' | 'apple' | 'livechat' | 'salesforce' | 'slack' | 'heroku' | 'okta' | (string & {});
|
|
3
|
+
export type OAuthProvider = ATProtoProvider | 'atlassian' | 'auth0' | 'authentik' | 'azureb2c' | 'battledotnet' | 'cognito' | 'discord' | 'dropbox' | 'facebook' | 'gitea' | 'github' | 'gitlab' | 'google' | 'hubspot' | 'instagram' | 'kick' | 'keycloak' | 'line' | 'linear' | 'linkedin' | 'microsoft' | 'paypal' | 'polar' | 'spotify' | 'seznam' | 'steam' | 'strava' | 'tiktok' | 'twitch' | 'vk' | 'workos' | 'x' | 'xsuaa' | 'yandex' | 'zitadel' | 'apple' | 'livechat' | 'salesforce' | 'slack' | 'heroku' | 'roblox' | 'okta' | 'ory' | (string & {});
|
|
4
4
|
export type OnError = (event: H3Event, error: H3Error) => Promise<void> | void;
|
|
5
5
|
export interface OAuthConfig<TConfig, TResult = {
|
|
6
6
|
user: any;
|
|
@@ -2,15 +2,16 @@ export const atprotoProviders = ["bluesky"];
|
|
|
2
2
|
export const atprotoProviderDefaultClientMetadata = {
|
|
3
3
|
clientMetadataFilename: "",
|
|
4
4
|
clientName: "",
|
|
5
|
-
clientUri:
|
|
6
|
-
logoUri:
|
|
7
|
-
policyUri:
|
|
8
|
-
tosUri:
|
|
5
|
+
clientUri: void 0,
|
|
6
|
+
logoUri: void 0,
|
|
7
|
+
policyUri: void 0,
|
|
8
|
+
tosUri: void 0,
|
|
9
9
|
scope: ["atproto"],
|
|
10
10
|
grantTypes: ["authorization_code"],
|
|
11
11
|
responseTypes: ["code"],
|
|
12
12
|
applicationType: "web",
|
|
13
|
-
|
|
13
|
+
// @ts-expect-error TypeScript is too smart for its own good
|
|
14
|
+
redirectUris: void 0,
|
|
14
15
|
dpopBoundAccessTokens: true,
|
|
15
16
|
tokenEndpointAuthMethod: "none"
|
|
16
17
|
};
|
package/dist/types.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-auth-utils",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.24",
|
|
4
4
|
"description": "Add Authentication to Nuxt applications with secured & sealed cookies sessions.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,16 +8,21 @@
|
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"type": "module",
|
|
11
|
-
"packageManager": "pnpm@
|
|
11
|
+
"packageManager": "pnpm@10.15.1",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"types": "./dist/types.d.
|
|
15
|
-
"import": "./dist/module.mjs"
|
|
16
|
-
|
|
14
|
+
"types": "./dist/types.d.mts",
|
|
15
|
+
"import": "./dist/module.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/module.mjs",
|
|
19
|
+
"typesVersions": {
|
|
20
|
+
"*": {
|
|
21
|
+
".": [
|
|
22
|
+
"./dist/types.d.mts"
|
|
23
|
+
]
|
|
17
24
|
}
|
|
18
25
|
},
|
|
19
|
-
"main": "./dist/module.cjs",
|
|
20
|
-
"types": "./dist/types.d.ts",
|
|
21
26
|
"files": [
|
|
22
27
|
"dist"
|
|
23
28
|
],
|
|
@@ -30,20 +35,19 @@
|
|
|
30
35
|
"lint": "eslint .",
|
|
31
36
|
"lint:fix": "eslint . --fix",
|
|
32
37
|
"test": "vitest run",
|
|
33
|
-
"test:types": "vue-tsc --noEmit",
|
|
34
|
-
"test:types:playground": "nuxt typecheck playground",
|
|
38
|
+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
|
|
35
39
|
"test:watch": "vitest watch"
|
|
36
40
|
},
|
|
37
41
|
"dependencies": {
|
|
38
|
-
"@adonisjs/hash": "^9.
|
|
39
|
-
"@nuxt/kit": "^
|
|
42
|
+
"@adonisjs/hash": "^9.1.1",
|
|
43
|
+
"@nuxt/kit": "^4.1.0",
|
|
40
44
|
"defu": "^6.1.4",
|
|
41
|
-
"h3": "^1.
|
|
45
|
+
"h3": "^1.15.4",
|
|
42
46
|
"hookable": "^5.5.3",
|
|
43
|
-
"jose": "^
|
|
47
|
+
"jose": "^6.1.0",
|
|
44
48
|
"ofetch": "^1.4.1",
|
|
45
|
-
"openid-client": "^6.1
|
|
46
|
-
"pathe": "^2.0.
|
|
49
|
+
"openid-client": "^6.7.1",
|
|
50
|
+
"pathe": "^2.0.3",
|
|
47
51
|
"scule": "^1.3.0",
|
|
48
52
|
"uncrypto": "^0.1.3"
|
|
49
53
|
},
|
|
@@ -68,20 +72,20 @@
|
|
|
68
72
|
}
|
|
69
73
|
},
|
|
70
74
|
"devDependencies": {
|
|
71
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
72
|
-
"@nuxt/devtools": "2.
|
|
73
|
-
"@nuxt/eslint-config": "^
|
|
74
|
-
"@nuxt/module-builder": "^0.
|
|
75
|
-
"@nuxt/schema": "^
|
|
76
|
-
"@nuxt/test-utils": "^3.
|
|
77
|
-
"@
|
|
78
|
-
"@nuxt/ui
|
|
79
|
-
"@simplewebauthn/types": "^
|
|
80
|
-
"changelogen": "^0.
|
|
81
|
-
"eslint": "^9.
|
|
82
|
-
"nuxt": "^
|
|
83
|
-
"typescript": "5.
|
|
84
|
-
"vitest": "^3.
|
|
85
|
-
"vue-tsc": "^
|
|
75
|
+
"@iconify-json/simple-icons": "^1.2.50",
|
|
76
|
+
"@nuxt/devtools": "2.6.3",
|
|
77
|
+
"@nuxt/eslint-config": "^1.9.0",
|
|
78
|
+
"@nuxt/module-builder": "^1.0.2",
|
|
79
|
+
"@nuxt/schema": "^4.1.0",
|
|
80
|
+
"@nuxt/test-utils": "^3.19.2",
|
|
81
|
+
"@types/node": "latest",
|
|
82
|
+
"@nuxt/ui": "^4.0.0-alpha.1",
|
|
83
|
+
"@simplewebauthn/types": "^12.0.0",
|
|
84
|
+
"changelogen": "^0.6.2",
|
|
85
|
+
"eslint": "^9.34.0",
|
|
86
|
+
"nuxt": "^4.1.0",
|
|
87
|
+
"typescript": "5.9.2",
|
|
88
|
+
"vitest": "^3.2.4",
|
|
89
|
+
"vue-tsc": "^3.0.6"
|
|
86
90
|
}
|
|
87
91
|
}
|
package/dist/module.cjs
DELETED
package/dist/module.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import { ScryptConfig } from '@adonisjs/hash/types';
|
|
3
|
-
import { SessionConfig } from 'h3';
|
|
4
|
-
|
|
5
|
-
interface ModuleOptions {
|
|
6
|
-
/**
|
|
7
|
-
* Enable WebAuthn (Passkeys)
|
|
8
|
-
* @default false
|
|
9
|
-
*/
|
|
10
|
-
webAuthn?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Enable atproto OAuth (Bluesky, etc.)
|
|
13
|
-
* @default false
|
|
14
|
-
*/
|
|
15
|
-
atproto?: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Hash options used for password hashing
|
|
18
|
-
*/
|
|
19
|
-
hash?: {
|
|
20
|
-
/**
|
|
21
|
-
* scrypt options used for password hashing
|
|
22
|
-
*/
|
|
23
|
-
scrypt?: ScryptConfig;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
declare module 'nuxt/schema' {
|
|
27
|
-
interface RuntimeConfig {
|
|
28
|
-
hash: {
|
|
29
|
-
scrypt: ScryptConfig;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Session configuration
|
|
33
|
-
*/
|
|
34
|
-
session: SessionConfig;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
38
|
-
|
|
39
|
-
export { type ModuleOptions, _default as default };
|
package/dist/types.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { type ModuleOptions, default } from './module'
|