@gnomondigital/nebulas-kit-core 0.4.0 → 0.5.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 +48 -20
- package/dist/client-api.d.ts +11 -0
- package/dist/client-api.d.ts.map +1 -0
- package/dist/client-api.js +9 -0
- package/dist/express-api.d.ts +5 -0
- package/dist/express-api.d.ts.map +1 -0
- package/dist/express-api.js +4 -0
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/nextjs-api.d.ts +5 -0
- package/dist/nextjs-api.d.ts.map +1 -0
- package/dist/nextjs-api.js +4 -0
- package/dist/server/auth-handler.d.ts +1 -16
- package/dist/server/auth-handler.d.ts.map +1 -1
- package/dist/server/auth-handler.js +1 -35
- package/dist/server/auth-strategies.d.ts +2 -9
- package/dist/server/auth-strategies.d.ts.map +1 -1
- package/dist/server/auth-strategies.js +37 -60
- package/dist/server/auth0/auth-handler.d.ts +17 -0
- package/dist/server/auth0/auth-handler.d.ts.map +1 -0
- package/dist/server/auth0/auth-handler.js +35 -0
- package/dist/server/auth0/auth-strategies.d.ts +16 -0
- package/dist/server/auth0/auth-strategies.d.ts.map +1 -0
- package/dist/server/auth0/auth-strategies.js +83 -0
- package/dist/server/auth0/client-credentials.d.ts +5 -0
- package/dist/server/auth0/client-credentials.d.ts.map +1 -0
- package/dist/server/auth0/client-credentials.js +37 -0
- package/dist/server/auth0/env-service-token.d.ts +5 -0
- package/dist/server/auth0/env-service-token.d.ts.map +1 -0
- package/dist/server/auth0/env-service-token.js +9 -0
- package/dist/server/config-handler.d.ts.map +1 -1
- package/dist/server/config-handler.js +4 -2
- package/dist/server/entra/env-service-token.d.ts +5 -0
- package/dist/server/entra/env-service-token.d.ts.map +1 -0
- package/dist/server/entra/env-service-token.js +104 -0
- package/dist/server/entra/session-token.d.ts +5 -0
- package/dist/server/entra/session-token.d.ts.map +1 -0
- package/dist/server/entra/session-token.js +109 -0
- package/dist/server/env-rop-token.d.ts +9 -3
- package/dist/server/env-rop-token.d.ts.map +1 -1
- package/dist/server/env-rop-token.js +131 -4
- package/dist/server/env-service-token.d.ts +12 -0
- package/dist/server/env-service-token.d.ts.map +1 -0
- package/dist/server/env-service-token.js +50 -0
- package/dist/server/express.d.ts.map +1 -1
- package/dist/server/express.js +53 -24
- package/dist/server/nebulas-proxy-handler.d.ts.map +1 -1
- package/dist/server/nebulas-proxy-handler.js +5 -4
- package/dist/server/nextjs.d.ts +15 -19
- package/dist/server/nextjs.d.ts.map +1 -1
- package/dist/server/nextjs.js +107 -174
- package/dist/server/node-env.d.ts +6 -0
- package/dist/server/node-env.d.ts.map +1 -0
- package/dist/server/node-env.js +12 -0
- package/dist/server/proxy-handler.d.ts +3 -0
- package/dist/server/proxy-handler.d.ts.map +1 -1
- package/dist/server/proxy-handler.js +5 -3
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -8,19 +8,40 @@ Framework-agnostic A2A chat client, Nebulas client, and server handlers.
|
|
|
8
8
|
npm install @gnomondigital/nebulas-kit-core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
### Subpath exports
|
|
12
|
+
|
|
13
|
+
| Import path | Use |
|
|
14
|
+
|-------------|-----|
|
|
15
|
+
| `@gnomondigital/nebulas-kit-core` | Framework-agnostic API (clients, shared handlers/types). |
|
|
16
|
+
| `@gnomondigital/nebulas-kit-core/nextjs` | Next.js route handlers and helpers (`next/server` based). |
|
|
17
|
+
| `@gnomondigital/nebulas-kit-core/client` | Browser-only: `sendMessageStream`, Nebulas client, types. **Use from React/Vite** so `next/server` is never bundled. |
|
|
18
|
+
| `@gnomondigital/nebulas-kit-core/express` | Express router only; no Next.js. |
|
|
19
|
+
|
|
20
|
+
`@gnomondigital/nebulas-kit-react` imports from `/client` internally.
|
|
21
|
+
|
|
11
22
|
## Environment Variables
|
|
12
23
|
|
|
13
24
|
| Variable | Required | Description |
|
|
14
25
|
|----------|----------|-------------|
|
|
15
26
|
| `A2A_URL` | Yes | A2A agent base URL |
|
|
16
|
-
| `A2A_AUTH_STRATEGY` | Yes | `session` \| `client_credentials` \| `resource_owner_password`
|
|
17
|
-
| `A2A_API_KEY` |
|
|
27
|
+
| `A2A_AUTH_STRATEGY` | Yes | `session` \| `client_credentials` \| `resource_owner_password` |
|
|
28
|
+
| `A2A_API_KEY` | Optional fallback | x-api-key header |
|
|
18
29
|
| `AUTH0_DOMAIN` | For Auth0 strategies | Auth0 tenant domain |
|
|
19
30
|
| `AUTH0_CLIENT_ID` | For client_credentials, ROP | Auth0 client ID |
|
|
20
31
|
| `AUTH0_CLIENT_SECRET` | For client_credentials, ROP | Auth0 client secret |
|
|
21
32
|
| `AUTH0_A2A_AUDIENCE` | For Auth0 strategies | API audience |
|
|
22
33
|
| `AUTH0_ROP_USERNAME` | For env ROP (`createA2AProxyHandlerFromEnvROP`) | Service user username (server secret) |
|
|
23
34
|
| `AUTH0_ROP_PASSWORD` | For env ROP | Service user password (server secret) |
|
|
35
|
+
| `AUTH_PROVIDER` | For env service auth | `auth0` \| `entra` |
|
|
36
|
+
| `ENTRA_TENANT_ID` | For Entra service auth | Entra tenant ID |
|
|
37
|
+
| `ENTRA_CLIENT_ID` | For Entra service auth | Entra app/client ID |
|
|
38
|
+
| `ENTRA_CLIENT_SECRET` | Optional for Entra service auth | Secret (if not using certificate) |
|
|
39
|
+
| `ENTRA_CLIENT_CERTIFICATE` / `_PATH` | Optional for Entra service auth | PEM certificate (inline or file path) |
|
|
40
|
+
| `ENTRA_CLIENT_PRIVATE_KEY` / `_PATH` | Optional for Entra service auth | PEM private key (inline or file path) |
|
|
41
|
+
| `ENTRA_A2A_SCOPE` | For Entra service auth | Scope for app/service token request (often `api://<app-id>/.default`) |
|
|
42
|
+
| `ENTRA_OBO_SCOPE` | For Entra OBO/session auth | Delegated downstream API scope for OBO (for example `api://<app-id>/user_impersonation`) |
|
|
43
|
+
| `ENTRA_OBO_CLIENT_ID` | For Entra OBO/session auth | client requesting OBO(upstream API) |
|
|
44
|
+
| `ENTRA_OBO_CLIENT_SECRET` | For Entra OBO/session auth | |
|
|
24
45
|
| `NEBULAS_API_URL` | For Nebulas | Conversation API base URL |
|
|
25
46
|
| `NEBULAS_API_KEY` | For Nebulas proxy | x-api-key fallback when no session token |
|
|
26
47
|
| `NEBULAS_PROJECT_ID` | For Nebulas | Project ID |
|
|
@@ -29,8 +50,8 @@ npm install @gnomondigital/nebulas-kit-core
|
|
|
29
50
|
|
|
30
51
|
| Mode | When to use | Exports |
|
|
31
52
|
|------|-------------|---------|
|
|
32
|
-
| **Auth0 session** | User signs in with `@auth0/nextjs-auth0`; access token for `AUTH0_A2A_AUDIENCE` comes from the session. | `createA2AProxyHandler`, `
|
|
33
|
-
| **Env
|
|
53
|
+
| **Auth0 session** | User signs in with `@auth0/nextjs-auth0`; access token for `AUTH0_A2A_AUDIENCE` comes from the session. | `createA2AProxyHandler`, `createGetHeadersForSession` |
|
|
54
|
+
| **Env service auth** | No browser session; uses Auth0 ROP service user (`AUTH_PROVIDER=auth0`) or Entra client credentials (`AUTH_PROVIDER=entra`, secret or certificate). Token is cached per process. | `createA2AProxyHandlerFromEnvService`, `createGetHeadersFromEnvService`, `getCachedAccessTokenFromEnvService` |
|
|
34
55
|
|
|
35
56
|
Env ROP example:
|
|
36
57
|
|
|
@@ -48,10 +69,10 @@ export const POST = createA2AProxyHandlerFromEnvROP({
|
|
|
48
69
|
import type { NextRequest } from "next/server";
|
|
49
70
|
import {
|
|
50
71
|
handleA2AConfigNextJsGET,
|
|
51
|
-
|
|
52
|
-
} from "@gnomondigital/nebulas-kit-core";
|
|
72
|
+
createGetHeadersFromEnvService,
|
|
73
|
+
} from "@gnomondigital/nebulas-kit-core/nextjs";
|
|
53
74
|
|
|
54
|
-
const getHeaders =
|
|
75
|
+
const getHeaders = createGetHeadersFromEnvService({
|
|
55
76
|
apiKey: process.env.A2A_API_KEY,
|
|
56
77
|
});
|
|
57
78
|
|
|
@@ -84,25 +105,16 @@ const content = await sendMessageStream(
|
|
|
84
105
|
|
|
85
106
|
```ts
|
|
86
107
|
// app/api/a2a/route.ts
|
|
87
|
-
import { handleA2ANextJsPOST } from "@nebulas-kit/
|
|
108
|
+
import { handleA2ANextJsPOST } from "@gnomondigital/nebulas-kit-core/nextjs";
|
|
88
109
|
|
|
89
110
|
export async function POST(req: NextRequest) {
|
|
90
111
|
return handleA2ANextJsPOST(req);
|
|
91
112
|
}
|
|
92
113
|
```
|
|
93
114
|
|
|
94
|
-
```ts
|
|
95
|
-
// app/api/a2a/auth/route.ts
|
|
96
|
-
import { handleA2AAuthNextJsPOST } from "@gnomondigital/nebulas-kit-core";
|
|
97
|
-
|
|
98
|
-
export async function POST(req: NextRequest) {
|
|
99
|
-
return handleA2AAuthNextJsPOST(req);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
115
|
```ts
|
|
104
116
|
// app/api/a2a/config/route.ts
|
|
105
|
-
import { handleA2AConfigNextJsGET } from "@gnomondigital/nebulas-kit-core";
|
|
117
|
+
import { handleA2AConfigNextJsGET } from "@gnomondigital/nebulas-kit-core/nextjs";
|
|
106
118
|
|
|
107
119
|
export async function GET() {
|
|
108
120
|
return handleA2AConfigNextJsGET();
|
|
@@ -111,7 +123,7 @@ export async function GET() {
|
|
|
111
123
|
|
|
112
124
|
```ts
|
|
113
125
|
// app/api/nebulas/[...path]/route.ts - proxies to Nebulas API (conversations, chat_messages)
|
|
114
|
-
import { createNebulasProxyHandler } from "@gnomondigital/nebulas-kit-core";
|
|
126
|
+
import { createNebulasProxyHandler } from "@gnomondigital/nebulas-kit-core/nextjs";
|
|
115
127
|
import { auth0 } from "@/lib/auth";
|
|
116
128
|
|
|
117
129
|
const handler = createNebulasProxyHandler({
|
|
@@ -131,10 +143,26 @@ export const DELETE = handler;
|
|
|
131
143
|
|
|
132
144
|
```ts
|
|
133
145
|
import express from "express";
|
|
134
|
-
import { createA2AExpressRouter } from "@gnomondigital/nebulas-kit-core";
|
|
146
|
+
import { createA2AExpressRouter } from "@gnomondigital/nebulas-kit-core/express";
|
|
135
147
|
|
|
136
148
|
const app = express();
|
|
137
149
|
app.use(express.json());
|
|
138
150
|
app.use("/api/a2a", createA2AExpressRouter(express));
|
|
139
151
|
app.listen(3000);
|
|
140
152
|
```
|
|
153
|
+
|
|
154
|
+
Use **`@gnomondigital/nebulas-kit-core/express`** so the bundle does not load Next.js adapters (`next/server`).
|
|
155
|
+
|
|
156
|
+
**Env ROP** (service user in `AUTH0_ROP_USERNAME` / `AUTH0_ROP_PASSWORD`, same as Next.js `createA2AProxyHandlerFromEnvROP`):
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
app.use(
|
|
160
|
+
"/api/a2a",
|
|
161
|
+
createA2AExpressRouter(express, {
|
|
162
|
+
useEnvRop: true,
|
|
163
|
+
envRopApiKey: process.env.A2A_API_KEY,
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
See `apps/demo_express_rop` in the monorepo for a full Express + Vite example.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser / React entry: A2A client, Nebulas client, shared types.
|
|
3
|
+
* Does not load Next.js, Express adapters, or other server-only modules.
|
|
4
|
+
*
|
|
5
|
+
* Use from UI code: `import { sendMessageStream } from "@gnomondigital/nebulas-kit-core/client"`
|
|
6
|
+
*/
|
|
7
|
+
export { sendMessageStream } from "./a2a-client.js";
|
|
8
|
+
export { createNebulasClient, nebulasClient, type NebulasConversation, type NebulasChatMessage, type CreateChatMessageParams, type NebulasClientOptions, } from "./nebulas-client.js";
|
|
9
|
+
export { transformUtcDatesToLocal } from "./utils/date-timezone.js";
|
|
10
|
+
export type { ChatMessage, ChatMessagePayload, SendMessageStreamOptions, } from "./types.js";
|
|
11
|
+
//# sourceMappingURL=client-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-api.d.ts","sourceRoot":"","sources":["../src/client-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser / React entry: A2A client, Nebulas client, shared types.
|
|
3
|
+
* Does not load Next.js, Express adapters, or other server-only modules.
|
|
4
|
+
*
|
|
5
|
+
* Use from UI code: `import { sendMessageStream } from "@gnomondigital/nebulas-kit-core/client"`
|
|
6
|
+
*/
|
|
7
|
+
export { sendMessageStream } from "./a2a-client.js";
|
|
8
|
+
export { createNebulasClient, nebulasClient, } from "./nebulas-client.js";
|
|
9
|
+
export { transformUtcDatesToLocal } from "./utils/date-timezone.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-api.d.ts","sourceRoot":"","sources":["../src/express-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,10 +8,8 @@ export { transformUtcDatesToLocal, } from "./utils/date-timezone.js";
|
|
|
8
8
|
export type { ChatMessage, ChatMessagePayload, SendMessageStreamOptions } from "./types.js";
|
|
9
9
|
export { handleA2AProxy, type ProxyRequest, type ProxyResponse, type ProxyHandlerOptions, } from "./server/proxy-handler.js";
|
|
10
10
|
export { getAuthStrategy, getAuthHeaders, type AuthStrategy, } from "./server/auth-strategies.js";
|
|
11
|
-
export { exchangePasswordForToken, type ROPAuthRequest, type ROPAuthResponse, } from "./server/auth-handler.js";
|
|
12
11
|
export { createConfigResponse, type ConfigResponse, type AgentCard, type AgentCardCapabilities, } from "./server/config-handler.js";
|
|
13
12
|
export { createA2AExpressRouter, type A2AExpressRouterOptions, } from "./server/express.js";
|
|
14
|
-
export {
|
|
15
|
-
export { getCachedAccessTokenFromEnvROP } from "./server/env-rop-token.js";
|
|
13
|
+
export { getCachedAccessTokenFromEnvService, } from "./server/env-service-token.js";
|
|
16
14
|
export { handleNebulasProxy, isRefreshTokenInvalid, type NebulasProxyRequest, type NebulasProxyResponse, type NebulasProxyHandlerOptions, } from "./server/nebulas-proxy-handler.js";
|
|
17
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE5F,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE5F,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kCAAkC,GACnC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,7 @@ export { createNebulasClient, nebulasClient, } from "./nebulas-client.js";
|
|
|
7
7
|
export { transformUtcDatesToLocal, } from "./utils/date-timezone.js";
|
|
8
8
|
export { handleA2AProxy, } from "./server/proxy-handler.js";
|
|
9
9
|
export { getAuthStrategy, getAuthHeaders, } from "./server/auth-strategies.js";
|
|
10
|
-
export { exchangePasswordForToken, } from "./server/auth-handler.js";
|
|
11
10
|
export { createConfigResponse, } from "./server/config-handler.js";
|
|
12
11
|
export { createA2AExpressRouter, } from "./server/express.js";
|
|
13
|
-
|
|
14
|
-
export { handleA2ANextJsPOST, handleA2AAuthNextJsPOST, handleA2AConfigNextJsGET, createGetHeadersForAuth0, createGetHeadersFromEnvROP, createA2AProxyHandler, createA2AProxyHandlerFromEnvROP, createNebulasProxyHandler, } from "./server/nextjs.js";
|
|
15
|
-
export { getCachedAccessTokenFromEnvROP } from "./server/env-rop-token.js";
|
|
12
|
+
export { getCachedAccessTokenFromEnvService, } from "./server/env-service-token.js";
|
|
16
13
|
export { handleNebulasProxy, isRefreshTokenInvalid, } from "./server/nebulas-proxy-handler.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js-only entry: avoids coupling the main package barrel to `next/server`.
|
|
3
|
+
*/
|
|
4
|
+
export { handleA2ANextJsPOST, handleA2AConfigNextJsGET, createGetHeadersForSession, createGetHeadersROP as createGetHeadersFromEnvService, createA2AProxyHandler, createA2AProxyHandlerFromEnvService, createNebulasProxyHandler, type HandleA2AConfigOptions, type SessionAuthClientInterface, type CreateA2AProxyHandlerOptions, type CreateA2AProxyHandlerFromEnvServiceOptions, type CreateGetHeadersROPOptions as CreateGetHeadersFromEnvServiceOptions, type CreateNebulasProxyHandlerOptions, } from "./server/nextjs.js";
|
|
5
|
+
//# sourceMappingURL=nextjs-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-api.d.ts","sourceRoot":"","sources":["../src/nextjs-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,IAAI,8BAA8B,EACrD,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,0CAA0C,EAC/C,KAAK,0BAA0B,IAAI,qCAAqC,EACxE,KAAK,gCAAgC,GACtC,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js-only entry: avoids coupling the main package barrel to `next/server`.
|
|
3
|
+
*/
|
|
4
|
+
export { handleA2ANextJsPOST, handleA2AConfigNextJsGET, createGetHeadersForSession, createGetHeadersROP as createGetHeadersFromEnvService, createA2AProxyHandler, createA2AProxyHandlerFromEnvService, createNebulasProxyHandler, } from "./server/nextjs.js";
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Auth handler for Resource Owner Password flow.
|
|
3
|
-
* Exchanges username/password for Auth0 token.
|
|
4
|
-
*/
|
|
5
|
-
export interface ROPAuthRequest {
|
|
6
|
-
username: string;
|
|
7
|
-
password: string;
|
|
8
|
-
}
|
|
9
|
-
export interface ROPAuthResponse {
|
|
10
|
-
access_token: string;
|
|
11
|
-
expires_in?: number;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Exchange username/password for Auth0 access token.
|
|
15
|
-
*/
|
|
16
|
-
export declare function exchangePasswordForToken(username: string, password: string): Promise<ROPAuthResponse>;
|
|
1
|
+
export { exchangePasswordForToken, type ROPAuthRequest, type ROPAuthResponse, } from "./auth0/auth-handler.js";
|
|
17
2
|
//# sourceMappingURL=auth-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/server/auth-handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/server/auth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC"}
|
|
@@ -1,35 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Auth handler for Resource Owner Password flow.
|
|
3
|
-
* Exchanges username/password for Auth0 token.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Exchange username/password for Auth0 access token.
|
|
7
|
-
*/
|
|
8
|
-
export async function exchangePasswordForToken(username, password) {
|
|
9
|
-
const domain = process.env.AUTH0_DOMAIN;
|
|
10
|
-
const clientId = process.env.AUTH0_CLIENT_ID;
|
|
11
|
-
const clientSecret = process.env.AUTH0_CLIENT_SECRET;
|
|
12
|
-
const audience = process.env.AUTH0_A2A_AUDIENCE;
|
|
13
|
-
if (!domain || !clientId || !clientSecret) {
|
|
14
|
-
throw new Error("AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET required for ROP");
|
|
15
|
-
}
|
|
16
|
-
const body = new URLSearchParams({
|
|
17
|
-
grant_type: "password",
|
|
18
|
-
username,
|
|
19
|
-
password,
|
|
20
|
-
client_id: clientId,
|
|
21
|
-
client_secret: clientSecret,
|
|
22
|
-
...(audience && { audience }),
|
|
23
|
-
});
|
|
24
|
-
const res = await fetch(`https://${domain}/oauth/token`, {
|
|
25
|
-
method: "POST",
|
|
26
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
27
|
-
body: body.toString(),
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
const body = await res.json().catch(() => ({}));
|
|
31
|
-
throw new Error(body.error_description || body.error || `Auth failed: ${res.status}`);
|
|
32
|
-
}
|
|
33
|
-
const data = (await res.json());
|
|
34
|
-
return data;
|
|
35
|
-
}
|
|
1
|
+
export { exchangePasswordForToken, } from "./auth0/auth-handler.js";
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
* Auth strategies for A2A proxy.
|
|
3
|
-
* Framework-agnostic; returns headers to add to the A2A request.
|
|
4
|
-
*/
|
|
5
|
-
export type AuthStrategy = "session" | "client_credentials" | "resource_owner_password" | "api_key_only";
|
|
6
|
-
/**
|
|
7
|
-
* Get headers for A2A request based on strategy.
|
|
8
|
-
* For session/bearer, the caller must pass the token (from session or Authorization header).
|
|
9
|
-
*/
|
|
1
|
+
export type AuthStrategy = "session" | "client_credentials" | "resource_owner_password";
|
|
10
2
|
export declare function getAuthHeaders(options: {
|
|
11
3
|
strategy: AuthStrategy;
|
|
12
4
|
bearerToken?: string;
|
|
13
5
|
getSessionToken?: () => Promise<string | undefined>;
|
|
6
|
+
apiKey?: string;
|
|
14
7
|
}): Promise<Record<string, string>>;
|
|
15
8
|
export declare function getAuthStrategy(): AuthStrategy;
|
|
16
9
|
//# sourceMappingURL=auth-strategies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-strategies.d.ts","sourceRoot":"","sources":["../../src/server/auth-strategies.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-strategies.d.ts","sourceRoot":"","sources":["../../src/server/auth-strategies.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,oBAAoB,GACpB,yBAAyB,CAAC;AAO9B,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA8ClC;AAED,wBAAgB,eAAe,IAAI,YAAY,CAU9C"}
|
|
@@ -1,71 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* Get Auth0 token via client credentials (M2M).
|
|
8
|
-
*/
|
|
9
|
-
async function getClientCredentialsToken() {
|
|
10
|
-
const domain = process.env.AUTH0_DOMAIN;
|
|
11
|
-
const clientId = process.env.AUTH0_CLIENT_ID;
|
|
12
|
-
const clientSecret = process.env.AUTH0_CLIENT_SECRET;
|
|
13
|
-
const audience = process.env.AUTH0_A2A_AUDIENCE;
|
|
14
|
-
if (!domain || !clientId || !clientSecret || !audience) {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
if (m2mTokenCache && m2mTokenCache.expiresAt > Date.now() + 60000) {
|
|
18
|
-
return m2mTokenCache.token;
|
|
19
|
-
}
|
|
20
|
-
const res = await fetch(`https://${domain}/oauth/token`, {
|
|
21
|
-
method: "POST",
|
|
22
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
23
|
-
body: new URLSearchParams({
|
|
24
|
-
grant_type: "client_credentials",
|
|
25
|
-
client_id: clientId,
|
|
26
|
-
client_secret: clientSecret,
|
|
27
|
-
audience,
|
|
28
|
-
}),
|
|
29
|
-
});
|
|
30
|
-
if (!res.ok) {
|
|
31
|
-
const body = await res.json().catch(() => ({}));
|
|
32
|
-
throw new Error(body.error_description || body.error || `Auth0 token failed: ${res.status}`);
|
|
33
|
-
}
|
|
34
|
-
const data = (await res.json());
|
|
35
|
-
const expiresIn = (data.expires_in ?? 86400) * 1000;
|
|
36
|
-
m2mTokenCache = {
|
|
37
|
-
token: data.access_token,
|
|
38
|
-
expiresAt: Date.now() + expiresIn,
|
|
39
|
-
};
|
|
40
|
-
return data.access_token;
|
|
1
|
+
import { exchangeEntraOnBehalfOfToken } from "./entra/session-token.js";
|
|
2
|
+
import { getAuth0ClientCredentialsToken } from "./auth0/client-credentials.js";
|
|
3
|
+
import { getCachedAccessTokenFromEnvService } from "./env-service-token.js";
|
|
4
|
+
function getAuthProvider() {
|
|
5
|
+
const provider = process.env.AUTH_PROVIDER?.toLowerCase();
|
|
6
|
+
return provider === "entra" ? "entra" : "auth0";
|
|
41
7
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Get headers for A2A request based on strategy.
|
|
44
|
-
* For session/bearer, the caller must pass the token (from session or Authorization header).
|
|
45
|
-
*/
|
|
46
8
|
export async function getAuthHeaders(options) {
|
|
47
9
|
const headers = {};
|
|
48
|
-
const apiKey = process.env.A2A_API_KEY;
|
|
10
|
+
const apiKey = options.apiKey ?? process.env.A2A_API_KEY;
|
|
11
|
+
if (apiKey)
|
|
12
|
+
headers["x-api-key"] = apiKey;
|
|
13
|
+
const provider = getAuthProvider();
|
|
49
14
|
switch (options.strategy) {
|
|
50
|
-
case "api_key_only":
|
|
51
|
-
if (apiKey)
|
|
52
|
-
headers["x-api-key"] = apiKey;
|
|
53
|
-
break;
|
|
54
15
|
case "client_credentials": {
|
|
55
|
-
const token =
|
|
16
|
+
const token = provider === "entra"
|
|
17
|
+
? await getCachedAccessTokenFromEnvService()
|
|
18
|
+
: await getAuth0ClientCredentialsToken();
|
|
56
19
|
if (token)
|
|
57
20
|
headers["Authorization"] = `Bearer ${token}`;
|
|
58
|
-
if (apiKey)
|
|
59
|
-
headers["x-api-key"] = apiKey;
|
|
60
21
|
break;
|
|
61
22
|
}
|
|
62
|
-
case "resource_owner_password":
|
|
63
23
|
case "session": {
|
|
64
|
-
const token = options.bearerToken ??
|
|
65
|
-
|
|
24
|
+
const token = options.bearerToken ??
|
|
25
|
+
(options.getSessionToken ? await options.getSessionToken() : undefined);
|
|
26
|
+
if (token) {
|
|
27
|
+
if (provider === "entra" && options.strategy === "session") {
|
|
28
|
+
const obo = await exchangeEntraOnBehalfOfToken(token);
|
|
29
|
+
console.log("obo", obo);
|
|
30
|
+
headers["Authorization"] = `Bearer ${obo.access_token}`;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log("token", token);
|
|
34
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "resource_owner_password": {
|
|
40
|
+
if (provider === "entra") {
|
|
41
|
+
throw new Error("A2A_AUTH_STRATEGY=resource_owner_password is Auth0-only.");
|
|
42
|
+
}
|
|
43
|
+
const token = await getCachedAccessTokenFromEnvService();
|
|
44
|
+
if (token) {
|
|
66
45
|
headers["Authorization"] = `Bearer ${token}`;
|
|
67
|
-
|
|
68
|
-
headers["x-api-key"] = apiKey;
|
|
46
|
+
}
|
|
69
47
|
break;
|
|
70
48
|
}
|
|
71
49
|
}
|
|
@@ -75,9 +53,8 @@ export function getAuthStrategy() {
|
|
|
75
53
|
const s = process.env.A2A_AUTH_STRATEGY?.toLowerCase();
|
|
76
54
|
if (s === "session" ||
|
|
77
55
|
s === "client_credentials" ||
|
|
78
|
-
s === "resource_owner_password"
|
|
79
|
-
s === "api_key_only") {
|
|
56
|
+
s === "resource_owner_password") {
|
|
80
57
|
return s;
|
|
81
58
|
}
|
|
82
|
-
return "
|
|
59
|
+
return "session";
|
|
83
60
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth0 handler for Resource Owner Password flow.
|
|
3
|
+
* Exchanges username/password for Auth0 token.
|
|
4
|
+
*/
|
|
5
|
+
export interface ROPAuthRequest {
|
|
6
|
+
username: string;
|
|
7
|
+
password: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ROPAuthResponse {
|
|
10
|
+
access_token: string;
|
|
11
|
+
expires_in?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Exchange username/password for Auth0 access token.
|
|
15
|
+
*/
|
|
16
|
+
export declare function exchangePasswordForToken(username: string, password: string): Promise<ROPAuthResponse>;
|
|
17
|
+
//# sourceMappingURL=auth-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/auth-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CA+B1B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth0 handler for Resource Owner Password flow.
|
|
3
|
+
* Exchanges username/password for Auth0 token.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Exchange username/password for Auth0 access token.
|
|
7
|
+
*/
|
|
8
|
+
export async function exchangePasswordForToken(username, password) {
|
|
9
|
+
const domain = process.env.AUTH0_DOMAIN;
|
|
10
|
+
const clientId = process.env.AUTH0_CLIENT_ID;
|
|
11
|
+
const clientSecret = process.env.AUTH0_CLIENT_SECRET;
|
|
12
|
+
const audience = process.env.AUTH0_A2A_AUDIENCE;
|
|
13
|
+
if (!domain || !clientId || !clientSecret) {
|
|
14
|
+
throw new Error("AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET required for ROP");
|
|
15
|
+
}
|
|
16
|
+
const body = new URLSearchParams({
|
|
17
|
+
grant_type: "password",
|
|
18
|
+
username,
|
|
19
|
+
password,
|
|
20
|
+
client_id: clientId,
|
|
21
|
+
client_secret: clientSecret,
|
|
22
|
+
...(audience && { audience }),
|
|
23
|
+
});
|
|
24
|
+
const res = await fetch(`https://${domain}/oauth/token`, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
27
|
+
body: body.toString(),
|
|
28
|
+
});
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
const payload = await res.json().catch(() => ({}));
|
|
31
|
+
throw new Error(payload.error_description || payload.error || `Auth failed: ${res.status}`);
|
|
32
|
+
}
|
|
33
|
+
const data = (await res.json());
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth strategies for A2A proxy.
|
|
3
|
+
* Framework-agnostic; returns headers to add to the A2A request.
|
|
4
|
+
*/
|
|
5
|
+
export type AuthStrategy = "session" | "client_credentials" | "resource_owner_password" | "api_key_only";
|
|
6
|
+
/**
|
|
7
|
+
* Get headers for A2A request based on strategy.
|
|
8
|
+
* For session/bearer, the caller must pass the token (from session or Authorization header).
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAuthHeaders(options: {
|
|
11
|
+
strategy: AuthStrategy;
|
|
12
|
+
bearerToken?: string;
|
|
13
|
+
getSessionToken?: () => Promise<string | undefined>;
|
|
14
|
+
}): Promise<Record<string, string>>;
|
|
15
|
+
export declare function getAuthStrategy(): AuthStrategy;
|
|
16
|
+
//# sourceMappingURL=auth-strategies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-strategies.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/auth-strategies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,oBAAoB,GACpB,yBAAyB,GACzB,cAAc,CAAC;AA8CnB;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA2BlC;AAED,wBAAgB,eAAe,IAAI,YAAY,CAW9C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth strategies for A2A proxy.
|
|
3
|
+
* Framework-agnostic; returns headers to add to the A2A request.
|
|
4
|
+
*/
|
|
5
|
+
let m2mTokenCache = null;
|
|
6
|
+
/**
|
|
7
|
+
* Get Auth0 token via client credentials (M2M).
|
|
8
|
+
*/
|
|
9
|
+
async function getClientCredentialsToken() {
|
|
10
|
+
const domain = process.env.AUTH0_DOMAIN;
|
|
11
|
+
const clientId = process.env.AUTH0_CLIENT_ID;
|
|
12
|
+
const clientSecret = process.env.AUTH0_CLIENT_SECRET;
|
|
13
|
+
const audience = process.env.AUTH0_A2A_AUDIENCE;
|
|
14
|
+
if (!domain || !clientId || !clientSecret || !audience) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (m2mTokenCache && m2mTokenCache.expiresAt > Date.now() + 60000) {
|
|
18
|
+
return m2mTokenCache.token;
|
|
19
|
+
}
|
|
20
|
+
const res = await fetch(`https://${domain}/oauth/token`, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
23
|
+
body: new URLSearchParams({
|
|
24
|
+
grant_type: "client_credentials",
|
|
25
|
+
client_id: clientId,
|
|
26
|
+
client_secret: clientSecret,
|
|
27
|
+
audience,
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
const body = await res.json().catch(() => ({}));
|
|
32
|
+
throw new Error(body.error_description || body.error || `Auth0 token failed: ${res.status}`);
|
|
33
|
+
}
|
|
34
|
+
const data = (await res.json());
|
|
35
|
+
const expiresIn = (data.expires_in ?? 86400) * 1000;
|
|
36
|
+
m2mTokenCache = {
|
|
37
|
+
token: data.access_token,
|
|
38
|
+
expiresAt: Date.now() + expiresIn,
|
|
39
|
+
};
|
|
40
|
+
return data.access_token;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get headers for A2A request based on strategy.
|
|
44
|
+
* For session/bearer, the caller must pass the token (from session or Authorization header).
|
|
45
|
+
*/
|
|
46
|
+
export async function getAuthHeaders(options) {
|
|
47
|
+
const headers = {};
|
|
48
|
+
const apiKey = process.env.A2A_API_KEY;
|
|
49
|
+
switch (options.strategy) {
|
|
50
|
+
case "api_key_only":
|
|
51
|
+
if (apiKey)
|
|
52
|
+
headers["x-api-key"] = apiKey;
|
|
53
|
+
break;
|
|
54
|
+
case "client_credentials": {
|
|
55
|
+
const token = await getClientCredentialsToken();
|
|
56
|
+
if (token)
|
|
57
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
58
|
+
if (apiKey)
|
|
59
|
+
headers["x-api-key"] = apiKey;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case "resource_owner_password":
|
|
63
|
+
case "session": {
|
|
64
|
+
const token = options.bearerToken ?? (options.getSessionToken ? await options.getSessionToken() : undefined);
|
|
65
|
+
if (token)
|
|
66
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
67
|
+
if (apiKey)
|
|
68
|
+
headers["x-api-key"] = apiKey;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return headers;
|
|
73
|
+
}
|
|
74
|
+
export function getAuthStrategy() {
|
|
75
|
+
const s = process.env.A2A_AUTH_STRATEGY?.toLowerCase();
|
|
76
|
+
if (s === "session" ||
|
|
77
|
+
s === "client_credentials" ||
|
|
78
|
+
s === "resource_owner_password" ||
|
|
79
|
+
s === "api_key_only") {
|
|
80
|
+
return s;
|
|
81
|
+
}
|
|
82
|
+
return "api_key_only";
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/client-credentials.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuClF"}
|