@enfyra/sdk-nuxt 0.6.2 → 0.7.0
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.cjs +15 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +15 -0
- package/dist/runtime/composables/useEnfyraAuth.d.ts.map +1 -1
- package/dist/runtime/composables/useEnfyraAuth.js +10 -1
- package/dist/runtime/server/api/all.d.ts.map +1 -1
- package/dist/runtime/server/api/all.js +11 -1
- package/dist/runtime/server/api/auth/[provider]/callback.get.d.ts +3 -0
- package/dist/runtime/server/api/auth/[provider]/callback.get.d.ts.map +1 -0
- package/dist/runtime/server/api/auth/[provider]/callback.get.js +16 -0
- package/dist/runtime/server/api/auth/[provider].get.d.ts +3 -0
- package/dist/runtime/server/api/auth/[provider].get.d.ts.map +1 -0
- package/dist/runtime/server/api/auth/[provider].get.js +31 -0
- package/dist/runtime/server/api/auth/callback.get.d.ts +3 -0
- package/dist/runtime/server/api/auth/callback.get.d.ts.map +1 -0
- package/dist/runtime/server/api/auth/callback.get.js +29 -0
- package/dist/runtime/server/middleware/auth.d.ts.map +1 -1
- package/dist/runtime/server/middleware/auth.js +2 -1
- package/dist/types/auth.d.ts +2 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/module.ts +19 -0
- package/src/runtime/composables/useEnfyraAuth.ts +12 -1
- package/src/runtime/server/api/all.ts +14 -1
- package/src/runtime/server/api/auth/[provider]/callback.get.ts +21 -0
- package/src/runtime/server/api/auth/[provider].get.ts +38 -0
- package/src/runtime/server/api/auth/callback.get.ts +39 -0
- package/src/runtime/server/middleware/auth.ts +6 -2
- package/src/types/auth.ts +3 -0
package/dist/module.cjs
CHANGED
|
@@ -98,6 +98,21 @@ declare module '#imports' {
|
|
|
98
98
|
handler: resolve("./runtime/server/api/logout.post"),
|
|
99
99
|
method: "post"
|
|
100
100
|
});
|
|
101
|
+
kit.addServerHandler({
|
|
102
|
+
route: `${apiPrefix}/auth/:provider`,
|
|
103
|
+
handler: resolve("./runtime/server/api/auth/[provider].get"),
|
|
104
|
+
method: "get"
|
|
105
|
+
});
|
|
106
|
+
kit.addServerHandler({
|
|
107
|
+
route: `${apiPrefix}/auth/:provider/callback`,
|
|
108
|
+
handler: resolve("./runtime/server/api/auth/[provider]/callback.get"),
|
|
109
|
+
method: "get"
|
|
110
|
+
});
|
|
111
|
+
kit.addServerHandler({
|
|
112
|
+
route: `${apiPrefix}/auth/callback`,
|
|
113
|
+
handler: resolve("./runtime/server/api/auth/callback.get"),
|
|
114
|
+
method: "get"
|
|
115
|
+
});
|
|
101
116
|
kit.addServerHandler({
|
|
102
117
|
route: "/assets/**",
|
|
103
118
|
handler: resolve("./runtime/server/api/all")
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;AAED,
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;AAED,wBAgJG"}
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -95,6 +95,21 @@ declare module '#imports' {
|
|
|
95
95
|
handler: resolve("./runtime/server/api/logout.post"),
|
|
96
96
|
method: "post"
|
|
97
97
|
});
|
|
98
|
+
addServerHandler({
|
|
99
|
+
route: `${apiPrefix}/auth/:provider`,
|
|
100
|
+
handler: resolve("./runtime/server/api/auth/[provider].get"),
|
|
101
|
+
method: "get"
|
|
102
|
+
});
|
|
103
|
+
addServerHandler({
|
|
104
|
+
route: `${apiPrefix}/auth/:provider/callback`,
|
|
105
|
+
handler: resolve("./runtime/server/api/auth/[provider]/callback.get"),
|
|
106
|
+
method: "get"
|
|
107
|
+
});
|
|
108
|
+
addServerHandler({
|
|
109
|
+
route: `${apiPrefix}/auth/callback`,
|
|
110
|
+
handler: resolve("./runtime/server/api/auth/callback.get"),
|
|
111
|
+
method: "get"
|
|
112
|
+
});
|
|
98
113
|
addServerHandler({
|
|
99
114
|
route: "/assets/**",
|
|
100
115
|
handler: resolve("./runtime/server/api/all")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEnfyraAuth.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useEnfyraAuth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useEnfyraAuth.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useEnfyraAuth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,mBAAmB,EAAiB,MAAM,kBAAkB,CAAC;AAO/F,wBAAgB,aAAa,IAAI,mBAAmB,CA4FnD"}
|
|
@@ -64,11 +64,20 @@ export function useEnfyraAuth() {
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
const isLoggedIn = computed(() => !!me.value);
|
|
67
|
+
const oauthLogin = (provider) => {
|
|
68
|
+
if (typeof window === "undefined") {
|
|
69
|
+
console.error("[Enfyra Auth] oauthLogin can only be called on the client side");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const currentUrl = window.location.href;
|
|
73
|
+
window.location.href = `/api/auth/${provider}?redirect=${encodeURIComponent(currentUrl)}`;
|
|
74
|
+
};
|
|
67
75
|
return {
|
|
68
76
|
me,
|
|
69
77
|
login,
|
|
70
78
|
logout,
|
|
71
79
|
fetchUser,
|
|
72
|
-
isLoggedIn
|
|
80
|
+
isLoggedIn,
|
|
81
|
+
oauthLogin
|
|
73
82
|
};
|
|
74
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../../../src/runtime/server/api/all.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../../../src/runtime/server/api/all.ts"],"names":[],"mappings":";AAUA,wBAQG"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import { defineEventHandler } from "h3";
|
|
1
|
+
import { defineEventHandler, setResponseHeaders } from "h3";
|
|
2
2
|
import { proxyToAPI } from "../../utils/server/proxy.js";
|
|
3
|
+
const CORS_HEADERS = {
|
|
4
|
+
"Access-Control-Allow-Origin": "*",
|
|
5
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS",
|
|
6
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
7
|
+
"Access-Control-Max-Age": "86400"
|
|
8
|
+
};
|
|
3
9
|
export default defineEventHandler(async (event) => {
|
|
10
|
+
setResponseHeaders(event, CORS_HEADERS);
|
|
11
|
+
if (event.method === "OPTIONS") {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
4
14
|
return proxyToAPI(event);
|
|
5
15
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.get.d.ts","sourceRoot":"","sources":["../../../../../../src/runtime/server/api/auth/[provider]/callback.get.ts"],"names":[],"mappings":";AAQA,wBAYG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
sendRedirect
|
|
5
|
+
} from "h3";
|
|
6
|
+
import { useRuntimeConfig } from "#imports";
|
|
7
|
+
import { normalizeUrl } from "../../../../utils/url.js";
|
|
8
|
+
export default defineEventHandler(async (event) => {
|
|
9
|
+
const config = useRuntimeConfig();
|
|
10
|
+
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
11
|
+
const provider = event.context.params?.provider;
|
|
12
|
+
const query = getQuery(event);
|
|
13
|
+
const queryString = new URLSearchParams(query).toString();
|
|
14
|
+
const backendUrl = normalizeUrl(apiUrl, `/auth/${provider}/callback?${queryString}`);
|
|
15
|
+
return sendRedirect(event, backendUrl, 302);
|
|
16
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"[provider].get.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/server/api/auth/[provider].get.ts"],"names":[],"mappings":";AAYA,wBAyBG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
createError,
|
|
5
|
+
sendError,
|
|
6
|
+
sendRedirect
|
|
7
|
+
} from "h3";
|
|
8
|
+
import { useRuntimeConfig } from "#imports";
|
|
9
|
+
import { normalizeUrl } from "../../../utils/url.js";
|
|
10
|
+
const VALID_PROVIDERS = ["google", "facebook", "github"];
|
|
11
|
+
export default defineEventHandler(async (event) => {
|
|
12
|
+
const config = useRuntimeConfig();
|
|
13
|
+
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
14
|
+
const provider = event.context.params?.provider;
|
|
15
|
+
if (!provider || !VALID_PROVIDERS.includes(provider)) {
|
|
16
|
+
return sendError(
|
|
17
|
+
event,
|
|
18
|
+
createError({
|
|
19
|
+
statusCode: 400,
|
|
20
|
+
statusMessage: `Invalid OAuth provider: ${provider}`
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const query = getQuery(event);
|
|
25
|
+
const redirectUrl = query.redirect;
|
|
26
|
+
let oauthUrl = normalizeUrl(apiUrl, `/auth/${provider}`);
|
|
27
|
+
if (redirectUrl) {
|
|
28
|
+
oauthUrl += `?redirect=${encodeURIComponent(redirectUrl)}`;
|
|
29
|
+
}
|
|
30
|
+
return sendRedirect(event, oauthUrl, 302);
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.get.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/server/api/auth/callback.get.ts"],"names":[],"mappings":";AAaA,wBAyBG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
setCookie,
|
|
5
|
+
sendRedirect
|
|
6
|
+
} from "h3";
|
|
7
|
+
import {
|
|
8
|
+
ACCESS_TOKEN_KEY,
|
|
9
|
+
REFRESH_TOKEN_KEY,
|
|
10
|
+
EXP_TIME_KEY
|
|
11
|
+
} from "../../../constants/auth.js";
|
|
12
|
+
export default defineEventHandler(async (event) => {
|
|
13
|
+
const query = getQuery(event);
|
|
14
|
+
const { accessToken, refreshToken, expTime, redirect } = query;
|
|
15
|
+
if (!accessToken || !refreshToken || !expTime) {
|
|
16
|
+
return sendRedirect(event, "/login?error=oauth_callback_failed");
|
|
17
|
+
}
|
|
18
|
+
const cookieOptions = {
|
|
19
|
+
httpOnly: true,
|
|
20
|
+
secure: true,
|
|
21
|
+
sameSite: "lax",
|
|
22
|
+
path: "/"
|
|
23
|
+
};
|
|
24
|
+
setCookie(event, ACCESS_TOKEN_KEY, accessToken, cookieOptions);
|
|
25
|
+
setCookie(event, REFRESH_TOKEN_KEY, refreshToken, cookieOptions);
|
|
26
|
+
setCookie(event, EXP_TIME_KEY, expTime, cookieOptions);
|
|
27
|
+
const redirectUrl = redirect || "/";
|
|
28
|
+
return sendRedirect(event, redirectUrl);
|
|
29
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/runtime/server/middleware/auth.ts"],"names":[],"mappings":";AAQA,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/runtime/server/middleware/auth.ts"],"names":[],"mappings":";AAQA,wBAuCG"}
|
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
} from "../../utils/server/refreshToken.js";
|
|
7
7
|
import { REFRESH_TOKEN_KEY } from "../../constants/auth.js";
|
|
8
8
|
export default defineEventHandler(async (event) => {
|
|
9
|
-
|
|
9
|
+
const url = event.node.req.url || "";
|
|
10
|
+
if (url === "/api/login" || url === "/api/logout" || url.startsWith("/api/auth/")) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
const { accessToken, needsRefresh } = validateTokens(event);
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Ref } from 'vue';
|
|
2
|
+
export type OAuthProvider = 'google' | 'facebook' | 'github';
|
|
2
3
|
export interface User {
|
|
3
4
|
id: string;
|
|
4
5
|
email: string;
|
|
@@ -39,5 +40,6 @@ export interface UseEnfyraAuthReturn {
|
|
|
39
40
|
fields?: string[];
|
|
40
41
|
}) => Promise<void>;
|
|
41
42
|
isLoggedIn: Ref<boolean>;
|
|
43
|
+
oauthLogin: (provider: OAuthProvider) => void;
|
|
42
44
|
}
|
|
43
45
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/types/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,gBAAgB,EAAE,eAAe,EAAE,CAAA;KACpC,CAAA;IACD,uBAAuB,CAAC,EAAE,eAAe,EAAE,CAAA;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC/B,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACpB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7D,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAA;AAE5D,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,gBAAgB,EAAE,eAAe,EAAE,CAAA;KACpC,CAAA;IACD,uBAAuB,CAAC,EAAE,eAAe,EAAE,CAAA;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC/B,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACpB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7D,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACxB,UAAU,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAA;CAC9C"}
|
package/package.json
CHANGED
package/src/module.ts
CHANGED
|
@@ -130,6 +130,25 @@ declare module '#imports' {
|
|
|
130
130
|
method: "post",
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
+
// OAuth routes
|
|
134
|
+
addServerHandler({
|
|
135
|
+
route: `${apiPrefix}/auth/:provider`,
|
|
136
|
+
handler: resolve("./runtime/server/api/auth/[provider].get"),
|
|
137
|
+
method: "get",
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
addServerHandler({
|
|
141
|
+
route: `${apiPrefix}/auth/:provider/callback`,
|
|
142
|
+
handler: resolve("./runtime/server/api/auth/[provider]/callback.get"),
|
|
143
|
+
method: "get",
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
addServerHandler({
|
|
147
|
+
route: `${apiPrefix}/auth/callback`,
|
|
148
|
+
handler: resolve("./runtime/server/api/auth/callback.get"),
|
|
149
|
+
method: "get",
|
|
150
|
+
});
|
|
151
|
+
|
|
133
152
|
addServerHandler({
|
|
134
153
|
route: "/assets/**",
|
|
135
154
|
handler: resolve("./runtime/server/api/all"),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, computed } from "vue";
|
|
2
|
-
import type { LoginPayload, User, UseEnfyraAuthReturn } from "../../types/auth";
|
|
2
|
+
import type { LoginPayload, User, UseEnfyraAuthReturn, OAuthProvider } from "../../types/auth";
|
|
3
3
|
import { $fetch } from "ofetch";
|
|
4
4
|
import { useEnfyra } from "./useEnfyra";
|
|
5
5
|
|
|
@@ -80,11 +80,22 @@ export function useEnfyraAuth(): UseEnfyraAuthReturn {
|
|
|
80
80
|
|
|
81
81
|
const isLoggedIn = computed(() => !!me.value);
|
|
82
82
|
|
|
83
|
+
const oauthLogin = (provider: OAuthProvider) => {
|
|
84
|
+
if (typeof window === "undefined") {
|
|
85
|
+
console.error("[Enfyra Auth] oauthLogin can only be called on the client side");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const currentUrl = window.location.href;
|
|
90
|
+
window.location.href = `/api/auth/${provider}?redirect=${encodeURIComponent(currentUrl)}`;
|
|
91
|
+
};
|
|
92
|
+
|
|
83
93
|
return {
|
|
84
94
|
me,
|
|
85
95
|
login,
|
|
86
96
|
logout,
|
|
87
97
|
fetchUser,
|
|
88
98
|
isLoggedIn,
|
|
99
|
+
oauthLogin,
|
|
89
100
|
} as const;
|
|
90
101
|
}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import { defineEventHandler } from "h3";
|
|
1
|
+
import { defineEventHandler, setResponseHeaders } from "h3";
|
|
2
2
|
import { proxyToAPI } from "../../utils/server/proxy";
|
|
3
3
|
|
|
4
|
+
const CORS_HEADERS = {
|
|
5
|
+
'Access-Control-Allow-Origin': '*',
|
|
6
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
|
|
7
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
8
|
+
'Access-Control-Max-Age': '86400',
|
|
9
|
+
};
|
|
10
|
+
|
|
4
11
|
export default defineEventHandler(async (event) => {
|
|
12
|
+
setResponseHeaders(event, CORS_HEADERS);
|
|
13
|
+
|
|
14
|
+
if (event.method === 'OPTIONS') {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
|
|
5
18
|
return proxyToAPI(event);
|
|
6
19
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
sendRedirect,
|
|
5
|
+
} from "h3";
|
|
6
|
+
import { useRuntimeConfig } from "#imports";
|
|
7
|
+
import { normalizeUrl } from "../../../../utils/url";
|
|
8
|
+
|
|
9
|
+
export default defineEventHandler(async (event) => {
|
|
10
|
+
const config = useRuntimeConfig();
|
|
11
|
+
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
12
|
+
const provider = event.context.params?.provider;
|
|
13
|
+
|
|
14
|
+
const query = getQuery(event);
|
|
15
|
+
const queryString = new URLSearchParams(query as Record<string, string>).toString();
|
|
16
|
+
|
|
17
|
+
// Redirect to backend OAuth callback
|
|
18
|
+
const backendUrl = normalizeUrl(apiUrl, `/auth/${provider}/callback?${queryString}`);
|
|
19
|
+
|
|
20
|
+
return sendRedirect(event, backendUrl, 302);
|
|
21
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
createError,
|
|
5
|
+
sendError,
|
|
6
|
+
sendRedirect,
|
|
7
|
+
} from "h3";
|
|
8
|
+
import { useRuntimeConfig } from "#imports";
|
|
9
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
10
|
+
|
|
11
|
+
const VALID_PROVIDERS = ["google", "facebook", "github"];
|
|
12
|
+
|
|
13
|
+
export default defineEventHandler(async (event) => {
|
|
14
|
+
const config = useRuntimeConfig();
|
|
15
|
+
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
16
|
+
const provider = event.context.params?.provider;
|
|
17
|
+
|
|
18
|
+
if (!provider || !VALID_PROVIDERS.includes(provider)) {
|
|
19
|
+
return sendError(
|
|
20
|
+
event,
|
|
21
|
+
createError({
|
|
22
|
+
statusCode: 400,
|
|
23
|
+
statusMessage: `Invalid OAuth provider: ${provider}`,
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const query = getQuery(event);
|
|
29
|
+
const redirectUrl = query.redirect as string | undefined;
|
|
30
|
+
|
|
31
|
+
// Build backend OAuth URL
|
|
32
|
+
let oauthUrl = normalizeUrl(apiUrl, `/auth/${provider}`);
|
|
33
|
+
if (redirectUrl) {
|
|
34
|
+
oauthUrl += `?redirect=${encodeURIComponent(redirectUrl)}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return sendRedirect(event, oauthUrl, 302);
|
|
38
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
setCookie,
|
|
5
|
+
sendRedirect,
|
|
6
|
+
} from "h3";
|
|
7
|
+
import { useRuntimeConfig } from "#imports";
|
|
8
|
+
import {
|
|
9
|
+
ACCESS_TOKEN_KEY,
|
|
10
|
+
REFRESH_TOKEN_KEY,
|
|
11
|
+
EXP_TIME_KEY,
|
|
12
|
+
} from "../../../constants/auth";
|
|
13
|
+
|
|
14
|
+
export default defineEventHandler(async (event) => {
|
|
15
|
+
const query = getQuery(event);
|
|
16
|
+
|
|
17
|
+
const { accessToken, refreshToken, expTime, redirect } = query;
|
|
18
|
+
|
|
19
|
+
// Validate required tokens
|
|
20
|
+
if (!accessToken || !refreshToken || !expTime) {
|
|
21
|
+
return sendRedirect(event, "/login?error=oauth_callback_failed");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Set cookies (same as login.post.ts)
|
|
25
|
+
const cookieOptions = {
|
|
26
|
+
httpOnly: true,
|
|
27
|
+
secure: true,
|
|
28
|
+
sameSite: "lax" as const,
|
|
29
|
+
path: "/",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
setCookie(event, ACCESS_TOKEN_KEY, accessToken as string, cookieOptions);
|
|
33
|
+
setCookie(event, REFRESH_TOKEN_KEY, refreshToken as string, cookieOptions);
|
|
34
|
+
setCookie(event, EXP_TIME_KEY, expTime as string, cookieOptions);
|
|
35
|
+
|
|
36
|
+
// Redirect to original page or home
|
|
37
|
+
const redirectUrl = (redirect as string) || "/";
|
|
38
|
+
return sendRedirect(event, redirectUrl);
|
|
39
|
+
});
|
|
@@ -7,9 +7,13 @@ import {
|
|
|
7
7
|
import { REFRESH_TOKEN_KEY } from "../../constants/auth";
|
|
8
8
|
|
|
9
9
|
export default defineEventHandler(async (event) => {
|
|
10
|
+
const url = event.node.req.url || "";
|
|
11
|
+
|
|
12
|
+
// Skip token validation for auth endpoints
|
|
10
13
|
if (
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
url === "/api/login" ||
|
|
15
|
+
url === "/api/logout" ||
|
|
16
|
+
url.startsWith("/api/auth/")
|
|
13
17
|
) {
|
|
14
18
|
return;
|
|
15
19
|
}
|
package/src/types/auth.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Ref } from 'vue'
|
|
2
2
|
|
|
3
|
+
export type OAuthProvider = 'google' | 'facebook' | 'github'
|
|
4
|
+
|
|
3
5
|
export interface User {
|
|
4
6
|
id: string
|
|
5
7
|
email: string
|
|
@@ -33,4 +35,5 @@ export interface UseEnfyraAuthReturn {
|
|
|
33
35
|
logout: () => Promise<void>
|
|
34
36
|
fetchUser: (options?: { fields?: string[] }) => Promise<void>
|
|
35
37
|
isLoggedIn: Ref<boolean>
|
|
38
|
+
oauthLogin: (provider: OAuthProvider) => void
|
|
36
39
|
}
|