nuxt-auth-utils 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +9 -0
- package/dist/runtime/server/lib/oauth/auth0.d.ts +6 -0
- package/dist/runtime/server/lib/oauth/auth0.mjs +2 -1
- package/dist/runtime/server/lib/oauth/discord.mjs +0 -1
- package/dist/runtime/server/lib/oauth/microsoft.d.ts +52 -0
- package/dist/runtime/server/lib/oauth/microsoft.mjs +87 -0
- package/dist/runtime/server/utils/oauth.d.ts +2 -0
- package/dist/runtime/server/utils/oauth.mjs +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,12 +150,13 @@ It can also be set using environment variables:
|
|
|
150
150
|
#### Supported OAuth Providers
|
|
151
151
|
|
|
152
152
|
- Auth0
|
|
153
|
+
- Battle.net
|
|
153
154
|
- Discord
|
|
154
155
|
- GitHub
|
|
155
156
|
- Google
|
|
157
|
+
- Microsoft
|
|
156
158
|
- Spotify
|
|
157
159
|
- Twitch
|
|
158
|
-
- Battle.net
|
|
159
160
|
|
|
160
161
|
You can add your favorite provider by creating a new file in [src/runtime/server/lib/oauth/](./src/runtime/server/lib/oauth/).
|
|
161
162
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -79,6 +79,15 @@ const module = defineNuxtModule({
|
|
|
79
79
|
clientSecret: "",
|
|
80
80
|
domain: ""
|
|
81
81
|
});
|
|
82
|
+
runtimeConfig.oauth.microsoft = defu(runtimeConfig.oauth.microsoft, {
|
|
83
|
+
clientId: "",
|
|
84
|
+
clientSecret: "",
|
|
85
|
+
tenant: "",
|
|
86
|
+
scope: [],
|
|
87
|
+
authorizationURL: "",
|
|
88
|
+
tokenURL: "",
|
|
89
|
+
userURL: ""
|
|
90
|
+
});
|
|
82
91
|
runtimeConfig.oauth.discord = defu(runtimeConfig.oauth.discord, {
|
|
83
92
|
clientId: "",
|
|
84
93
|
clientSecret: ""
|
|
@@ -32,5 +32,11 @@ export interface OAuthAuth0Config {
|
|
|
32
32
|
* @default false
|
|
33
33
|
*/
|
|
34
34
|
emailRequired?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Maximum Authentication Age. If the elapsed time is greater than this value, the OP must attempt to actively re-authenticate the end-user.
|
|
37
|
+
* @default 0
|
|
38
|
+
* @see https://auth0.com/docs/authenticate/login/max-age-reauthentication
|
|
39
|
+
*/
|
|
40
|
+
maxAge?: number;
|
|
35
41
|
}
|
|
36
42
|
export declare function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
|
|
@@ -31,7 +31,8 @@ export function auth0EventHandler({ config, onSuccess, onError }) {
|
|
|
31
31
|
client_id: config.clientId,
|
|
32
32
|
redirect_uri: redirectUrl,
|
|
33
33
|
scope: config.scope.join(" "),
|
|
34
|
-
audience: config.audience || ""
|
|
34
|
+
audience: config.audience || "",
|
|
35
|
+
max_age: config.maxAge || 0
|
|
35
36
|
})
|
|
36
37
|
);
|
|
37
38
|
}
|
|
@@ -60,7 +60,6 @@ export function discordEventHandler({ config, onSuccess, onError }) {
|
|
|
60
60
|
return { error };
|
|
61
61
|
});
|
|
62
62
|
if (tokens.error) {
|
|
63
|
-
console.log(tokens);
|
|
64
63
|
const error = createError({
|
|
65
64
|
statusCode: 401,
|
|
66
65
|
message: `Discord login failed: ${tokens.error?.data?.error_description || "Unknown error"}`,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { H3Event, H3Error } from 'h3';
|
|
2
|
+
export interface OAuthMicrosoftConfig {
|
|
3
|
+
/**
|
|
4
|
+
* Microsoft OAuth Client ID
|
|
5
|
+
* @default process.env.NUXT_OAUTH_MICROSOFT_CLIENT_ID
|
|
6
|
+
*/
|
|
7
|
+
clientId?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Microsoft OAuth Client Secret
|
|
10
|
+
* @default process.env.NUXT_OAUTH_MICROSOFT_CLIENT_SECRET
|
|
11
|
+
*/
|
|
12
|
+
clientSecret?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Microsoft OAuth Tenant ID
|
|
15
|
+
* @default process.env.NUXT_OAUTH_MICROSOFT_TENANT
|
|
16
|
+
*/
|
|
17
|
+
tenant?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Microsoft OAuth Scope
|
|
20
|
+
* @default ['User.Read']
|
|
21
|
+
* @see https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc
|
|
22
|
+
*/
|
|
23
|
+
scope?: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Microsoft OAuth Authorization URL
|
|
26
|
+
* @default https://login.microsoftonline.com/${tenant}/oauth2/v2.0/authorize
|
|
27
|
+
* @see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
|
28
|
+
*/
|
|
29
|
+
authorizationURL?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Microsoft OAuth Token URL
|
|
32
|
+
* @default https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token
|
|
33
|
+
* @see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
|
34
|
+
*/
|
|
35
|
+
tokenURL?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Microsoft OAuth User URL
|
|
38
|
+
* @default https://graph.microsoft.com/v1.0/me
|
|
39
|
+
* @see https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http
|
|
40
|
+
*/
|
|
41
|
+
userURL?: string;
|
|
42
|
+
}
|
|
43
|
+
interface OAuthConfig {
|
|
44
|
+
config?: OAuthMicrosoftConfig;
|
|
45
|
+
onSuccess: (event: H3Event, result: {
|
|
46
|
+
user: any;
|
|
47
|
+
tokens: any;
|
|
48
|
+
}) => Promise<void> | void;
|
|
49
|
+
onError?: (event: H3Event, error: H3Error) => Promise<void> | void;
|
|
50
|
+
}
|
|
51
|
+
export declare function microsoftEventHandler({ config, onSuccess, onError }: OAuthConfig): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
import { useRuntimeConfig } from "#imports";
|
|
6
|
+
export function microsoftEventHandler({ config, onSuccess, onError }) {
|
|
7
|
+
return eventHandler(async (event) => {
|
|
8
|
+
config = defu(config, useRuntimeConfig(event).oauth?.microsoft);
|
|
9
|
+
const { code } = getQuery(event);
|
|
10
|
+
if (!config.clientId || !config.clientSecret || !config.tenant) {
|
|
11
|
+
const error = createError({
|
|
12
|
+
statusCode: 500,
|
|
13
|
+
message: "Missing NUXT_OAUTH_MICROSOFT_CLIENT_ID or NUXT_OAUTH_MICROSOFT_CLIENT_SECRET or NUXT_OAUTH_MICROSOFT_TENANT env variables."
|
|
14
|
+
});
|
|
15
|
+
if (!onError)
|
|
16
|
+
throw error;
|
|
17
|
+
return onError(event, error);
|
|
18
|
+
}
|
|
19
|
+
const authorizationURL = config.authorizationURL || `https://login.microsoftonline.com/${config.tenant}/oauth2/v2.0/authorize`;
|
|
20
|
+
const tokenURL = config.tokenURL || `https://login.microsoftonline.com/${config.tenant}/oauth2/v2.0/token`;
|
|
21
|
+
const redirectUrl = getRequestURL(event).href;
|
|
22
|
+
if (!code) {
|
|
23
|
+
const scope = config.scope && config.scope.length > 0 ? config.scope : ["User.Read"];
|
|
24
|
+
return sendRedirect(
|
|
25
|
+
event,
|
|
26
|
+
withQuery(authorizationURL, {
|
|
27
|
+
client_id: config.clientId,
|
|
28
|
+
response_type: "code",
|
|
29
|
+
redirect_uri: redirectUrl,
|
|
30
|
+
scope: scope.join("%20")
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
const data = new URLSearchParams();
|
|
35
|
+
data.append("grant_type", "authorization_code");
|
|
36
|
+
data.append("client_id", config.clientId);
|
|
37
|
+
data.append("client_secret", config.clientSecret);
|
|
38
|
+
data.append("redirect_uri", parsePath(redirectUrl).pathname);
|
|
39
|
+
data.append("code", String(code));
|
|
40
|
+
const tokens = await ofetch(
|
|
41
|
+
tokenURL,
|
|
42
|
+
{
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: {
|
|
45
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
46
|
+
},
|
|
47
|
+
body: data
|
|
48
|
+
}
|
|
49
|
+
).catch((error) => {
|
|
50
|
+
return { error };
|
|
51
|
+
});
|
|
52
|
+
if (tokens.error) {
|
|
53
|
+
const error = createError({
|
|
54
|
+
statusCode: 401,
|
|
55
|
+
message: `Microsoft login failed: ${tokens.error?.data?.error_description || "Unknown error"}`,
|
|
56
|
+
data: tokens
|
|
57
|
+
});
|
|
58
|
+
if (!onError)
|
|
59
|
+
throw error;
|
|
60
|
+
return onError(event, error);
|
|
61
|
+
}
|
|
62
|
+
const tokenType = tokens.token_type;
|
|
63
|
+
const accessToken = tokens.access_token;
|
|
64
|
+
const userURL = config.userURL || "https://graph.microsoft.com/v1.0/me";
|
|
65
|
+
const user = await ofetch(userURL, {
|
|
66
|
+
headers: {
|
|
67
|
+
Authorization: `${tokenType} ${accessToken}`
|
|
68
|
+
}
|
|
69
|
+
}).catch((error) => {
|
|
70
|
+
return { error };
|
|
71
|
+
});
|
|
72
|
+
if (user.error) {
|
|
73
|
+
const error = createError({
|
|
74
|
+
statusCode: 401,
|
|
75
|
+
message: `Microsoft login failed: ${user.error || "Unknown error"}`,
|
|
76
|
+
data: user
|
|
77
|
+
});
|
|
78
|
+
if (!onError)
|
|
79
|
+
throw error;
|
|
80
|
+
return onError(event, error);
|
|
81
|
+
}
|
|
82
|
+
return onSuccess(event, {
|
|
83
|
+
tokens,
|
|
84
|
+
user
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -3,6 +3,7 @@ import { googleEventHandler } from '../lib/oauth/google';
|
|
|
3
3
|
import { spotifyEventHandler } from '../lib/oauth/spotify';
|
|
4
4
|
import { twitchEventHandler } from '../lib/oauth/twitch';
|
|
5
5
|
import { auth0EventHandler } from '../lib/oauth/auth0';
|
|
6
|
+
import { microsoftEventHandler } from '../lib/oauth/microsoft';
|
|
6
7
|
import { discordEventHandler } from '../lib/oauth/discord';
|
|
7
8
|
import { battledotnetEventHandler } from '../lib/oauth/battledotnet';
|
|
8
9
|
export declare const oauth: {
|
|
@@ -11,6 +12,7 @@ export declare const oauth: {
|
|
|
11
12
|
googleEventHandler: typeof googleEventHandler;
|
|
12
13
|
twitchEventHandler: typeof twitchEventHandler;
|
|
13
14
|
auth0EventHandler: typeof auth0EventHandler;
|
|
15
|
+
microsoftEventHandler: typeof microsoftEventHandler;
|
|
14
16
|
discordEventHandler: typeof discordEventHandler;
|
|
15
17
|
battledotnetEventHandler: typeof battledotnetEventHandler;
|
|
16
18
|
};
|
|
@@ -3,6 +3,7 @@ import { googleEventHandler } from "../lib/oauth/google.mjs";
|
|
|
3
3
|
import { spotifyEventHandler } from "../lib/oauth/spotify.mjs";
|
|
4
4
|
import { twitchEventHandler } from "../lib/oauth/twitch.mjs";
|
|
5
5
|
import { auth0EventHandler } from "../lib/oauth/auth0.mjs";
|
|
6
|
+
import { microsoftEventHandler } from "../lib/oauth/microsoft.mjs";
|
|
6
7
|
import { discordEventHandler } from "../lib/oauth/discord.mjs";
|
|
7
8
|
import { battledotnetEventHandler } from "../lib/oauth/battledotnet.mjs";
|
|
8
9
|
export const oauth = {
|
|
@@ -11,6 +12,7 @@ export const oauth = {
|
|
|
11
12
|
googleEventHandler,
|
|
12
13
|
twitchEventHandler,
|
|
13
14
|
auth0EventHandler,
|
|
15
|
+
microsoftEventHandler,
|
|
14
16
|
discordEventHandler,
|
|
15
17
|
battledotnetEventHandler
|
|
16
18
|
};
|