nuxt-auth-utils 0.5.28 → 0.5.30
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 +4 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -0
- package/dist/runtime/app/plugins/session.client.js +1 -1
- package/dist/runtime/server/lib/oauth/apple.js +12 -3
- package/dist/runtime/server/lib/oauth/atlassian.js +7 -4
- package/dist/runtime/server/lib/oauth/auth0.js +7 -2
- package/dist/runtime/server/lib/oauth/authentik.js +7 -2
- package/dist/runtime/server/lib/oauth/azureb2c.js +2 -2
- package/dist/runtime/server/lib/oauth/battledotnet.js +7 -5
- package/dist/runtime/server/lib/oauth/box.d.ts +95 -0
- package/dist/runtime/server/lib/oauth/box.js +69 -0
- package/dist/runtime/server/lib/oauth/cognito.js +7 -2
- package/dist/runtime/server/lib/oauth/discord.js +7 -2
- package/dist/runtime/server/lib/oauth/dropbox.js +7 -2
- package/dist/runtime/server/lib/oauth/facebook.js +7 -3
- package/dist/runtime/server/lib/oauth/gitea.js +8 -1
- package/dist/runtime/server/lib/oauth/github.js +2 -2
- package/dist/runtime/server/lib/oauth/gitlab.js +8 -1
- package/dist/runtime/server/lib/oauth/google.js +7 -3
- package/dist/runtime/server/lib/oauth/heroku.js +2 -2
- package/dist/runtime/server/lib/oauth/hubspot.js +8 -1
- package/dist/runtime/server/lib/oauth/instagram.js +7 -2
- package/dist/runtime/server/lib/oauth/keycloak.js +9 -2
- package/dist/runtime/server/lib/oauth/kick.js +6 -3
- package/dist/runtime/server/lib/oauth/line.js +7 -3
- package/dist/runtime/server/lib/oauth/linear.js +7 -2
- package/dist/runtime/server/lib/oauth/linkedin.js +7 -2
- package/dist/runtime/server/lib/oauth/livechat.js +9 -5
- package/dist/runtime/server/lib/oauth/microsoft.js +7 -3
- package/dist/runtime/server/lib/oauth/oidc.js +2 -2
- package/dist/runtime/server/lib/oauth/okta.js +3 -4
- package/dist/runtime/server/lib/oauth/ory.js +2 -2
- package/dist/runtime/server/lib/oauth/osu.js +2 -2
- package/dist/runtime/server/lib/oauth/paypal.js +7 -2
- package/dist/runtime/server/lib/oauth/polar.js +7 -2
- package/dist/runtime/server/lib/oauth/riotgames.d.ts +74 -0
- package/dist/runtime/server/lib/oauth/riotgames.js +83 -0
- package/dist/runtime/server/lib/oauth/roblox.js +7 -2
- package/dist/runtime/server/lib/oauth/salesforce.js +2 -2
- package/dist/runtime/server/lib/oauth/seznam.js +6 -2
- package/dist/runtime/server/lib/oauth/shopifyCustomer.js +4 -1
- package/dist/runtime/server/lib/oauth/slack.js +2 -2
- package/dist/runtime/server/lib/oauth/spotify.js +7 -2
- package/dist/runtime/server/lib/oauth/steam.js +6 -2
- package/dist/runtime/server/lib/oauth/strava.js +8 -1
- package/dist/runtime/server/lib/oauth/tiktok.js +7 -2
- package/dist/runtime/server/lib/oauth/twitch.js +7 -2
- package/dist/runtime/server/lib/oauth/vk.js +7 -1
- package/dist/runtime/server/lib/oauth/workos.js +7 -2
- package/dist/runtime/server/lib/oauth/xsuaa.js +7 -2
- package/dist/runtime/server/lib/oauth/yandex.js +8 -1
- package/dist/runtime/server/lib/oauth/zitadel.js +2 -2
- package/dist/runtime/server/lib/utils.d.ts +5 -1
- package/dist/runtime/server/lib/utils.js +11 -9
- package/dist/runtime/types/oauth-config.d.ts +1 -1
- package/dist/runtime/types/webauthn.d.ts +1 -1
- package/package.json +14 -14
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, handleInvalidState, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthRobloxEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -18,6 +18,7 @@ export function defineOAuthRobloxEventHandler({ config, onSuccess, onError }) {
|
|
|
18
18
|
return handleAccessTokenErrorResponse(event, "roblox", query, onError);
|
|
19
19
|
}
|
|
20
20
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
21
|
+
const state = await handleState(event);
|
|
21
22
|
if (!query.code) {
|
|
22
23
|
config.scope = config.scope || [];
|
|
23
24
|
return sendRedirect(
|
|
@@ -27,10 +28,14 @@ export function defineOAuthRobloxEventHandler({ config, onSuccess, onError }) {
|
|
|
27
28
|
client_id: config.clientId,
|
|
28
29
|
redirect_uri: redirectURL,
|
|
29
30
|
scope: config.scope.join(" "),
|
|
30
|
-
...config.authorizationParams
|
|
31
|
+
...config.authorizationParams,
|
|
32
|
+
state
|
|
31
33
|
})
|
|
32
34
|
);
|
|
33
35
|
}
|
|
36
|
+
if (query.state !== state) {
|
|
37
|
+
return handleInvalidState(event, "roblox", onError);
|
|
38
|
+
}
|
|
34
39
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
35
40
|
body: {
|
|
36
41
|
client_id: config.clientId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import defu from "defu";
|
|
2
2
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
3
3
|
import { withQuery } from "ufo";
|
|
4
|
-
import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleMissingConfiguration, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleInvalidState, handleMissingConfiguration, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthSeznamEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -15,6 +15,7 @@ export function defineOAuthSeznamEventHandler({ config, onSuccess, onError }) {
|
|
|
15
15
|
return handleMissingConfiguration(event, "seznam", ["clientId", "clientSecret"], onError);
|
|
16
16
|
}
|
|
17
17
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
18
|
+
const state = await handleState(event);
|
|
18
19
|
if (!query.code) {
|
|
19
20
|
config.scope = config.scope || ["identity"];
|
|
20
21
|
return sendRedirect(
|
|
@@ -24,10 +25,13 @@ export function defineOAuthSeznamEventHandler({ config, onSuccess, onError }) {
|
|
|
24
25
|
client_id: config.clientId,
|
|
25
26
|
redirect_uri: redirectURL,
|
|
26
27
|
scope: config.scope.join(","),
|
|
27
|
-
state
|
|
28
|
+
state
|
|
28
29
|
})
|
|
29
30
|
);
|
|
30
31
|
}
|
|
32
|
+
if (query.state !== state) {
|
|
33
|
+
return handleInvalidState(event, "seznam", onError);
|
|
34
|
+
}
|
|
31
35
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
32
36
|
body: {
|
|
33
37
|
grant_type: "authorization_code",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createError, eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleMissingConfiguration, handlePkceVerifier, handleState, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleInvalidState, handleMissingConfiguration, handlePkceVerifier, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthShopifyCustomerEventHandler({
|
|
7
7
|
config,
|
|
@@ -42,6 +42,9 @@ export function defineOAuthShopifyCustomerEventHandler({
|
|
|
42
42
|
})
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
|
+
if (query.state !== state) {
|
|
46
|
+
return handleInvalidState(event, "shopifyCustomer", onError);
|
|
47
|
+
}
|
|
45
48
|
const tokens = await requestAccessToken(discoveryResponse.token_endpoint, {
|
|
46
49
|
body: {
|
|
47
50
|
grant_type: "authorization_code",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, handleInvalidState, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthSpotifyEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -15,6 +15,7 @@ export function defineOAuthSpotifyEventHandler({ config, onSuccess, onError }) {
|
|
|
15
15
|
return handleMissingConfiguration(event, "spotify", ["clientId", "clientSecret"], onError);
|
|
16
16
|
}
|
|
17
17
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
18
|
+
const state = await handleState(event);
|
|
18
19
|
if (!query.code) {
|
|
19
20
|
config.scope = config.scope || [];
|
|
20
21
|
if (config.emailRequired && !config.scope.includes("user-read-email")) {
|
|
@@ -27,10 +28,14 @@ export function defineOAuthSpotifyEventHandler({ config, onSuccess, onError }) {
|
|
|
27
28
|
client_id: config.clientId,
|
|
28
29
|
redirect_uri: redirectURL,
|
|
29
30
|
scope: config.scope.join(" "),
|
|
30
|
-
...config.authorizationParams
|
|
31
|
+
...config.authorizationParams,
|
|
32
|
+
state
|
|
31
33
|
})
|
|
32
34
|
);
|
|
33
35
|
}
|
|
36
|
+
if (query.state !== state) {
|
|
37
|
+
return handleInvalidState(event, "spotify", onError);
|
|
38
|
+
}
|
|
34
39
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
35
40
|
headers: {
|
|
36
41
|
Authorization: `Basic ${Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64")}`
|
|
@@ -1,7 +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 { handleMissingConfiguration } from "../utils.js";
|
|
4
|
+
import { handleInvalidState, handleMissingConfiguration, handleState } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthSteamEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -13,8 +13,9 @@ export function defineOAuthSteamEventHandler({ config, onSuccess, onError }) {
|
|
|
13
13
|
return handleMissingConfiguration(event, "steam", ["apiKey"], onError);
|
|
14
14
|
}
|
|
15
15
|
const url = getRequestURL(event);
|
|
16
|
+
const state = await handleState(event, { isCallback: Boolean(query["openid.claimed_id"]) });
|
|
16
17
|
if (!query["openid.claimed_id"]) {
|
|
17
|
-
const redirectURL = config.redirectURL || getRequestURL(event).href;
|
|
18
|
+
const redirectURL = withQuery(config.redirectURL || getRequestURL(event).href, { state });
|
|
18
19
|
const realm = url.port ? `${url.protocol}//${url.hostname}:${url.port}` : `${url.protocol}//${url.hostname}`;
|
|
19
20
|
const steamOpenIdParams = {
|
|
20
21
|
"openid.ns": "http://specs.openid.net/auth/2.0",
|
|
@@ -26,6 +27,9 @@ export function defineOAuthSteamEventHandler({ config, onSuccess, onError }) {
|
|
|
26
27
|
};
|
|
27
28
|
return sendRedirect(event, withQuery(config.authorizationURL, steamOpenIdParams));
|
|
28
29
|
}
|
|
30
|
+
if (query.state !== state) {
|
|
31
|
+
return handleInvalidState(event, "steam", onError);
|
|
32
|
+
}
|
|
29
33
|
if (!query["openid.signed"] || !query["openid.sig"]) {
|
|
30
34
|
const error = createError({
|
|
31
35
|
statusCode: 400,
|
|
@@ -4,7 +4,9 @@ import { defu } from "defu";
|
|
|
4
4
|
import {
|
|
5
5
|
getOAuthRedirectURL,
|
|
6
6
|
handleAccessTokenErrorResponse,
|
|
7
|
+
handleInvalidState,
|
|
7
8
|
handleMissingConfiguration,
|
|
9
|
+
handleState,
|
|
8
10
|
requestAccessToken
|
|
9
11
|
} from "../utils.js";
|
|
10
12
|
import { useRuntimeConfig, createError } from "#imports";
|
|
@@ -36,6 +38,7 @@ export function defineOAuthStravaEventHandler({
|
|
|
36
38
|
const authorizationURL = "https://www.strava.com/oauth/authorize";
|
|
37
39
|
const tokenURL = "https://www.strava.com/oauth/token";
|
|
38
40
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
41
|
+
const state = await handleState(event);
|
|
39
42
|
if (!query.code) {
|
|
40
43
|
return sendRedirect(
|
|
41
44
|
event,
|
|
@@ -44,10 +47,14 @@ export function defineOAuthStravaEventHandler({
|
|
|
44
47
|
redirect_uri: redirectURL,
|
|
45
48
|
response_type: "code",
|
|
46
49
|
approval_prompt: config.approvalPrompt || "auto",
|
|
47
|
-
scope: config.scope
|
|
50
|
+
scope: config.scope,
|
|
51
|
+
state
|
|
48
52
|
})
|
|
49
53
|
);
|
|
50
54
|
}
|
|
55
|
+
if (query.state !== state) {
|
|
56
|
+
return handleInvalidState(event, "strava", onError);
|
|
57
|
+
}
|
|
51
58
|
const tokens = await requestAccessToken(tokenURL, {
|
|
52
59
|
body: {
|
|
53
60
|
client_id: config.clientId,
|
|
@@ -2,7 +2,7 @@ import crypto from "node:crypto";
|
|
|
2
2
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
3
3
|
import { withQuery } from "ufo";
|
|
4
4
|
import { defu } from "defu";
|
|
5
|
-
import { handleAccessTokenErrorResponse, handleMissingConfiguration, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
5
|
+
import { handleAccessTokenErrorResponse, handleInvalidState, handleMissingConfiguration, getOAuthRedirectURL, handleState, requestAccessToken } from "../utils.js";
|
|
6
6
|
import { useRuntimeConfig, createError } from "#imports";
|
|
7
7
|
export function defineOAuthTikTokEventHandler({ config, onSuccess, onError }) {
|
|
8
8
|
return eventHandler(async (event) => {
|
|
@@ -17,6 +17,7 @@ export function defineOAuthTikTokEventHandler({ config, onSuccess, onError }) {
|
|
|
17
17
|
}
|
|
18
18
|
const codeVerifier = "verify";
|
|
19
19
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
20
|
+
const state = await handleState(event);
|
|
20
21
|
if (!query.code) {
|
|
21
22
|
config.scope = config.scope || [];
|
|
22
23
|
if (!config.scope.includes("user.info.basic")) {
|
|
@@ -33,10 +34,14 @@ export function defineOAuthTikTokEventHandler({ config, onSuccess, onError }) {
|
|
|
33
34
|
code_verifier: codeVerifier,
|
|
34
35
|
code_challenge: crypto.createHash("sha256").update(codeVerifier).digest("hex"),
|
|
35
36
|
code_challenge_method: "S256"
|
|
36
|
-
} : {}
|
|
37
|
+
} : {},
|
|
38
|
+
state
|
|
37
39
|
})
|
|
38
40
|
);
|
|
39
41
|
}
|
|
42
|
+
if (query.state !== state) {
|
|
43
|
+
return handleInvalidState(event, "tiktok", onError);
|
|
44
|
+
}
|
|
40
45
|
const tokens = await requestAccessToken(
|
|
41
46
|
config.tokenURL,
|
|
42
47
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, handleInvalidState, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig, createError } from "#imports";
|
|
6
6
|
export function defineOAuthTwitchEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -15,6 +15,7 @@ export function defineOAuthTwitchEventHandler({ config, onSuccess, onError }) {
|
|
|
15
15
|
return handleMissingConfiguration(event, "twitch", ["clientId", "clientSecret"], onError);
|
|
16
16
|
}
|
|
17
17
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
18
|
+
const state = await handleState(event);
|
|
18
19
|
if (!query.code) {
|
|
19
20
|
config.scope = config.scope || [];
|
|
20
21
|
if (config.emailRequired && !config.scope.includes("user:read:email")) {
|
|
@@ -27,10 +28,14 @@ export function defineOAuthTwitchEventHandler({ config, onSuccess, onError }) {
|
|
|
27
28
|
client_id: config.clientId,
|
|
28
29
|
redirect_uri: redirectURL,
|
|
29
30
|
scope: config.scope.join(" "),
|
|
30
|
-
...config.authorizationParams
|
|
31
|
+
...config.authorizationParams,
|
|
32
|
+
state
|
|
31
33
|
})
|
|
32
34
|
);
|
|
33
35
|
}
|
|
36
|
+
if (query.state !== state) {
|
|
37
|
+
return handleInvalidState(event, "twitch", onError);
|
|
38
|
+
}
|
|
34
39
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
35
40
|
body: {
|
|
36
41
|
grant_type: "authorization_code",
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
handleMissingConfiguration,
|
|
7
7
|
handleAccessTokenErrorResponse,
|
|
8
8
|
getOAuthRedirectURL,
|
|
9
|
+
handleInvalidState,
|
|
10
|
+
handleState,
|
|
9
11
|
requestAccessToken
|
|
10
12
|
} from "../utils.js";
|
|
11
13
|
import { useRuntimeConfig, createError } from "#imports";
|
|
@@ -31,6 +33,7 @@ export function defineOAuthVKEventHandler({
|
|
|
31
33
|
}
|
|
32
34
|
const codeVerifier = "verify";
|
|
33
35
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
36
|
+
const state = await handleState(event);
|
|
34
37
|
if (!query.code) {
|
|
35
38
|
config.scope = config.scope || [];
|
|
36
39
|
if (config.emailRequired && !config.scope.includes("email")) {
|
|
@@ -43,12 +46,15 @@ export function defineOAuthVKEventHandler({
|
|
|
43
46
|
client_id: config.clientId,
|
|
44
47
|
code_challenge: crypto.createHash("sha256").update(codeVerifier).digest("base64url"),
|
|
45
48
|
code_challenge_method: "s256",
|
|
46
|
-
state
|
|
49
|
+
state,
|
|
47
50
|
redirect_uri: redirectURL,
|
|
48
51
|
scope: config.scope.join(" ")
|
|
49
52
|
})
|
|
50
53
|
);
|
|
51
54
|
}
|
|
55
|
+
if (query.state !== state) {
|
|
56
|
+
return handleInvalidState(event, "vk", onError);
|
|
57
|
+
}
|
|
52
58
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
53
59
|
body: {
|
|
54
60
|
grant_type: "authorization_code",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect, getRequestIP, getRequestHeader } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, handleInvalidState, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthWorkOSEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -14,6 +14,7 @@ export function defineOAuthWorkOSEventHandler({ config, onSuccess, onError }) {
|
|
|
14
14
|
if (query.error) {
|
|
15
15
|
return handleAccessTokenErrorResponse(event, "workos", query, onError);
|
|
16
16
|
}
|
|
17
|
+
const state = await handleState(event);
|
|
17
18
|
if (!query.code) {
|
|
18
19
|
return sendRedirect(
|
|
19
20
|
event,
|
|
@@ -24,10 +25,14 @@ export function defineOAuthWorkOSEventHandler({ config, onSuccess, onError }) {
|
|
|
24
25
|
redirect_uri: redirectURL || void 0,
|
|
25
26
|
connection_id: config.connectionId || void 0,
|
|
26
27
|
screen_hint: config.screenHint || "sign-in",
|
|
27
|
-
organization_id: config.organizationId || void 0
|
|
28
|
+
organization_id: config.organizationId || void 0,
|
|
29
|
+
state
|
|
28
30
|
})
|
|
29
31
|
);
|
|
30
32
|
}
|
|
33
|
+
if (query.state !== state) {
|
|
34
|
+
return handleInvalidState(event, "workos", onError);
|
|
35
|
+
}
|
|
31
36
|
const authenticateResponse = await requestAccessToken("https://api.workos.com/user_management/authenticate", {
|
|
32
37
|
headers: {
|
|
33
38
|
"Content-Type": "application/json"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventHandler, getQuery, sendRedirect } from "h3";
|
|
2
2
|
import { withQuery } from "ufo";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken } from "../utils.js";
|
|
4
|
+
import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, handleInvalidState, handleState, requestAccessToken } from "../utils.js";
|
|
5
5
|
import { useRuntimeConfig } from "#imports";
|
|
6
6
|
export function defineOAuthXSUAAEventHandler({ config, onSuccess, onError }) {
|
|
7
7
|
return eventHandler(async (event) => {
|
|
@@ -13,6 +13,7 @@ export function defineOAuthXSUAAEventHandler({ config, onSuccess, onError }) {
|
|
|
13
13
|
const authorizationURL = `https://${config.domain}/oauth/authorize`;
|
|
14
14
|
const tokenURL = `https://${config.domain}/oauth/token`;
|
|
15
15
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
16
|
+
const state = await handleState(event);
|
|
16
17
|
if (!query.code) {
|
|
17
18
|
config.scope = config.scope || [];
|
|
18
19
|
return sendRedirect(
|
|
@@ -21,10 +22,14 @@ export function defineOAuthXSUAAEventHandler({ config, onSuccess, onError }) {
|
|
|
21
22
|
response_type: "code",
|
|
22
23
|
client_id: config.clientId,
|
|
23
24
|
redirect_uri: redirectURL,
|
|
24
|
-
scope: config.scope.join(" ")
|
|
25
|
+
scope: config.scope.join(" "),
|
|
26
|
+
state
|
|
25
27
|
})
|
|
26
28
|
);
|
|
27
29
|
}
|
|
30
|
+
if (query.state !== state) {
|
|
31
|
+
return handleInvalidState(event, "xsuaa", onError);
|
|
32
|
+
}
|
|
28
33
|
const tokens = await requestAccessToken(tokenURL, {
|
|
29
34
|
body: {
|
|
30
35
|
grant_type: "authorization_code",
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
handleMissingConfiguration,
|
|
6
6
|
handleAccessTokenErrorResponse,
|
|
7
7
|
getOAuthRedirectURL,
|
|
8
|
+
handleInvalidState,
|
|
9
|
+
handleState,
|
|
8
10
|
requestAccessToken
|
|
9
11
|
} from "../utils.js";
|
|
10
12
|
import { useRuntimeConfig } from "#imports";
|
|
@@ -29,6 +31,7 @@ export function defineOAuthYandexEventHandler({
|
|
|
29
31
|
);
|
|
30
32
|
}
|
|
31
33
|
const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
|
|
34
|
+
const state = await handleState(event);
|
|
32
35
|
if (!query.code) {
|
|
33
36
|
config.scope = config.scope || [];
|
|
34
37
|
if (config.emailRequired && !config.scope.includes("login:email")) {
|
|
@@ -40,10 +43,14 @@ export function defineOAuthYandexEventHandler({
|
|
|
40
43
|
response_type: "code",
|
|
41
44
|
client_id: config.clientId,
|
|
42
45
|
redirect_uri: redirectURL,
|
|
43
|
-
scope: config.scope.join(" ")
|
|
46
|
+
scope: config.scope.join(" "),
|
|
47
|
+
state
|
|
44
48
|
})
|
|
45
49
|
);
|
|
46
50
|
}
|
|
51
|
+
if (query.state !== state) {
|
|
52
|
+
return handleInvalidState(event, "yandex", onError);
|
|
53
|
+
}
|
|
47
54
|
const tokens = await requestAccessToken(config.tokenURL, {
|
|
48
55
|
body: {
|
|
49
56
|
grant_type: "authorization_code",
|
|
@@ -36,10 +36,10 @@ export function defineOAuthZitadelEventHandler({ config, onSuccess, onError }) {
|
|
|
36
36
|
client_id: config.clientId,
|
|
37
37
|
redirect_uri: redirectURL,
|
|
38
38
|
scope: config.scope.join(" "),
|
|
39
|
-
state,
|
|
40
39
|
code_challenge: verifier.code_challenge,
|
|
41
40
|
code_challenge_method: verifier.code_challenge_method,
|
|
42
|
-
...config.authorizationParams
|
|
41
|
+
...config.authorizationParams,
|
|
42
|
+
state
|
|
43
43
|
})
|
|
44
44
|
);
|
|
45
45
|
}
|
|
@@ -70,7 +70,11 @@ export declare function handlePkceVerifier(event: H3Event): Promise<{
|
|
|
70
70
|
code_challenge?: undefined;
|
|
71
71
|
code_challenge_method?: undefined;
|
|
72
72
|
}>;
|
|
73
|
-
|
|
73
|
+
interface HandleStateOptions {
|
|
74
|
+
isCallback?: boolean;
|
|
75
|
+
sameSite?: 'lax' | 'none' | 'strict';
|
|
76
|
+
}
|
|
77
|
+
export declare function handleState(event: H3Event, options?: HandleStateOptions): Promise<string | undefined>;
|
|
74
78
|
export declare function parseJwt(token: string): jose.JWTPayload;
|
|
75
79
|
export declare function handleNonce(event: H3Event): string | undefined;
|
|
76
80
|
export {};
|
|
@@ -101,21 +101,23 @@ export async function handlePkceVerifier(event) {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
const verifier = getCookie(event, "nuxt-auth-pkce");
|
|
104
|
-
deleteCookie(event, "nuxt-auth-pkce");
|
|
104
|
+
deleteCookie(event, "nuxt-auth-pkce", { path: "/" });
|
|
105
105
|
return { code_verifier: verifier };
|
|
106
106
|
}
|
|
107
|
-
export async function handleState(event) {
|
|
107
|
+
export async function handleState(event, options = {}) {
|
|
108
108
|
const query = getQuery(event);
|
|
109
|
-
|
|
109
|
+
const isCallback = options.isCallback ?? Boolean(query.code);
|
|
110
|
+
if (isCallback) {
|
|
110
111
|
const state2 = getCookie(event, "nuxt-auth-state");
|
|
111
|
-
deleteCookie(event, "nuxt-auth-state");
|
|
112
|
+
deleteCookie(event, "nuxt-auth-state", { path: "/" });
|
|
112
113
|
return state2;
|
|
113
114
|
}
|
|
114
|
-
const state = encodeBase64Url(getRandomBytes(
|
|
115
|
+
const state = encodeBase64Url(getRandomBytes());
|
|
116
|
+
const sameSite = options.sameSite || "lax";
|
|
115
117
|
setCookie(event, "nuxt-auth-state", state, {
|
|
116
118
|
httpOnly: true,
|
|
117
|
-
secure: !isDevelopment,
|
|
118
|
-
sameSite
|
|
119
|
+
secure: sameSite === "none" || !isDevelopment,
|
|
120
|
+
sameSite,
|
|
119
121
|
maxAge: OAUTH_COOKIE_MAX_AGE,
|
|
120
122
|
path: "/"
|
|
121
123
|
});
|
|
@@ -128,10 +130,10 @@ export function handleNonce(event) {
|
|
|
128
130
|
const query = getQuery(event);
|
|
129
131
|
if (query.code) {
|
|
130
132
|
const nonce2 = getCookie(event, "nuxt-auth-nonce");
|
|
131
|
-
deleteCookie(event, "nuxt-auth-nonce");
|
|
133
|
+
deleteCookie(event, "nuxt-auth-nonce", { path: "/" });
|
|
132
134
|
return nonce2;
|
|
133
135
|
}
|
|
134
|
-
const nonce = encodeBase64Url(getRandomBytes(
|
|
136
|
+
const nonce = encodeBase64Url(getRandomBytes());
|
|
135
137
|
setCookie(event, "nuxt-auth-nonce", nonce, {
|
|
136
138
|
httpOnly: true,
|
|
137
139
|
secure: !isDevelopment,
|
|
@@ -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' | 'roblox' | 'okta' | 'ory' | 'shopifyCustomer' | 'oidc' | 'osu' | (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' | 'shopifyCustomer' | 'oidc' | 'osu' | 'riotgames' | 'box' | (string & {});
|
|
4
4
|
export type OnError = (event: H3Event, error: H3Error) => Promise<void> | void;
|
|
5
5
|
export interface OAuthConfig<TConfig, TResult = {
|
|
6
6
|
user: any;
|
|
@@ -86,7 +86,7 @@ export interface WebAuthnComposable {
|
|
|
86
86
|
* @param user.displayName - The display name to register, used for convenience and personalization and should not be relied upon as a secure identifier for authentication processes
|
|
87
87
|
* @returns true if the registration was successful
|
|
88
88
|
*/
|
|
89
|
-
register: <T extends WebAuthnUser>(
|
|
89
|
+
register: <T extends WebAuthnUser>(user: T) => Promise<boolean>;
|
|
90
90
|
/**
|
|
91
91
|
* Authenticate a credential
|
|
92
92
|
* @param userName - The user name to authenticate, can be an email address, a username, or any other form of unique ID chosen by the user
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-auth-utils",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.30",
|
|
4
4
|
"description": "Add Authentication to Nuxt applications with secured & sealed cookies sessions.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"type": "module",
|
|
11
|
-
"packageManager": "pnpm@10.
|
|
11
|
+
"packageManager": "pnpm@10.29.3",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
14
|
"types": "./dist/types.d.mts",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@adonisjs/hash": "^9.1.1",
|
|
43
|
-
"@nuxt/kit": "^4.
|
|
43
|
+
"@nuxt/kit": "^4.3.1",
|
|
44
44
|
"defu": "^6.1.4",
|
|
45
45
|
"h3": "^1.15.4",
|
|
46
46
|
"hookable": "^6.0.1",
|
|
47
47
|
"jose": "^6.1.3",
|
|
48
48
|
"ofetch": "^1.5.1",
|
|
49
|
-
"openid-client": "^6.8.
|
|
49
|
+
"openid-client": "^6.8.2",
|
|
50
50
|
"pathe": "^2.0.3",
|
|
51
51
|
"scule": "^1.3.0",
|
|
52
52
|
"uncrypto": "^0.1.3"
|
|
@@ -72,20 +72,20 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
76
|
-
"@nuxt/devtools": "3.
|
|
77
|
-
"@nuxt/eslint-config": "^1.
|
|
75
|
+
"@iconify-json/simple-icons": "^1.2.71",
|
|
76
|
+
"@nuxt/devtools": "3.2.1",
|
|
77
|
+
"@nuxt/eslint-config": "^1.15.1",
|
|
78
78
|
"@nuxt/module-builder": "^1.0.2",
|
|
79
|
-
"@nuxt/schema": "^4.
|
|
80
|
-
"@nuxt/test-utils": "^
|
|
79
|
+
"@nuxt/schema": "^4.3.1",
|
|
80
|
+
"@nuxt/test-utils": "^4.0.0",
|
|
81
81
|
"@types/node": "latest",
|
|
82
|
-
"@nuxt/ui": "^4.
|
|
82
|
+
"@nuxt/ui": "^4.4.0",
|
|
83
83
|
"@simplewebauthn/types": "^12.0.0",
|
|
84
84
|
"changelogen": "^0.6.2",
|
|
85
|
-
"eslint": "^
|
|
86
|
-
"nuxt": "^4.
|
|
85
|
+
"eslint": "^10.0.0",
|
|
86
|
+
"nuxt": "^4.3.1",
|
|
87
87
|
"typescript": "5.9.3",
|
|
88
|
-
"vitest": "^4.0.
|
|
89
|
-
"vue-tsc": "^3.2.
|
|
88
|
+
"vitest": "^4.0.18",
|
|
89
|
+
"vue-tsc": "^3.2.4"
|
|
90
90
|
}
|
|
91
91
|
}
|