nuxt-auth-utils 0.3.3 → 0.3.5
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 -0
- package/dist/module.d.mts +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.json +2 -2
- package/dist/module.mjs +33 -17
- package/dist/runtime/app/plugins/session.client.js +3 -1
- package/dist/runtime/server/lib/oauth/auth0.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/auth0.js +7 -17
- package/dist/runtime/server/lib/oauth/battledotnet.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/battledotnet.js +11 -17
- package/dist/runtime/server/lib/oauth/cognito.d.ts +10 -0
- package/dist/runtime/server/lib/oauth/cognito.js +11 -20
- package/dist/runtime/server/lib/oauth/discord.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/discord.js +7 -17
- package/dist/runtime/server/lib/oauth/facebook.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/facebook.js +6 -16
- package/dist/runtime/server/lib/oauth/github.d.ts +6 -0
- package/dist/runtime/server/lib/oauth/github.js +5 -15
- package/dist/runtime/server/lib/oauth/google.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/google.js +6 -17
- package/dist/runtime/server/lib/oauth/keycloak.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/keycloak.js +6 -16
- package/dist/runtime/server/lib/oauth/linkedin.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/linkedin.js +7 -17
- package/dist/runtime/server/lib/oauth/microsoft.d.ts +1 -1
- package/dist/runtime/server/lib/oauth/microsoft.js +6 -16
- package/dist/runtime/server/lib/oauth/paypal.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/paypal.js +6 -16
- package/dist/runtime/server/lib/oauth/spotify.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/spotify.js +7 -17
- package/dist/runtime/server/lib/oauth/steam.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/steam.js +4 -8
- package/dist/runtime/server/lib/oauth/twitch.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/twitch.js +6 -16
- package/dist/runtime/server/lib/oauth/x.d.ts +6 -6
- package/dist/runtime/server/lib/oauth/x.js +10 -44
- package/dist/runtime/server/lib/oauth/xsuaa.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/xsuaa.js +7 -17
- package/dist/runtime/server/lib/oauth/yandex.d.ts +5 -0
- package/dist/runtime/server/lib/oauth/yandex.js +6 -17
- package/dist/runtime/server/lib/utils.d.ts +9 -0
- package/dist/runtime/server/lib/utils.js +21 -0
- package/dist/runtime/types/index.d.ts +1 -1
- package/dist/runtime/types/oauth-config.d.ts +3 -1
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -233,6 +233,8 @@ export default oauthGitHubEventHandler({
|
|
|
233
233
|
|
|
234
234
|
Make sure to set the callback URL in your OAuth app settings as `<your-domain>/auth/github`.
|
|
235
235
|
|
|
236
|
+
If the redirect URL mismatch in production, this means that the module cannot guess the right redirect URL. You can set the `NUXT_OAUTH_<PROVIDER>_REDIRECT_URL` env variable to overwrite the default one.
|
|
237
|
+
|
|
236
238
|
### Extend Session
|
|
237
239
|
|
|
238
240
|
We leverage hooks to let you extend the session data with your own data or log when the user clears the session.
|
package/dist/module.d.mts
CHANGED
|
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
2
2
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
}
|
|
5
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
5
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
|
|
7
7
|
export { type ModuleOptions, _default as default };
|
package/dist/module.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
2
2
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
}
|
|
5
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
5
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
|
|
7
7
|
export { type ModuleOptions, _default as default };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -55,25 +55,30 @@ const module = defineNuxtModule({
|
|
|
55
55
|
runtimeConfig.oauth = defu(runtimeConfig.oauth, {});
|
|
56
56
|
runtimeConfig.oauth.github = defu(runtimeConfig.oauth.github, {
|
|
57
57
|
clientId: "",
|
|
58
|
-
clientSecret: ""
|
|
58
|
+
clientSecret: "",
|
|
59
|
+
redirectURL: ""
|
|
59
60
|
});
|
|
60
61
|
runtimeConfig.oauth.spotify = defu(runtimeConfig.oauth.spotify, {
|
|
61
62
|
clientId: "",
|
|
62
|
-
clientSecret: ""
|
|
63
|
+
clientSecret: "",
|
|
64
|
+
redirectURL: ""
|
|
63
65
|
});
|
|
64
66
|
runtimeConfig.oauth.google = defu(runtimeConfig.oauth.google, {
|
|
65
67
|
clientId: "",
|
|
66
|
-
clientSecret: ""
|
|
68
|
+
clientSecret: "",
|
|
69
|
+
redirectURL: ""
|
|
67
70
|
});
|
|
68
71
|
runtimeConfig.oauth.twitch = defu(runtimeConfig.oauth.twitch, {
|
|
69
72
|
clientId: "",
|
|
70
|
-
clientSecret: ""
|
|
73
|
+
clientSecret: "",
|
|
74
|
+
redirectURL: ""
|
|
71
75
|
});
|
|
72
76
|
runtimeConfig.oauth.auth0 = defu(runtimeConfig.oauth.auth0, {
|
|
73
77
|
clientId: "",
|
|
74
78
|
clientSecret: "",
|
|
75
79
|
domain: "",
|
|
76
|
-
audience: ""
|
|
80
|
+
audience: "",
|
|
81
|
+
redirectURL: ""
|
|
77
82
|
});
|
|
78
83
|
runtimeConfig.oauth.microsoft = defu(runtimeConfig.oauth.microsoft, {
|
|
79
84
|
clientId: "",
|
|
@@ -83,55 +88,66 @@ const module = defineNuxtModule({
|
|
|
83
88
|
authorizationURL: "",
|
|
84
89
|
tokenURL: "",
|
|
85
90
|
userURL: "",
|
|
86
|
-
|
|
91
|
+
redirectURL: ""
|
|
87
92
|
});
|
|
88
93
|
runtimeConfig.oauth.discord = defu(runtimeConfig.oauth.discord, {
|
|
89
94
|
clientId: "",
|
|
90
|
-
clientSecret: ""
|
|
95
|
+
clientSecret: "",
|
|
96
|
+
redirectURL: ""
|
|
91
97
|
});
|
|
92
98
|
runtimeConfig.oauth.battledotnet = defu(runtimeConfig.oauth.battledotnet, {
|
|
93
99
|
clientId: "",
|
|
94
|
-
clientSecret: ""
|
|
100
|
+
clientSecret: "",
|
|
101
|
+
redirectURL: ""
|
|
95
102
|
});
|
|
96
103
|
runtimeConfig.oauth.keycloak = defu(runtimeConfig.oauth.keycloak, {
|
|
97
104
|
clientId: "",
|
|
98
105
|
clientSecret: "",
|
|
99
106
|
serverUrl: "",
|
|
100
|
-
realm: ""
|
|
107
|
+
realm: "",
|
|
108
|
+
redirectURL: ""
|
|
101
109
|
});
|
|
102
110
|
runtimeConfig.oauth.linkedin = defu(runtimeConfig.oauth.linkedin, {
|
|
103
111
|
clientId: "",
|
|
104
|
-
clientSecret: ""
|
|
112
|
+
clientSecret: "",
|
|
113
|
+
redirectURL: ""
|
|
105
114
|
});
|
|
106
115
|
runtimeConfig.oauth.cognito = defu(runtimeConfig.oauth.cognito, {
|
|
107
116
|
clientId: "",
|
|
108
117
|
clientSecret: "",
|
|
109
118
|
region: "",
|
|
110
|
-
userPoolId: ""
|
|
119
|
+
userPoolId: "",
|
|
120
|
+
redirectURL: ""
|
|
111
121
|
});
|
|
112
122
|
runtimeConfig.oauth.facebook = defu(runtimeConfig.oauth.facebook, {
|
|
113
123
|
clientId: "",
|
|
114
|
-
clientSecret: ""
|
|
124
|
+
clientSecret: "",
|
|
125
|
+
redirectURL: ""
|
|
115
126
|
});
|
|
116
127
|
runtimeConfig.oauth.paypal = defu(runtimeConfig.oauth.paypal, {
|
|
117
128
|
clientId: "",
|
|
118
|
-
clientSecret: ""
|
|
129
|
+
clientSecret: "",
|
|
130
|
+
redirectURL: ""
|
|
119
131
|
});
|
|
120
132
|
runtimeConfig.oauth.steam = defu(runtimeConfig.oauth.steam, {
|
|
121
|
-
apiKey: ""
|
|
133
|
+
apiKey: "",
|
|
134
|
+
redirectURL: ""
|
|
122
135
|
});
|
|
123
136
|
runtimeConfig.oauth.x = defu(runtimeConfig.oauth.x, {
|
|
124
137
|
clientId: "",
|
|
125
|
-
clientSecret: ""
|
|
138
|
+
clientSecret: "",
|
|
139
|
+
redirectURL: ""
|
|
126
140
|
});
|
|
127
141
|
runtimeConfig.oauth.xsuaa = defu(runtimeConfig.oauth.xsuaa, {
|
|
128
142
|
clientId: "",
|
|
129
143
|
clientSecret: "",
|
|
130
|
-
domain: ""
|
|
144
|
+
domain: "",
|
|
145
|
+
redirectURL: ""
|
|
131
146
|
});
|
|
132
147
|
runtimeConfig.oauth.yandex = defu(runtimeConfig.oauth.yandex, {
|
|
133
148
|
clientId: "",
|
|
134
|
-
clientSecret: ""
|
|
149
|
+
clientSecret: "",
|
|
150
|
+
redirectURL: ""
|
|
135
151
|
});
|
|
136
152
|
}
|
|
137
153
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useUserSession } from "#imports";
|
|
2
2
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
3
|
-
if (!nuxtApp.payload.serverRendered
|
|
3
|
+
if (!nuxtApp.payload.serverRendered) {
|
|
4
|
+
await useUserSession().fetch();
|
|
5
|
+
} else if (Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached)) {
|
|
4
6
|
nuxtApp.hook("app:mounted", async () => {
|
|
5
7
|
await useUserSession().fetch();
|
|
6
8
|
});
|
|
@@ -51,5 +51,10 @@ export interface OAuthAuth0Config {
|
|
|
51
51
|
* @example { display: 'popup' }
|
|
52
52
|
*/
|
|
53
53
|
authorizationParams?: Record<string, string>;
|
|
54
|
+
/**
|
|
55
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
56
|
+
* @default process.env.NUXT_OAUTH_AUTH0_REDIRECT_URL or current URL
|
|
57
|
+
*/
|
|
58
|
+
redirectURL?: string;
|
|
54
59
|
}
|
|
55
60
|
export declare function oauthAuth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { eventHandler,
|
|
1
|
+
import { eventHandler, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parsePath } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse } from "../utils.js";
|
|
4
5
|
import { useRuntimeConfig } from "#imports";
|
|
5
6
|
export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
|
|
6
7
|
return eventHandler(async (event) => {
|
|
@@ -9,16 +10,11 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
|
|
|
9
10
|
});
|
|
10
11
|
const { code } = getQuery(event);
|
|
11
12
|
if (!config.clientId || !config.clientSecret || !config.domain) {
|
|
12
|
-
|
|
13
|
-
statusCode: 500,
|
|
14
|
-
message: "Missing NUXT_OAUTH_AUTH0_CLIENT_ID or NUXT_OAUTH_AUTH0_CLIENT_SECRET or NUXT_OAUTH_AUTH0_DOMAIN env variables."
|
|
15
|
-
});
|
|
16
|
-
if (!onError) throw error;
|
|
17
|
-
return onError(event, error);
|
|
13
|
+
return handleMissingConfiguration(event, "auth0", ["clientId", "clientSecret", "domain"], onError);
|
|
18
14
|
}
|
|
19
15
|
const authorizationURL = `https://${config.domain}/authorize`;
|
|
20
16
|
const tokenURL = `https://${config.domain}/oauth/token`;
|
|
21
|
-
const
|
|
17
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
22
18
|
if (!code) {
|
|
23
19
|
config.scope = config.scope || ["openid", "offline_access"];
|
|
24
20
|
if (config.emailRequired && !config.scope.includes("email")) {
|
|
@@ -29,7 +25,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
|
|
|
29
25
|
withQuery(authorizationURL, {
|
|
30
26
|
response_type: "code",
|
|
31
27
|
client_id: config.clientId,
|
|
32
|
-
redirect_uri:
|
|
28
|
+
redirect_uri: redirectURL,
|
|
33
29
|
scope: config.scope.join(" "),
|
|
34
30
|
audience: config.audience || "",
|
|
35
31
|
max_age: config.maxAge || 0,
|
|
@@ -49,7 +45,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
|
|
|
49
45
|
grant_type: "authorization_code",
|
|
50
46
|
client_id: config.clientId,
|
|
51
47
|
client_secret: config.clientSecret,
|
|
52
|
-
redirect_uri: parsePath(
|
|
48
|
+
redirect_uri: parsePath(redirectURL).pathname,
|
|
53
49
|
code
|
|
54
50
|
}
|
|
55
51
|
}
|
|
@@ -57,13 +53,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
|
|
|
57
53
|
return { error };
|
|
58
54
|
});
|
|
59
55
|
if (tokens.error) {
|
|
60
|
-
|
|
61
|
-
statusCode: 401,
|
|
62
|
-
message: `Auth0 login failed: ${tokens.error?.data?.error_description || "Unknown error"}`,
|
|
63
|
-
data: tokens
|
|
64
|
-
});
|
|
65
|
-
if (!onError) throw error;
|
|
66
|
-
return onError(event, error);
|
|
56
|
+
return handleAccessTokenErrorResponse(event, "auth0", tokens, onError);
|
|
67
57
|
}
|
|
68
58
|
const tokenType = tokens.token_type;
|
|
69
59
|
const accessToken = tokens.access_token;
|
|
@@ -39,5 +39,10 @@ export interface OAuthBattledotnetConfig {
|
|
|
39
39
|
* @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
|
|
40
40
|
*/
|
|
41
41
|
authorizationParams?: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
44
|
+
* @default process.env.NUXT_OAUTH_BATTLEDOTNET_REDIRECT_URL or current URL
|
|
45
|
+
*/
|
|
46
|
+
redirectURL?: string;
|
|
42
47
|
}
|
|
43
48
|
export declare function oauthBattledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
3
3
|
import { withQuery, parsePath } from "ufo";
|
|
4
4
|
import { defu } from "defu";
|
|
5
|
+
import { handleAccessTokenErrorResponse, handleMissingConfiguration } from "../utils.js";
|
|
5
6
|
import { useRuntimeConfig } from "#imports";
|
|
6
7
|
export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
|
|
7
8
|
return eventHandler(async (event) => {
|
|
@@ -22,13 +23,14 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
|
|
|
22
23
|
return onError(event, error);
|
|
23
24
|
}
|
|
24
25
|
if (!config.clientId || !config.clientSecret) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
return handleMissingConfiguration(
|
|
27
|
+
event,
|
|
28
|
+
"battledotnet",
|
|
29
|
+
["clientId", "clientSecret"],
|
|
30
|
+
onError
|
|
31
|
+
);
|
|
31
32
|
}
|
|
33
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
32
34
|
if (!code) {
|
|
33
35
|
config.scope = config.scope || ["openid"];
|
|
34
36
|
config.region = config.region || "EU";
|
|
@@ -36,12 +38,11 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
|
|
|
36
38
|
config.authorizationURL = "https://oauth.battlenet.com.cn/authorize";
|
|
37
39
|
config.tokenURL = "https://oauth.battlenet.com.cn/token";
|
|
38
40
|
}
|
|
39
|
-
const redirectUrl2 = getRequestURL(event).href;
|
|
40
41
|
return sendRedirect(
|
|
41
42
|
event,
|
|
42
43
|
withQuery(config.authorizationURL, {
|
|
43
44
|
client_id: config.clientId,
|
|
44
|
-
redirect_uri:
|
|
45
|
+
redirect_uri: redirectURL,
|
|
45
46
|
scope: config.scope.join(" "),
|
|
46
47
|
state: randomUUID(),
|
|
47
48
|
// Todo: handle PKCE flow
|
|
@@ -50,7 +51,6 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
|
|
|
50
51
|
})
|
|
51
52
|
);
|
|
52
53
|
}
|
|
53
|
-
const redirectUrl = getRequestURL(event).href;
|
|
54
54
|
config.scope = config.scope || [];
|
|
55
55
|
if (!config.scope.includes("openid")) {
|
|
56
56
|
config.scope.push("openid");
|
|
@@ -68,20 +68,14 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
|
|
|
68
68
|
code,
|
|
69
69
|
grant_type: "authorization_code",
|
|
70
70
|
scope: config.scope.join(" "),
|
|
71
|
-
redirect_uri: parsePath(
|
|
71
|
+
redirect_uri: parsePath(redirectURL).pathname
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
).catch((error) => {
|
|
75
75
|
return { error };
|
|
76
76
|
});
|
|
77
77
|
if (tokens.error) {
|
|
78
|
-
|
|
79
|
-
statusCode: 401,
|
|
80
|
-
message: `Battle.net login failed: ${tokens.error || "Unknown error"}`,
|
|
81
|
-
data: tokens
|
|
82
|
-
});
|
|
83
|
-
if (!onError) throw error;
|
|
84
|
-
return onError(event, error);
|
|
78
|
+
return handleAccessTokenErrorResponse(event, "battle.net", tokens, onError);
|
|
85
79
|
}
|
|
86
80
|
const accessToken = tokens.access_token;
|
|
87
81
|
const user = await $fetch("https://oauth.battle.net/userinfo", {
|
|
@@ -30,5 +30,15 @@ export interface OAuthCognitoConfig {
|
|
|
30
30
|
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html
|
|
31
31
|
*/
|
|
32
32
|
authorizationParams?: Record<string, string>;
|
|
33
|
+
/**
|
|
34
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
35
|
+
* @default process.env.NUXT_OAUTH_COGNITO_REDIRECT_URL or current URL
|
|
36
|
+
*/
|
|
37
|
+
redirectURL?: string;
|
|
38
|
+
/**
|
|
39
|
+
* AWS Cognito App Custom Domain – some pool configurations require this
|
|
40
|
+
* @default ''
|
|
41
|
+
*/
|
|
42
|
+
domain?: string;
|
|
33
43
|
}
|
|
34
44
|
export declare function oauthCognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { eventHandler,
|
|
1
|
+
import { eventHandler, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parsePath } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
+
import { handleAccessTokenErrorResponse, handleMissingConfiguration } from "../utils.js";
|
|
4
5
|
import { useRuntimeConfig } from "#imports";
|
|
5
6
|
export function oauthCognitoEventHandler({ config, onSuccess, onError }) {
|
|
6
7
|
return eventHandler(async (event) => {
|
|
@@ -9,23 +10,19 @@ export function oauthCognitoEventHandler({ config, onSuccess, onError }) {
|
|
|
9
10
|
});
|
|
10
11
|
const { code } = getQuery(event);
|
|
11
12
|
if (!config.clientId || !config.clientSecret || !config.userPoolId || !config.region) {
|
|
12
|
-
|
|
13
|
-
statusCode: 500,
|
|
14
|
-
message: "Missing NUXT_OAUTH_COGNITO_CLIENT_ID, NUXT_OAUTH_COGNITO_CLIENT_SECRET, NUXT_OAUTH_COGNITO_USER_POOL_ID, or NUXT_OAUTH_COGNITO_REGION env variables."
|
|
15
|
-
});
|
|
16
|
-
if (!onError) throw error;
|
|
17
|
-
return onError(event, error);
|
|
13
|
+
return handleMissingConfiguration(event, "cognito", ["clientId", "clientSecret", "userPoolId", "region"], onError);
|
|
18
14
|
}
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
15
|
+
const urlBase = config?.domain || `${config.userPoolId}.auth.${config.region}.amazoncognito.com`;
|
|
16
|
+
const authorizationURL = `https://${urlBase}/oauth2/authorize`;
|
|
17
|
+
const tokenURL = `https://${urlBase}/oauth2/token`;
|
|
18
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
22
19
|
if (!code) {
|
|
23
20
|
config.scope = config.scope || ["openid", "profile"];
|
|
24
21
|
return sendRedirect(
|
|
25
22
|
event,
|
|
26
23
|
withQuery(authorizationURL, {
|
|
27
24
|
client_id: config.clientId,
|
|
28
|
-
redirect_uri:
|
|
25
|
+
redirect_uri: redirectURL,
|
|
29
26
|
response_type: "code",
|
|
30
27
|
scope: config.scope.join(" "),
|
|
31
28
|
...config.authorizationParams
|
|
@@ -39,23 +36,17 @@ export function oauthCognitoEventHandler({ config, onSuccess, onError }) {
|
|
|
39
36
|
headers: {
|
|
40
37
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
41
38
|
},
|
|
42
|
-
body: `grant_type=authorization_code&client_id=${config.clientId}&client_secret=${config.clientSecret}&redirect_uri=${parsePath(
|
|
39
|
+
body: `grant_type=authorization_code&client_id=${config.clientId}&client_secret=${config.clientSecret}&redirect_uri=${parsePath(redirectURL).pathname}&code=${code}`
|
|
43
40
|
}
|
|
44
41
|
).catch((error) => {
|
|
45
42
|
return { error };
|
|
46
43
|
});
|
|
47
44
|
if (tokens.error) {
|
|
48
|
-
|
|
49
|
-
statusCode: 401,
|
|
50
|
-
message: `Cognito login failed: ${tokens.error_description || "Unknown error"}`,
|
|
51
|
-
data: tokens
|
|
52
|
-
});
|
|
53
|
-
if (!onError) throw error;
|
|
54
|
-
return onError(event, error);
|
|
45
|
+
return handleAccessTokenErrorResponse(event, "cognito", tokens, onError);
|
|
55
46
|
}
|
|
56
47
|
const tokenType = tokens.token_type;
|
|
57
48
|
const accessToken = tokens.access_token;
|
|
58
|
-
const user = await $fetch(`https://${
|
|
49
|
+
const user = await $fetch(`https://${urlBase}/oauth2/userInfo`, {
|
|
59
50
|
headers: {
|
|
60
51
|
Authorization: `${tokenType} ${accessToken}`
|
|
61
52
|
}
|
|
@@ -44,5 +44,10 @@ export interface OAuthDiscordConfig {
|
|
|
44
44
|
* @example { allow_signup: 'true' }
|
|
45
45
|
*/
|
|
46
46
|
authorizationParams?: Record<string, string>;
|
|
47
|
+
/**
|
|
48
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
49
|
+
* @default process.env.NUXT_OAUTH_DISCORD_REDIRECT_URL or current URL
|
|
50
|
+
*/
|
|
51
|
+
redirectURL?: string;
|
|
47
52
|
}
|
|
48
53
|
export declare function oauthDiscordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { eventHandler,
|
|
1
|
+
import { eventHandler, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery, parseURL, stringifyParsedURL } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
+
import { handleAccessTokenErrorResponse, handleMissingConfiguration } from "../utils.js";
|
|
4
5
|
import { useRuntimeConfig } from "#imports";
|
|
5
6
|
export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
|
|
6
7
|
return eventHandler(async (event) => {
|
|
@@ -12,14 +13,9 @@ export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
|
|
|
12
13
|
});
|
|
13
14
|
const { code } = getQuery(event);
|
|
14
15
|
if (!config.clientId || !config.clientSecret) {
|
|
15
|
-
|
|
16
|
-
statusCode: 500,
|
|
17
|
-
message: "Missing NUXT_OAUTH_DISCORD_CLIENT_ID or NUXT_OAUTH_DISCORD_CLIENT_SECRET env variables."
|
|
18
|
-
});
|
|
19
|
-
if (!onError) throw error;
|
|
20
|
-
return onError(event, error);
|
|
16
|
+
return handleMissingConfiguration(event, "discord", ["clientId", "clientSecret"], onError);
|
|
21
17
|
}
|
|
22
|
-
const
|
|
18
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
23
19
|
if (!code) {
|
|
24
20
|
config.scope = config.scope || [];
|
|
25
21
|
if (config.emailRequired && !config.scope.includes("email")) {
|
|
@@ -33,13 +29,13 @@ export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
|
|
|
33
29
|
withQuery(config.authorizationURL, {
|
|
34
30
|
response_type: "code",
|
|
35
31
|
client_id: config.clientId,
|
|
36
|
-
redirect_uri:
|
|
32
|
+
redirect_uri: redirectURL,
|
|
37
33
|
scope: config.scope.join(" "),
|
|
38
34
|
...config.authorizationParams
|
|
39
35
|
})
|
|
40
36
|
);
|
|
41
37
|
}
|
|
42
|
-
const parsedRedirectUrl = parseURL(
|
|
38
|
+
const parsedRedirectUrl = parseURL(redirectURL);
|
|
43
39
|
parsedRedirectUrl.search = "";
|
|
44
40
|
const tokens = await $fetch(
|
|
45
41
|
config.tokenURL,
|
|
@@ -60,13 +56,7 @@ export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
|
|
|
60
56
|
return { error };
|
|
61
57
|
});
|
|
62
58
|
if (tokens.error) {
|
|
63
|
-
|
|
64
|
-
statusCode: 401,
|
|
65
|
-
message: `Discord login failed: ${tokens.error?.data?.error_description || "Unknown error"}`,
|
|
66
|
-
data: tokens
|
|
67
|
-
});
|
|
68
|
-
if (!onError) throw error;
|
|
69
|
-
return onError(event, error);
|
|
59
|
+
return handleAccessTokenErrorResponse(event, "discord", tokens, onError);
|
|
70
60
|
}
|
|
71
61
|
const accessToken = tokens.access_token;
|
|
72
62
|
const user = await $fetch("https://discord.com/api/users/@me", {
|
|
@@ -39,5 +39,10 @@ export interface OAuthFacebookConfig {
|
|
|
39
39
|
* @see https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/
|
|
40
40
|
*/
|
|
41
41
|
authorizationParams?: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
44
|
+
* @default process.env.NUXT_OAUTH_FACEBOOK_REDIRECT_URL or current URL
|
|
45
|
+
*/
|
|
46
|
+
redirectURL?: string;
|
|
42
47
|
}
|
|
43
48
|
export declare function oauthFacebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from "h3";
|
|
8
8
|
import { withQuery } from "ufo";
|
|
9
9
|
import { defu } from "defu";
|
|
10
|
+
import { handleAccessTokenErrorResponse, handleMissingConfiguration } from "../utils.js";
|
|
10
11
|
import { useRuntimeConfig } from "#imports";
|
|
11
12
|
export function oauthFacebookEventHandler({
|
|
12
13
|
config,
|
|
@@ -30,21 +31,16 @@ export function oauthFacebookEventHandler({
|
|
|
30
31
|
return onError(event, error);
|
|
31
32
|
}
|
|
32
33
|
if (!config.clientId) {
|
|
33
|
-
|
|
34
|
-
statusCode: 500,
|
|
35
|
-
message: "Missing NUXT_OAUTH_FACEBOOK_CLIENT_ID or NUXT_OAUTH_FACEBOOK_CLIENT_SECRET env variables."
|
|
36
|
-
});
|
|
37
|
-
if (!onError) throw error;
|
|
38
|
-
return onError(event, error);
|
|
34
|
+
return handleMissingConfiguration(event, "facebook", ["clientId"], onError);
|
|
39
35
|
}
|
|
40
|
-
const
|
|
36
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
41
37
|
if (!query.code) {
|
|
42
38
|
config.scope = config.scope || [];
|
|
43
39
|
return sendRedirect(
|
|
44
40
|
event,
|
|
45
41
|
withQuery(config.authorizationURL, {
|
|
46
42
|
client_id: config.clientId,
|
|
47
|
-
redirect_uri:
|
|
43
|
+
redirect_uri: redirectURL,
|
|
48
44
|
scope: config.scope.join(" ")
|
|
49
45
|
})
|
|
50
46
|
);
|
|
@@ -54,18 +50,12 @@ export function oauthFacebookEventHandler({
|
|
|
54
50
|
body: {
|
|
55
51
|
client_id: config.clientId,
|
|
56
52
|
client_secret: config.clientSecret,
|
|
57
|
-
redirect_uri:
|
|
53
|
+
redirect_uri: redirectURL,
|
|
58
54
|
code: query.code
|
|
59
55
|
}
|
|
60
56
|
});
|
|
61
57
|
if (tokens.error) {
|
|
62
|
-
|
|
63
|
-
statusCode: 401,
|
|
64
|
-
message: `Facebook login failed: ${tokens.error || "Unknown error"}`,
|
|
65
|
-
data: tokens
|
|
66
|
-
});
|
|
67
|
-
if (!onError) throw error;
|
|
68
|
-
return onError(event, error);
|
|
58
|
+
return handleAccessTokenErrorResponse(event, "facebook", tokens, onError);
|
|
69
59
|
}
|
|
70
60
|
const accessToken = tokens.access_token;
|
|
71
61
|
config.fields = config.fields || ["id", "name"];
|
|
@@ -38,5 +38,11 @@ export interface OAuthGitHubConfig {
|
|
|
38
38
|
* @example { allow_signup: 'true' }
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
43
|
+
* @default process.env.NUXT_OAUTH_GITHUB_REDIRECT_URL
|
|
44
|
+
* @see https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps
|
|
45
|
+
*/
|
|
46
|
+
redirectURL?: string;
|
|
41
47
|
}
|
|
42
48
|
export declare function oauthGitHubEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthGitHubConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
+
import { handleAccessTokenErrorResponse, handleMissingConfiguration } from "../utils.js";
|
|
4
5
|
import { useRuntimeConfig } from "#imports";
|
|
5
6
|
export function oauthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
6
7
|
return eventHandler(async (event) => {
|
|
@@ -20,24 +21,19 @@ export function oauthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
|
20
21
|
return onError(event, error);
|
|
21
22
|
}
|
|
22
23
|
if (!config.clientId || !config.clientSecret) {
|
|
23
|
-
|
|
24
|
-
statusCode: 500,
|
|
25
|
-
message: "Missing NUXT_OAUTH_GITHUB_CLIENT_ID or NUXT_OAUTH_GITHUB_CLIENT_SECRET env variables."
|
|
26
|
-
});
|
|
27
|
-
if (!onError) throw error;
|
|
28
|
-
return onError(event, error);
|
|
24
|
+
return handleMissingConfiguration(event, "github", ["clientId", "clientSecret"], onError);
|
|
29
25
|
}
|
|
30
26
|
if (!query.code) {
|
|
31
27
|
config.scope = config.scope || [];
|
|
32
28
|
if (config.emailRequired && !config.scope.includes("user:email")) {
|
|
33
29
|
config.scope.push("user:email");
|
|
34
30
|
}
|
|
35
|
-
const
|
|
31
|
+
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
36
32
|
return sendRedirect(
|
|
37
33
|
event,
|
|
38
34
|
withQuery(config.authorizationURL, {
|
|
39
35
|
client_id: config.clientId,
|
|
40
|
-
redirect_uri:
|
|
36
|
+
redirect_uri: redirectURL,
|
|
41
37
|
scope: config.scope.join(" "),
|
|
42
38
|
...config.authorizationParams
|
|
43
39
|
})
|
|
@@ -55,13 +51,7 @@ export function oauthGitHubEventHandler({ config, onSuccess, onError }) {
|
|
|
55
51
|
}
|
|
56
52
|
);
|
|
57
53
|
if (tokens.error) {
|
|
58
|
-
|
|
59
|
-
statusCode: 401,
|
|
60
|
-
message: `GitHub login failed: ${tokens.error || "Unknown error"}`,
|
|
61
|
-
data: tokens
|
|
62
|
-
});
|
|
63
|
-
if (!onError) throw error;
|
|
64
|
-
return onError(event, error);
|
|
54
|
+
return handleAccessTokenErrorResponse(event, "github", tokens, onError);
|
|
65
55
|
}
|
|
66
56
|
const accessToken = tokens.access_token;
|
|
67
57
|
const user = await $fetch("https://api.github.com/user", {
|
|
@@ -38,5 +38,10 @@ export interface OAuthGoogleConfig {
|
|
|
38
38
|
* @example { access_type: 'offline' }
|
|
39
39
|
*/
|
|
40
40
|
authorizationParams?: Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
|
|
43
|
+
* @default process.env.NUXT_OAUTH_GOOGLE_REDIRECT_URL or current URL
|
|
44
|
+
*/
|
|
45
|
+
redirectURL?: string;
|
|
41
46
|
}
|
|
42
47
|
export declare function oauthGoogleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
|