@wpnuxt/auth 2.0.0-alpha.4 → 2.0.0-alpha.6
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/dist/module.json +4 -1
- package/dist/module.mjs +13 -17
- package/dist/runtime/composables/useWPAuth.js +46 -27
- package/dist/runtime/server/api/auth/oauth/authorize.get.js +10 -4
- package/dist/runtime/server/api/auth/oauth/callback.get.js +1 -1
- package/dist/runtime/server/api/auth/provider/[provider]/authorize.get.js +1 -1
- package/package.json +4 -4
- package/dist/runtime/server/api/auth/login.post.d.ts +0 -0
- package/dist/runtime/server/api/auth/login.post.js +0 -51
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -38,7 +38,7 @@ function validateAuthSchema(schemaPath, options = {}) {
|
|
|
38
38
|
const capabilities = detectAuthCapabilities(schemaPath);
|
|
39
39
|
if (capabilities === null) {
|
|
40
40
|
throw new Error(
|
|
41
|
-
`[
|
|
41
|
+
`[wpnuxt:auth] Cannot validate GraphQL schema - file not found or unreadable.
|
|
42
42
|
|
|
43
43
|
Schema path: ${schemaPath}
|
|
44
44
|
|
|
@@ -50,7 +50,7 @@ To fix this, run: pnpm dev:prepare`
|
|
|
50
50
|
}
|
|
51
51
|
if (!capabilities.hasHeadlessLogin) {
|
|
52
52
|
throw new Error(
|
|
53
|
-
`[
|
|
53
|
+
`[wpnuxt:auth] Headless Login for WPGraphQL plugin not detected.
|
|
54
54
|
|
|
55
55
|
The @wpnuxt/auth module requires this WordPress plugin for authentication.
|
|
56
56
|
Your WordPress GraphQL schema is missing the required 'loginClients' query.
|
|
@@ -65,7 +65,7 @@ To disable @wpnuxt/auth, remove it from your nuxt.config.ts modules.`
|
|
|
65
65
|
}
|
|
66
66
|
if (options.requirePassword && !capabilities.hasPasswordAuth) {
|
|
67
67
|
throw new Error(
|
|
68
|
-
`[
|
|
68
|
+
`[wpnuxt:auth] Password authentication not available in GraphQL schema.
|
|
69
69
|
|
|
70
70
|
The 'login' mutation is missing from your WordPress GraphQL schema.
|
|
71
71
|
Make sure Headless Login for WPGraphQL is properly configured with PASSWORD provider enabled.`
|
|
@@ -73,7 +73,7 @@ Make sure Headless Login for WPGraphQL is properly configured with PASSWORD prov
|
|
|
73
73
|
}
|
|
74
74
|
if (options.requireHeadlessLogin && capabilities.detectedProviders.length === 0) {
|
|
75
75
|
throw new Error(
|
|
76
|
-
`[
|
|
76
|
+
`[wpnuxt:auth] No OAuth providers detected in GraphQL schema.
|
|
77
77
|
|
|
78
78
|
Headless Login is installed but no providers are configured.
|
|
79
79
|
Configure OAuth providers (Google, GitHub, etc.) in WordPress admin under:
|
|
@@ -97,7 +97,10 @@ const DEFAULT_HEADLESS_LOGIN_CONFIG = {
|
|
|
97
97
|
const module$1 = defineNuxtModule({
|
|
98
98
|
meta: {
|
|
99
99
|
name: "@wpnuxt/auth",
|
|
100
|
-
configKey: "wpNuxtAuth"
|
|
100
|
+
configKey: "wpNuxtAuth",
|
|
101
|
+
compatibility: {
|
|
102
|
+
nuxt: ">=3.0.0"
|
|
103
|
+
}
|
|
101
104
|
},
|
|
102
105
|
defaults: {
|
|
103
106
|
enabled: true,
|
|
@@ -183,38 +186,31 @@ const module$1 = defineNuxtModule({
|
|
|
183
186
|
{ name: "useWPAuth", from: resolver.resolve("./runtime/composables/useWPAuth") },
|
|
184
187
|
{ name: "useWPUser", from: resolver.resolve("./runtime/composables/useWPUser") }
|
|
185
188
|
]);
|
|
186
|
-
if (passwordEnabled) {
|
|
187
|
-
addServerHandler({
|
|
188
|
-
route: "/api/auth/login",
|
|
189
|
-
method: "post",
|
|
190
|
-
handler: resolver.resolve("./runtime/server/api/auth/login.post")
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
189
|
addServerHandler({
|
|
194
|
-
route: "/api/auth/logout",
|
|
190
|
+
route: "/api/_wpnuxt-auth/logout",
|
|
195
191
|
method: "post",
|
|
196
192
|
handler: resolver.resolve("./runtime/server/api/auth/logout.post")
|
|
197
193
|
});
|
|
198
194
|
if (oauthEnabled) {
|
|
199
195
|
addServerHandler({
|
|
200
|
-
route: "/api/auth/oauth/authorize",
|
|
196
|
+
route: "/api/_wpnuxt-auth/oauth/authorize",
|
|
201
197
|
method: "get",
|
|
202
198
|
handler: resolver.resolve("./runtime/server/api/auth/oauth/authorize.get")
|
|
203
199
|
});
|
|
204
200
|
addServerHandler({
|
|
205
|
-
route: "/api/auth/oauth/callback",
|
|
201
|
+
route: "/api/_wpnuxt-auth/oauth/callback",
|
|
206
202
|
method: "get",
|
|
207
203
|
handler: resolver.resolve("./runtime/server/api/auth/oauth/callback.get")
|
|
208
204
|
});
|
|
209
205
|
}
|
|
210
206
|
if (headlessLoginEnabled) {
|
|
211
207
|
addServerHandler({
|
|
212
|
-
route: "/api/auth/provider/:provider/authorize",
|
|
208
|
+
route: "/api/_wpnuxt-auth/provider/:provider/authorize",
|
|
213
209
|
method: "get",
|
|
214
210
|
handler: resolver.resolve("./runtime/server/api/auth/provider/[provider]/authorize.get")
|
|
215
211
|
});
|
|
216
212
|
addServerHandler({
|
|
217
|
-
route: "/api/auth/provider/:provider/callback",
|
|
213
|
+
route: "/api/_wpnuxt-auth/provider/:provider/callback",
|
|
218
214
|
method: "get",
|
|
219
215
|
handler: resolver.resolve("./runtime/server/api/auth/provider/[provider]/callback.get")
|
|
220
216
|
});
|
|
@@ -27,34 +27,30 @@ export function useWPAuth() {
|
|
|
27
27
|
authState.value.isLoading = true;
|
|
28
28
|
authState.value.error = null;
|
|
29
29
|
try {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
username: credentials.username,
|
|
34
|
-
password: credentials.password
|
|
35
|
-
}
|
|
30
|
+
const { data, errors } = await useGraphqlMutation("Login", {
|
|
31
|
+
username: credentials.username,
|
|
32
|
+
password: credentials.password
|
|
36
33
|
});
|
|
37
|
-
const data = response.data;
|
|
38
|
-
const errors = response.errors;
|
|
39
34
|
if (errors?.length) {
|
|
40
35
|
const errorMessage = errors[0]?.message || "Login failed";
|
|
41
36
|
authState.value.error = errorMessage;
|
|
42
37
|
authState.value.isLoading = false;
|
|
43
38
|
return { success: false, error: errorMessage };
|
|
44
39
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
const loginData = data;
|
|
41
|
+
if (loginData?.login) {
|
|
42
|
+
authToken.value = loginData.login.authToken;
|
|
43
|
+
refreshTokenCookie.value = loginData.login.refreshToken;
|
|
44
|
+
userDataCookie.value = JSON.stringify(loginData.login.user);
|
|
45
|
+
authState.value.user = loginData.login.user;
|
|
50
46
|
authState.value.isAuthenticated = true;
|
|
51
47
|
authState.value.isLoading = false;
|
|
52
48
|
return {
|
|
53
49
|
success: true,
|
|
54
|
-
user:
|
|
50
|
+
user: loginData.login.user,
|
|
55
51
|
tokens: {
|
|
56
|
-
authToken:
|
|
57
|
-
refreshToken:
|
|
52
|
+
authToken: loginData.login.authToken,
|
|
53
|
+
refreshToken: loginData.login.refreshToken
|
|
58
54
|
}
|
|
59
55
|
};
|
|
60
56
|
}
|
|
@@ -68,7 +64,7 @@ export function useWPAuth() {
|
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
66
|
async function logout() {
|
|
71
|
-
await $fetch("/api/auth/logout", { method: "POST" }).catch(() => {
|
|
67
|
+
await $fetch("/api/_wpnuxt-auth/logout", { method: "POST" }).catch(() => {
|
|
72
68
|
});
|
|
73
69
|
authToken.value = null;
|
|
74
70
|
refreshTokenCookie.value = null;
|
|
@@ -82,22 +78,45 @@ export function useWPAuth() {
|
|
|
82
78
|
}
|
|
83
79
|
async function refresh() {
|
|
84
80
|
if (!refreshTokenCookie.value) {
|
|
85
|
-
return false;
|
|
81
|
+
return { success: false, error: "No refresh token available" };
|
|
86
82
|
}
|
|
87
83
|
try {
|
|
88
84
|
const { data, errors } = await useGraphqlMutation("RefreshToken", {
|
|
89
85
|
refreshToken: refreshTokenCookie.value
|
|
90
86
|
});
|
|
87
|
+
if (errors?.length) {
|
|
88
|
+
const errorMessage = errors[0]?.message || "Token refresh failed";
|
|
89
|
+
authToken.value = null;
|
|
90
|
+
refreshTokenCookie.value = null;
|
|
91
|
+
userDataCookie.value = null;
|
|
92
|
+
authState.value.isAuthenticated = false;
|
|
93
|
+
authState.value.user = null;
|
|
94
|
+
authState.value.error = errorMessage;
|
|
95
|
+
return { success: false, error: errorMessage };
|
|
96
|
+
}
|
|
91
97
|
const refreshData = data;
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
if (!refreshData?.refreshToken?.success) {
|
|
99
|
+
const errorMessage = "Token refresh was not successful";
|
|
100
|
+
authToken.value = null;
|
|
101
|
+
refreshTokenCookie.value = null;
|
|
102
|
+
userDataCookie.value = null;
|
|
103
|
+
authState.value.isAuthenticated = false;
|
|
104
|
+
authState.value.user = null;
|
|
105
|
+
authState.value.error = errorMessage;
|
|
106
|
+
return { success: false, error: errorMessage };
|
|
95
107
|
}
|
|
96
108
|
authToken.value = refreshData.refreshToken.authToken;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
109
|
+
authState.value.error = null;
|
|
110
|
+
return { success: true };
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const errorMessage = error instanceof Error ? error.message : "Token refresh failed unexpectedly";
|
|
113
|
+
authToken.value = null;
|
|
114
|
+
refreshTokenCookie.value = null;
|
|
115
|
+
userDataCookie.value = null;
|
|
116
|
+
authState.value.isAuthenticated = false;
|
|
117
|
+
authState.value.user = null;
|
|
118
|
+
authState.value.error = errorMessage;
|
|
119
|
+
return { success: false, error: errorMessage };
|
|
101
120
|
}
|
|
102
121
|
}
|
|
103
122
|
function getToken() {
|
|
@@ -117,7 +136,7 @@ export function useWPAuth() {
|
|
|
117
136
|
logger.warn("OAuth is not enabled");
|
|
118
137
|
return;
|
|
119
138
|
}
|
|
120
|
-
await navigateTo("/api/auth/oauth/authorize", { external: true });
|
|
139
|
+
await navigateTo("/api/_wpnuxt-auth/oauth/authorize", { external: true });
|
|
121
140
|
}
|
|
122
141
|
function hasPasswordAuth() {
|
|
123
142
|
return getProviders().password;
|
|
@@ -179,7 +198,7 @@ export function useWPAuth() {
|
|
|
179
198
|
logger.warn("Headless Login is not enabled");
|
|
180
199
|
return;
|
|
181
200
|
}
|
|
182
|
-
await navigateTo(`/api/auth/provider/${provider.toLowerCase()}/authorize`, { external: true });
|
|
201
|
+
await navigateTo(`/api/_wpnuxt-auth/provider/${provider.toLowerCase()}/authorize`, { external: true });
|
|
183
202
|
}
|
|
184
203
|
return {
|
|
185
204
|
// State
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { defineEventHandler, setCookie, getRequestURL, setResponseStatus, setResponseHeader } from "h3";
|
|
1
|
+
import { defineEventHandler, setCookie, getRequestURL, setResponseStatus, setResponseHeader, createError } from "h3";
|
|
2
2
|
import { useRuntimeConfig } from "#imports";
|
|
3
3
|
export default defineEventHandler(async (event) => {
|
|
4
4
|
const config = useRuntimeConfig();
|
|
5
5
|
const publicConfig = config.public.wpNuxtAuth;
|
|
6
6
|
const wordpressUrl = config.public.wordpressUrl;
|
|
7
7
|
if (!wordpressUrl) {
|
|
8
|
-
throw
|
|
8
|
+
throw createError({
|
|
9
|
+
statusCode: 500,
|
|
10
|
+
message: "[wpnuxt:auth] WordPress URL not configured"
|
|
11
|
+
});
|
|
9
12
|
}
|
|
10
13
|
if (!publicConfig.providers.oauth.enabled) {
|
|
11
|
-
throw
|
|
14
|
+
throw createError({
|
|
15
|
+
statusCode: 403,
|
|
16
|
+
message: "[wpnuxt:auth] OAuth authentication is not enabled"
|
|
17
|
+
});
|
|
12
18
|
}
|
|
13
19
|
const state = crypto.randomUUID();
|
|
14
20
|
setCookie(event, "wpnuxt-oauth-state", state, {
|
|
@@ -20,7 +26,7 @@ export default defineEventHandler(async (event) => {
|
|
|
20
26
|
path: "/"
|
|
21
27
|
});
|
|
22
28
|
const requestUrl = getRequestURL(event);
|
|
23
|
-
const callbackUrl = `${requestUrl.origin}/api/auth/oauth/callback`;
|
|
29
|
+
const callbackUrl = `${requestUrl.origin}/api/_wpnuxt-auth/oauth/callback`;
|
|
24
30
|
const authUrl = new URL(
|
|
25
31
|
publicConfig.providers.oauth.authorizationEndpoint,
|
|
26
32
|
wordpressUrl
|
|
@@ -28,7 +28,7 @@ export default defineEventHandler(async (event) => {
|
|
|
28
28
|
}
|
|
29
29
|
deleteCookie(event, "wpnuxt-oauth-state");
|
|
30
30
|
const requestUrl = getRequestURL(event);
|
|
31
|
-
const callbackUrl = `${requestUrl.origin}/api/auth/oauth/callback`;
|
|
31
|
+
const callbackUrl = `${requestUrl.origin}/api/_wpnuxt-auth/oauth/callback`;
|
|
32
32
|
const tokenUrl = new URL(privateConfig.tokenEndpoint, wordpressUrl);
|
|
33
33
|
const tokenResponse = await $fetch(tokenUrl.toString(), {
|
|
34
34
|
method: "POST",
|
|
@@ -76,7 +76,7 @@ export default defineEventHandler(async (event) => {
|
|
|
76
76
|
const authUrl = new URL(loginClient.authorizationUrl);
|
|
77
77
|
authUrl.searchParams.set("state", state);
|
|
78
78
|
const requestUrl = getRequestURL(event);
|
|
79
|
-
const callbackUrl = `${requestUrl.origin}/api/auth/provider/${provider}/callback`;
|
|
79
|
+
const callbackUrl = `${requestUrl.origin}/api/_wpnuxt-auth/provider/${provider}/callback`;
|
|
80
80
|
authUrl.searchParams.set("redirect_uri", callbackUrl);
|
|
81
81
|
return sendRedirect(event, authUrl.toString());
|
|
82
82
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wpnuxt/auth",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.6",
|
|
4
4
|
"description": "Authentication module for WPNuxt using WPGraphQL JWT",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nuxt",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@nuxt/module-builder": "^1.0.2",
|
|
41
41
|
"@nuxt/schema": "4.2.2",
|
|
42
|
-
"@types/node": "^25.0.
|
|
42
|
+
"@types/node": "^25.0.9",
|
|
43
43
|
"nuxt": "4.2.2",
|
|
44
|
-
"vue-tsc": "^3.2.
|
|
44
|
+
"vue-tsc": "^3.2.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"nuxt": "^4.0.0",
|
|
48
|
-
"@wpnuxt/core": "2.0.0-alpha.
|
|
48
|
+
"@wpnuxt/core": "2.0.0-alpha.6"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "nuxt-module-build build",
|
|
File without changes
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { defineEventHandler, readBody, createError } from "h3";
|
|
2
|
-
import { useRuntimeConfig } from "#imports";
|
|
3
|
-
const LOGIN_MUTATION = `
|
|
4
|
-
mutation Login($username: String!, $password: String!) {
|
|
5
|
-
login(input: {
|
|
6
|
-
provider: PASSWORD
|
|
7
|
-
credentials: {
|
|
8
|
-
username: $username
|
|
9
|
-
password: $password
|
|
10
|
-
}
|
|
11
|
-
}) {
|
|
12
|
-
authToken
|
|
13
|
-
authTokenExpiration
|
|
14
|
-
refreshToken
|
|
15
|
-
refreshTokenExpiration
|
|
16
|
-
user {
|
|
17
|
-
id
|
|
18
|
-
databaseId
|
|
19
|
-
name
|
|
20
|
-
email
|
|
21
|
-
firstName
|
|
22
|
-
lastName
|
|
23
|
-
username
|
|
24
|
-
avatar { url }
|
|
25
|
-
roles { nodes { name } }
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
`;
|
|
30
|
-
export default defineEventHandler(async (event) => {
|
|
31
|
-
const config = useRuntimeConfig();
|
|
32
|
-
const body = await readBody(event);
|
|
33
|
-
if (!body?.username || !body?.password) {
|
|
34
|
-
throw createError({
|
|
35
|
-
statusCode: 400,
|
|
36
|
-
message: "Username and password are required"
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
const response = await $fetch(config.graphqlMiddleware.graphqlEndpoint, {
|
|
40
|
-
method: "POST",
|
|
41
|
-
body: {
|
|
42
|
-
query: LOGIN_MUTATION,
|
|
43
|
-
variables: {
|
|
44
|
-
username: body.username,
|
|
45
|
-
password: body.password
|
|
46
|
-
},
|
|
47
|
-
operationName: "Login"
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
return response;
|
|
51
|
-
});
|