@meistrari/auth-nuxt 3.7.0 → 3.8.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/README.md +22 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +9 -5
- package/dist/runtime/composables/api-key.js +8 -4
- package/dist/runtime/server/routes/auth/api-key-proxy.d.ts +2 -0
- package/dist/runtime/server/routes/auth/api-key-proxy.js +93 -0
- package/dist/runtime/shared.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,9 +12,30 @@ This SDK supports two authentication models:
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
bun add @meistrari/auth-nuxt
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
export default defineNuxtConfig({
|
|
22
|
+
modules: ['@meistrari/auth-nuxt'],
|
|
23
|
+
telaAuth: {
|
|
24
|
+
apiUrl: 'https://auth.tela.com',
|
|
25
|
+
application: {
|
|
26
|
+
enabled: true,
|
|
27
|
+
dashboardUrl: 'https://accounts.tela.com',
|
|
28
|
+
applicationId: 'app_123',
|
|
29
|
+
redirectUri: 'https://your-app.com/auth/callback',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Application auth auto-imports `useTelaApplicationAuth()`, registers `<TelaRole>`, installs role directives, and adds SDK routes under `/auth/*` plus `/api/auth/api-key/**`. `useTelaApiKey()` is also available; in application mode it targets the local API key proxy for app-scoped user API keys.
|
|
36
|
+
|
|
37
|
+
First-party auth auto-imports `useTelaSession()`, `useTelaOrganization()`, and `useTelaApiKey()`.
|
|
38
|
+
|
|
18
39
|
## API Reference
|
|
19
40
|
|
|
20
41
|
See it on [Pantry](https://pantry.tela.tools/ingredients/auth-nuxt/api)
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -12,6 +12,11 @@ const module$1 = defineNuxtModule({
|
|
|
12
12
|
setup(options, nuxt) {
|
|
13
13
|
const resolver = createResolver(import.meta.url);
|
|
14
14
|
nuxt.options.runtimeConfig.public.telaAuth = options;
|
|
15
|
+
addImports({
|
|
16
|
+
name: "useTelaApiKey",
|
|
17
|
+
as: "useTelaApiKey",
|
|
18
|
+
from: resolver.resolve("runtime/composables/api-key")
|
|
19
|
+
});
|
|
15
20
|
if (options.application?.enabled) {
|
|
16
21
|
addImports({
|
|
17
22
|
name: "useTelaApplicationAuth",
|
|
@@ -71,6 +76,10 @@ const module$1 = defineNuxtModule({
|
|
|
71
76
|
handler: resolver.resolve("./runtime/server/routes/auth/whoami"),
|
|
72
77
|
method: "get"
|
|
73
78
|
});
|
|
79
|
+
addServerHandler({
|
|
80
|
+
route: "/api/auth/api-key/**",
|
|
81
|
+
handler: resolver.resolve("./runtime/server/routes/auth/api-key-proxy")
|
|
82
|
+
});
|
|
74
83
|
addPlugin(resolver.resolve("./runtime/plugins/application-token-refresh"));
|
|
75
84
|
addPlugin(resolver.resolve("./runtime/plugins/auth-guard"));
|
|
76
85
|
addPlugin(resolver.resolve("./runtime/plugins/directives"));
|
|
@@ -92,11 +101,6 @@ const module$1 = defineNuxtModule({
|
|
|
92
101
|
as: "useTelaOrganization",
|
|
93
102
|
from: resolver.resolve("runtime/composables/organization")
|
|
94
103
|
});
|
|
95
|
-
addImports({
|
|
96
|
-
name: "useTelaApiKey",
|
|
97
|
-
as: "useTelaApiKey",
|
|
98
|
-
from: resolver.resolve("runtime/composables/api-key")
|
|
99
|
-
});
|
|
100
104
|
addPlugin(resolver.resolve("./runtime/plugins/handshake"));
|
|
101
105
|
}
|
|
102
106
|
});
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { useCookie, useRuntimeConfig } from "#app";
|
|
1
|
+
import { useCookie, useRequestURL, useRuntimeConfig } from "#app";
|
|
2
2
|
import { createNuxtAuthClient } from "../shared.js";
|
|
3
3
|
export function useTelaApiKey() {
|
|
4
|
-
const { jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
|
|
5
|
-
const tokenCookie = useCookie(jwtCookieName);
|
|
6
|
-
const
|
|
4
|
+
const { application, jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
|
|
5
|
+
const tokenCookie = useCookie(application?.enabled ? "tela-access-token" : jwtCookieName);
|
|
6
|
+
const requestUrl = useRequestURL();
|
|
7
|
+
const authClient = createNuxtAuthClient(
|
|
8
|
+
application?.enabled ? requestUrl.origin : apiUrl,
|
|
9
|
+
() => tokenCookie.value ?? null
|
|
10
|
+
);
|
|
7
11
|
async function createApiKey(payload) {
|
|
8
12
|
return await authClient.apiKey.createApiKey(payload);
|
|
9
13
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createError, useRuntimeConfig } from "#imports";
|
|
2
|
+
import {
|
|
3
|
+
defineEventHandler,
|
|
4
|
+
getCookie,
|
|
5
|
+
getHeaders,
|
|
6
|
+
getRequestURL,
|
|
7
|
+
readRawBody,
|
|
8
|
+
setResponseHeader,
|
|
9
|
+
setResponseStatus
|
|
10
|
+
} from "h3";
|
|
11
|
+
const ALLOWED_REQUEST_HEADERS = /* @__PURE__ */ new Set([
|
|
12
|
+
"accept",
|
|
13
|
+
"content-type"
|
|
14
|
+
]);
|
|
15
|
+
const ALLOWED_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
|
|
16
|
+
"cache-control",
|
|
17
|
+
"content-type"
|
|
18
|
+
]);
|
|
19
|
+
const ALLOWED_API_KEY_ROUTES = /* @__PURE__ */ new Map([
|
|
20
|
+
["/api/auth/api-key/create", /* @__PURE__ */ new Set(["POST"])],
|
|
21
|
+
["/api/auth/api-key/delete", /* @__PURE__ */ new Set(["POST"])],
|
|
22
|
+
["/api/auth/api-key/get", /* @__PURE__ */ new Set(["GET"])],
|
|
23
|
+
["/api/auth/api-key/list", /* @__PURE__ */ new Set(["GET"])],
|
|
24
|
+
["/api/auth/api-key/update", /* @__PURE__ */ new Set(["POST"])]
|
|
25
|
+
]);
|
|
26
|
+
function getBearerToken(authorization) {
|
|
27
|
+
const value = Array.isArray(authorization) ? authorization[0] : authorization;
|
|
28
|
+
if (!value?.toLowerCase().startsWith("bearer ")) {
|
|
29
|
+
return void 0;
|
|
30
|
+
}
|
|
31
|
+
return value.slice("bearer ".length).trimStart() || void 0;
|
|
32
|
+
}
|
|
33
|
+
export default defineEventHandler(async (event) => {
|
|
34
|
+
const authConfig = useRuntimeConfig(event).public.telaAuth;
|
|
35
|
+
const requestUrl = getRequestURL(event);
|
|
36
|
+
const requestHeaders = getHeaders(event);
|
|
37
|
+
const accessToken = getCookie(event, "tela-access-token") ?? getBearerToken(requestHeaders.authorization);
|
|
38
|
+
const allowedMethods = ALLOWED_API_KEY_ROUTES.get(requestUrl.pathname);
|
|
39
|
+
if (!authConfig.application?.enabled) {
|
|
40
|
+
throw createError({
|
|
41
|
+
statusCode: 404,
|
|
42
|
+
statusMessage: "Not Found"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (!accessToken) {
|
|
46
|
+
throw createError({
|
|
47
|
+
statusCode: 401,
|
|
48
|
+
statusMessage: "Unauthorized",
|
|
49
|
+
message: "No access token found"
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!allowedMethods) {
|
|
53
|
+
throw createError({
|
|
54
|
+
statusCode: 404,
|
|
55
|
+
statusMessage: "Not Found"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (!allowedMethods.has(event.method)) {
|
|
59
|
+
throw createError({
|
|
60
|
+
statusCode: 405,
|
|
61
|
+
statusMessage: "Method Not Allowed"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const origin = Array.isArray(requestHeaders.origin) ? requestHeaders.origin[0] : requestHeaders.origin;
|
|
65
|
+
if (event.method !== "GET" && origin && origin !== requestUrl.origin) {
|
|
66
|
+
throw createError({
|
|
67
|
+
statusCode: 403,
|
|
68
|
+
statusMessage: "Forbidden"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const targetUrl = new URL(requestUrl.pathname + requestUrl.search, authConfig.apiUrl);
|
|
72
|
+
const headers = new Headers();
|
|
73
|
+
for (const [name, value] of Object.entries(requestHeaders)) {
|
|
74
|
+
if (value && ALLOWED_REQUEST_HEADERS.has(name.toLowerCase())) {
|
|
75
|
+
headers.set(name, Array.isArray(value) ? value.join(", ") : value);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
79
|
+
const method = event.method;
|
|
80
|
+
const body = method === "GET" || method === "HEAD" ? void 0 : await readRawBody(event);
|
|
81
|
+
const response = await fetch(targetUrl, {
|
|
82
|
+
body,
|
|
83
|
+
headers,
|
|
84
|
+
method
|
|
85
|
+
});
|
|
86
|
+
setResponseStatus(event, response.status, response.statusText);
|
|
87
|
+
for (const [name, value] of response.headers) {
|
|
88
|
+
if (ALLOWED_RESPONSE_HEADERS.has(name.toLowerCase())) {
|
|
89
|
+
setResponseHeader(event, name, value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return await response.text();
|
|
93
|
+
});
|
package/dist/runtime/shared.js
CHANGED
|
@@ -8,7 +8,7 @@ export function createNuxtAuthClient(apiUrl, getAuthToken, getRefreshToken = ()
|
|
|
8
8
|
"X-User-Agent": userAgent
|
|
9
9
|
},
|
|
10
10
|
onRequest: (context) => {
|
|
11
|
-
const requestUrl = new URL(context.url);
|
|
11
|
+
const requestUrl = new URL(context.url, "http://localhost");
|
|
12
12
|
const token = getAuthToken();
|
|
13
13
|
const isTokenRequest = requestUrl.pathname.endsWith("/api/auth/token");
|
|
14
14
|
if (token && !isTokenRequest) {
|