@gnomondigital/nebulas-kit-core 0.5.0 → 0.5.1

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/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { handleA2AProxy, type ProxyRequest, type ProxyResponse, type ProxyHandle
10
10
  export { getAuthStrategy, getAuthHeaders, type AuthStrategy, } from "./server/auth-strategies.js";
11
11
  export { createConfigResponse, type ConfigResponse, type AgentCard, type AgentCardCapabilities, } from "./server/config-handler.js";
12
12
  export { createA2AExpressRouter, type A2AExpressRouterOptions, } from "./server/express.js";
13
+ export { configureNebulasServer, getNebulasServerConfig, type NebulasServerRuntimeConfig, } from "./server/runtime-config.js";
13
14
  export { getCachedAccessTokenFromEnvService, } from "./server/env-service-token.js";
14
15
  export { handleNebulasProxy, isRefreshTokenInvalid, type NebulasProxyRequest, type NebulasProxyResponse, type NebulasProxyHandlerOptions, } from "./server/nebulas-proxy-handler.js";
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -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,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"}
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,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,0BAA0B,GAChC,MAAM,4BAA4B,CAAC;AAEpC,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
@@ -9,5 +9,6 @@ export { handleA2AProxy, } from "./server/proxy-handler.js";
9
9
  export { getAuthStrategy, getAuthHeaders, } from "./server/auth-strategies.js";
10
10
  export { createConfigResponse, } from "./server/config-handler.js";
11
11
  export { createA2AExpressRouter, } from "./server/express.js";
12
+ export { configureNebulasServer, getNebulasServerConfig, } from "./server/runtime-config.js";
12
13
  export { getCachedAccessTokenFromEnvService, } from "./server/env-service-token.js";
13
14
  export { handleNebulasProxy, isRefreshTokenInvalid, } from "./server/nebulas-proxy-handler.js";
@@ -1 +1 @@
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
+ {"version":3,"file":"auth-strategies.d.ts","sourceRoot":"","sources":["../../src/server/auth-strategies.ts"],"names":[],"mappings":"AAKA,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,CA4ClC;AAED,wBAAgB,eAAe,IAAI,YAAY,CAU9C"}
@@ -1,13 +1,14 @@
1
1
  import { exchangeEntraOnBehalfOfToken } from "./entra/session-token.js";
2
2
  import { getAuth0ClientCredentialsToken } from "./auth0/client-credentials.js";
3
3
  import { getCachedAccessTokenFromEnvService } from "./env-service-token.js";
4
+ import { getNebulasServerConfig } from "./runtime-config.js";
4
5
  function getAuthProvider() {
5
- const provider = process.env.AUTH_PROVIDER?.toLowerCase();
6
+ const provider = getNebulasServerConfig().authProvider;
6
7
  return provider === "entra" ? "entra" : "auth0";
7
8
  }
8
9
  export async function getAuthHeaders(options) {
9
10
  const headers = {};
10
- const apiKey = options.apiKey ?? process.env.A2A_API_KEY;
11
+ const apiKey = options.apiKey ?? getNebulasServerConfig().a2aApiKey;
11
12
  if (apiKey)
12
13
  headers["x-api-key"] = apiKey;
13
14
  const provider = getAuthProvider();
@@ -26,11 +27,9 @@ export async function getAuthHeaders(options) {
26
27
  if (token) {
27
28
  if (provider === "entra" && options.strategy === "session") {
28
29
  const obo = await exchangeEntraOnBehalfOfToken(token);
29
- console.log("obo", obo);
30
30
  headers["Authorization"] = `Bearer ${obo.access_token}`;
31
31
  }
32
32
  else {
33
- console.log("token", token);
34
33
  headers["Authorization"] = `Bearer ${token}`;
35
34
  }
36
35
  }
@@ -50,7 +49,7 @@ export async function getAuthHeaders(options) {
50
49
  return headers;
51
50
  }
52
51
  export function getAuthStrategy() {
53
- const s = process.env.A2A_AUTH_STRATEGY?.toLowerCase();
52
+ const s = getNebulasServerConfig().a2aAuthStrategy;
54
53
  if (s === "session" ||
55
54
  s === "client_credentials" ||
56
55
  s === "resource_owner_password") {
@@ -1 +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"}
1
+ {"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/auth-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,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,CAgC1B"}
@@ -2,14 +2,16 @@
2
2
  * Auth0 handler for Resource Owner Password flow.
3
3
  * Exchanges username/password for Auth0 token.
4
4
  */
5
+ import { getNebulasServerConfig } from "../runtime-config.js";
5
6
  /**
6
7
  * Exchange username/password for Auth0 access token.
7
8
  */
8
9
  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;
10
+ const config = getNebulasServerConfig().auth0;
11
+ const domain = config?.domain;
12
+ const clientId = config?.clientId;
13
+ const clientSecret = config?.clientSecret;
14
+ const audience = config?.audience;
13
15
  if (!domain || !clientId || !clientSecret) {
14
16
  throw new Error("AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET required for ROP");
15
17
  }
@@ -1 +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"}
1
+ {"version":3,"file":"client-credentials.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/client-credentials.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAwClF"}
@@ -1,12 +1,14 @@
1
+ import { getNebulasServerConfig } from "../runtime-config.js";
1
2
  let m2mTokenCache = null;
2
3
  /**
3
4
  * Get Auth0 token via client credentials (M2M).
4
5
  */
5
6
  export async function getAuth0ClientCredentialsToken() {
6
- const domain = process.env.AUTH0_DOMAIN;
7
- const clientId = process.env.AUTH0_CLIENT_ID;
8
- const clientSecret = process.env.AUTH0_CLIENT_SECRET;
9
- const audience = process.env.AUTH0_A2A_AUDIENCE;
7
+ const config = getNebulasServerConfig().auth0;
8
+ const domain = config?.domain;
9
+ const clientId = config?.clientId;
10
+ const clientSecret = config?.clientSecret;
11
+ const audience = config?.audience;
10
12
  if (!domain || !clientId || !clientSecret || !audience) {
11
13
  return undefined;
12
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/env-service-token.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,IAAI,OAAO,CAAC;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CASD"}
1
+ {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../../src/server/auth0/env-service-token.ts"],"names":[],"mappings":"AAGA,wBAAsB,4BAA4B,IAAI,OAAO,CAAC;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAUD"}
@@ -1,9 +1,11 @@
1
1
  import { exchangePasswordForToken } from "./auth-handler.js";
2
+ import { getNebulasServerConfig } from "../runtime-config.js";
2
3
  export async function exchangeAuth0EnvServiceToken() {
3
- const username = process.env.AUTH0_ROP_USERNAME;
4
- const password = process.env.AUTH0_ROP_PASSWORD;
4
+ const serviceUser = getNebulasServerConfig().auth0ServiceUser;
5
+ const username = serviceUser?.username;
6
+ const password = serviceUser?.password;
5
7
  if (!username || !password) {
6
- throw new Error("AUTH0_ROP_USERNAME and AUTH0_ROP_PASSWORD are required for Auth0 env ROP token");
8
+ throw new Error("Auth0 service user credentials are required for service ROP token");
7
9
  }
8
10
  return exchangePasswordForToken(username, password);
9
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config-handler.d.ts","sourceRoot":"","sources":["../../src/server/config-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAyBD,wBAAsB,oBAAoB,CACxC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,cAAc,CAAC,CAoBzB"}
1
+ {"version":3,"file":"config-handler.d.ts","sourceRoot":"","sources":["../../src/server/config-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AA0BD,wBAAsB,oBAAoB,CACxC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,cAAc,CAAC,CAmBzB"}
@@ -3,10 +3,10 @@
3
3
  * Fetches agent card from A2A_URL/.well-known/agent-card.json when A2A_URL is set.
4
4
  * Framework-agnostic; returns JSON response body.
5
5
  */
6
- import { nodeEnv } from "./node-env.js";
7
- const A2A_URL = nodeEnv("A2A_URL") || nodeEnv("NEXT_PUBLIC_A2A_URL") || "";
6
+ import { getNebulasServerConfig } from "./runtime-config.js";
8
7
  async function fetchAgentCard(headers) {
9
- const base = A2A_URL.replace(/\/$/, "");
8
+ const a2aUrl = getNebulasServerConfig().a2aUrl ?? "";
9
+ const base = a2aUrl.replace(/\/$/, "");
10
10
  if (!base)
11
11
  return null;
12
12
  const url = `${base}/.well-known/agent-card.json`;
@@ -29,9 +29,8 @@ async function fetchAgentCard(headers) {
29
29
  }
30
30
  }
31
31
  export async function createConfigResponse(options) {
32
- const nebulasProjectId = nodeEnv("NEBULAS_PROJECT_ID") ?? null;
32
+ const nebulasProjectId = getNebulasServerConfig().nebulasProjectId ?? null;
33
33
  const includeAgentCard = options?.includeAgentCard !== false;
34
- console.log("includeAgentCard", includeAgentCard);
35
34
  if (!includeAgentCard) {
36
35
  return {
37
36
  nebulasProjectId,
@@ -1 +1 @@
1
- {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../../src/server/entra/env-service-token.ts"],"names":[],"mappings":"AAmEA,wBAAsB,mCAAmC,IAAI,OAAO,CAAC;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAuED"}
1
+ {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../../src/server/entra/env-service-token.ts"],"names":[],"mappings":"AAkEA,wBAAsB,mCAAmC,IAAI,OAAO,CAAC;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAwED"}
@@ -1,5 +1,6 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { X509Certificate, createHash, createSign, randomUUID } from "node:crypto";
3
+ import { getNebulasServerConfig } from "../runtime-config.js";
3
4
  function base64UrlEncode(input) {
4
5
  const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input;
5
6
  return buf
@@ -8,12 +9,10 @@ function base64UrlEncode(input) {
8
9
  .replace(/\//g, "_")
9
10
  .replace(/=+$/g, "");
10
11
  }
11
- async function readEnvOrFile(valueEnv, pathEnv) {
12
- const inline = process.env[valueEnv];
13
- if (inline) {
14
- return inline.replace(/\\n/g, "\n");
12
+ async function readInlineOrFile(inlineValue, filePath) {
13
+ if (inlineValue) {
14
+ return inlineValue.replace(/\\n/g, "\n");
15
15
  }
16
- const filePath = process.env[pathEnv];
17
16
  if (filePath) {
18
17
  const content = await readFile(filePath, "utf8");
19
18
  return content;
@@ -53,21 +52,22 @@ function createClientAssertion(options) {
53
52
  return `${signingInput}.${base64UrlEncode(signature)}`;
54
53
  }
55
54
  export async function exchangeEntraClientCredentialsToken() {
56
- const tenantId = process.env.ENTRA_TENANT_ID;
57
- const clientId = process.env.ENTRA_CLIENT_ID;
58
- const clientSecret = process.env.ENTRA_CLIENT_SECRET;
59
- const certificatePem = await readEnvOrFile("ENTRA_CLIENT_CERTIFICATE", "ENTRA_CLIENT_CERTIFICATE_PATH");
60
- const privateKeyPem = await readEnvOrFile("ENTRA_CLIENT_PRIVATE_KEY", "ENTRA_CLIENT_PRIVATE_KEY_PATH");
61
- const scope = process.env.ENTRA_A2A_SCOPE || process.env.ENTRA_SCOPE;
55
+ const config = getNebulasServerConfig().entraService;
56
+ const tenantId = config?.tenantId;
57
+ const clientId = config?.clientId;
58
+ const clientSecret = config?.clientSecret;
59
+ const certificatePem = await readInlineOrFile(config?.certificatePem, config?.certificatePath);
60
+ const privateKeyPem = await readInlineOrFile(config?.privateKeyPem, config?.privateKeyPath);
61
+ const scope = config?.scope;
62
62
  if (!tenantId || !clientId || !scope) {
63
- throw new Error("ENTRA_TENANT_ID, ENTRA_CLIENT_ID, and ENTRA_A2A_SCOPE (or ENTRA_SCOPE) are required for Entra service token");
63
+ throw new Error("Entra service config requires tenantId, clientId, and scope");
64
64
  }
65
65
  const hasCertificateAuth = Boolean(certificatePem || privateKeyPem);
66
66
  if (hasCertificateAuth && (!certificatePem || !privateKeyPem)) {
67
- throw new Error("Entra certificate auth requires both certificate and private key (ENTRA_CLIENT_CERTIFICATE/ENTRA_CLIENT_CERTIFICATE_PATH and ENTRA_CLIENT_PRIVATE_KEY/ENTRA_CLIENT_PRIVATE_KEY_PATH)");
67
+ throw new Error("Entra certificate auth requires both certificate and private key");
68
68
  }
69
69
  if (!hasCertificateAuth && !clientSecret) {
70
- throw new Error("Provide ENTRA_CLIENT_SECRET or certificate credentials for Entra service token");
70
+ throw new Error("Provide Entra clientSecret or certificate credentials for service token");
71
71
  }
72
72
  const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
73
73
  const body = new URLSearchParams({
@@ -1 +1 @@
1
- {"version":3,"file":"session-token.d.ts","sourceRoot":"","sources":["../../../src/server/entra/session-token.ts"],"names":[],"mappings":"AAkEA,wBAAsB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAiFD"}
1
+ {"version":3,"file":"session-token.d.ts","sourceRoot":"","sources":["../../../src/server/entra/session-token.ts"],"names":[],"mappings":"AAiEA,wBAAsB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CA0ED"}
@@ -1,5 +1,6 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { X509Certificate, createHash, createSign, randomUUID } from "node:crypto";
3
+ import { getNebulasServerConfig } from "../runtime-config.js";
3
4
  function base64UrlEncode(input) {
4
5
  const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input;
5
6
  return buf
@@ -8,12 +9,10 @@ function base64UrlEncode(input) {
8
9
  .replace(/\//g, "_")
9
10
  .replace(/=+$/g, "");
10
11
  }
11
- async function readEnvOrFile(valueEnv, pathEnv) {
12
- const inline = process.env[valueEnv];
13
- if (inline) {
14
- return inline.replace(/\\n/g, "\n");
12
+ async function readInlineOrFile(inlineValue, filePath) {
13
+ if (inlineValue) {
14
+ return inlineValue.replace(/\\n/g, "\n");
15
15
  }
16
- const filePath = process.env[pathEnv];
17
16
  if (filePath) {
18
17
  return readFile(filePath, "utf8");
19
18
  }
@@ -52,25 +51,22 @@ function createClientAssertion(options) {
52
51
  return `${signingInput}.${base64UrlEncode(signature)}`;
53
52
  }
54
53
  export async function exchangeEntraOnBehalfOfToken(userAccessToken) {
55
- const tenantId = process.env.ENTRA_TENANT_ID;
56
- const clientId = process.env.ENTRA_OBO_CLIENT_ID;
57
- const clientSecret = process.env.ENTRA_OBO_CLIENT_SECRET;
58
- const certificatePem = await readEnvOrFile("ENTRA_CLIENT_CERTIFICATE", "ENTRA_CLIENT_CERTIFICATE_PATH");
59
- const privateKeyPem = await readEnvOrFile("ENTRA_CLIENT_PRIVATE_KEY", "ENTRA_CLIENT_PRIVATE_KEY_PATH");
60
- // OBO should request delegated user scopes for the downstream API.
61
- // Prefer a dedicated OBO scope, while keeping legacy fallbacks.
62
- const scope = process.env.ENTRA_OBO_SCOPE ||
63
- process.env.ENTRA_SCOPE ||
64
- process.env.ENTRA_A2A_SCOPE;
54
+ const config = getNebulasServerConfig().entraObo;
55
+ const tenantId = config?.tenantId;
56
+ const clientId = config?.clientId;
57
+ const clientSecret = config?.clientSecret;
58
+ const certificatePem = await readInlineOrFile(config?.certificatePem, config?.certificatePath);
59
+ const privateKeyPem = await readInlineOrFile(config?.privateKeyPem, config?.privateKeyPath);
60
+ const scope = config?.scope;
65
61
  if (!tenantId || !clientId || !scope) {
66
- throw new Error("ENTRA_TENANT_ID, ENTRA_CLIENT_ID, and ENTRA_OBO_SCOPE (or ENTRA_SCOPE, legacy ENTRA_A2A_SCOPE) are required for Entra OBO token");
62
+ throw new Error("Entra OBO config requires tenantId, clientId, and scope");
67
63
  }
68
64
  const hasCertificateAuth = Boolean(certificatePem || privateKeyPem);
69
65
  if (hasCertificateAuth && (!certificatePem || !privateKeyPem)) {
70
- throw new Error("Entra certificate auth requires both certificate and private key (ENTRA_CLIENT_CERTIFICATE/ENTRA_CLIENT_CERTIFICATE_PATH and ENTRA_CLIENT_PRIVATE_KEY/ENTRA_CLIENT_PRIVATE_KEY_PATH)");
66
+ throw new Error("Entra certificate auth requires both certificate and private key");
71
67
  }
72
68
  if (!hasCertificateAuth && !clientSecret) {
73
- throw new Error("Provide ENTRA_CLIENT_SECRET or certificate credentials for Entra OBO token");
69
+ throw new Error("Provide Entra clientSecret or certificate credentials for OBO token");
74
70
  }
75
71
  const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
76
72
  const body = new URLSearchParams({
@@ -93,7 +89,6 @@ export async function exchangeEntraOnBehalfOfToken(userAccessToken) {
93
89
  else {
94
90
  body.set("client_secret", clientSecret);
95
91
  }
96
- console.log("body", body.toString());
97
92
  const res = await fetch(tokenUrl, {
98
93
  method: "POST",
99
94
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
@@ -1 +1 @@
1
- {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../src/server/env-service-token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH;;;GAGG;AACH,wBAAsB,kCAAkC,IAAI,OAAO,CAAC,MAAM,CAAC,CAiB1E"}
1
+ {"version":3,"file":"env-service-token.d.ts","sourceRoot":"","sources":["../../src/server/env-service-token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyCH;;;GAGG;AACH,wBAAsB,kCAAkC,IAAI,OAAO,CAAC,MAAM,CAAC,CAiB1E"}
@@ -6,11 +6,12 @@
6
6
  */
7
7
  import { exchangeAuth0EnvServiceToken } from "./auth0/env-service-token.js";
8
8
  import { exchangeEntraClientCredentialsToken } from "./entra/env-service-token.js";
9
+ import { getNebulasServerConfig } from "./runtime-config.js";
9
10
  const EXPIRY_SKEW_MS = 60000;
10
11
  let cache = null;
11
12
  let refreshPromise = null;
12
13
  function getAuthProvider() {
13
- const provider = process.env.AUTH_PROVIDER?.toLowerCase();
14
+ const provider = getNebulasServerConfig().authProvider;
14
15
  if (provider === "entra") {
15
16
  return "entra";
16
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nebulas-proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/nebulas-proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC;CAC1D;AAED,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3E;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAS3D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,oBAAoB,CAAC,CAwH/B"}
1
+ {"version":3,"file":"nebulas-proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/nebulas-proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC;CAC1D;AAED,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3E;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAS3D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,oBAAoB,CAAC,CA6H/B"}
@@ -2,11 +2,7 @@
2
2
  * Framework-agnostic Nebulas API proxy handler.
3
3
  * Proxies requests to the Nebulas API (conversations, chat_messages).
4
4
  */
5
- import { nodeEnv } from "./node-env.js";
6
- const NEBULAS_API_URL = nodeEnv("NEBULAS_API_URL") || "http://localhost:8020";
7
- const A2A_AUDIENCE = nodeEnv("AUTH0_A2A_AUDIENCE");
8
- const A2A_API_KEY = nodeEnv("A2A_API_KEY");
9
- const NEBULAS_API_KEY = nodeEnv("NEBULAS_API_KEY");
5
+ import { getNebulasServerConfig } from "./runtime-config.js";
10
6
  /**
11
7
  * Check if an error indicates invalid refresh token (for session re-auth).
12
8
  */
@@ -23,8 +19,13 @@ export function isRefreshTokenInvalid(err) {
23
19
  * Proxies to NEBULAS_API_URL with auth headers from getHeaders or API keys.
24
20
  */
25
21
  export async function handleNebulasProxy(req, options = {}) {
22
+ const config = getNebulasServerConfig();
23
+ const nebulasApiUrl = config.nebulasApiUrl ?? "http://localhost:8020";
24
+ const a2aAudience = config.auth0?.audience;
25
+ const a2aApiKey = config.a2aApiKey;
26
+ const nebulasApiKey = config.nebulasApiKey;
26
27
  const backendPath = `/${req.path.join("/")}`;
27
- const url = new URL(backendPath, NEBULAS_API_URL.replace(/\/$/, "") + "/");
28
+ const url = new URL(backendPath, nebulasApiUrl.replace(/\/$/, "") + "/");
28
29
  for (const [key, value] of Object.entries(req.searchParams)) {
29
30
  url.searchParams.set(key, value);
30
31
  }
@@ -33,11 +34,11 @@ export async function handleNebulasProxy(req, options = {}) {
33
34
  if (contentType) {
34
35
  headers["Content-Type"] = contentType;
35
36
  }
36
- if (NEBULAS_API_KEY) {
37
- headers["x-api-key"] = NEBULAS_API_KEY;
37
+ if (nebulasApiKey) {
38
+ headers["x-api-key"] = nebulasApiKey;
38
39
  }
39
- else if (A2A_API_KEY) {
40
- headers["x-api-key"] = A2A_API_KEY;
40
+ else if (a2aApiKey) {
41
+ headers["x-api-key"] = a2aApiKey;
41
42
  }
42
43
  if (options.headers) {
43
44
  Object.assign(headers, options.headers);
@@ -59,7 +60,7 @@ export async function handleNebulasProxy(req, options = {}) {
59
60
  }),
60
61
  };
61
62
  }
62
- if (!A2A_API_KEY && !NEBULAS_API_KEY) {
63
+ if (!a2aApiKey && !nebulasApiKey) {
63
64
  return {
64
65
  status: 401,
65
66
  headers: { "Content-Type": "application/json" },
@@ -73,7 +74,7 @@ export async function handleNebulasProxy(req, options = {}) {
73
74
  }
74
75
  }
75
76
  const hasAuth = headers["Authorization"] || headers["x-api-key"];
76
- if (!hasAuth && (A2A_AUDIENCE || options.getHeaders)) {
77
+ if (!hasAuth && (a2aAudience || options.getHeaders)) {
77
78
  return {
78
79
  status: 401,
79
80
  headers: { "Content-Type": "application/json" },
@@ -64,7 +64,7 @@ export interface CreateA2AProxyHandlerOptions {
64
64
  * Propagates Set-Cookie from Auth0 token refresh.
65
65
  *
66
66
  * Use in app/api/a2a/route.ts:
67
- * const handler = createA2AProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.A2A_API_KEY });
67
+ * const handler = createA2AProxyHandler({ auth0, audience: "api://your-audience", apiKey: "your-api-key" });
68
68
  * export const POST = handler;
69
69
  */
70
70
  export declare function createA2AProxyHandler(options: CreateA2AProxyHandlerOptions): (request: NextRequest) => Promise<Response>;
@@ -83,7 +83,7 @@ export interface CreateA2AProxyHandlerFromEnvServiceOptions {
83
83
  * Next.js POST handler for the A2A proxy using service auth (Auth0 ROP or Entra client credentials), not Auth0 session.
84
84
  *
85
85
  * Use in app/api/a2a/route.ts:
86
- * export const POST = createA2AProxyHandlerFromEnvService({ apiKey: process.env.A2A_API_KEY });
86
+ * export const POST = createA2AProxyHandlerFromEnvService({ apiKey: "your-api-key" });
87
87
  */
88
88
  export declare function createA2AProxyHandlerFromEnvService(options?: CreateA2AProxyHandlerFromEnvServiceOptions): (request: NextRequest) => Promise<Response>;
89
89
  /**
@@ -99,7 +99,7 @@ export interface CreateNebulasProxyHandlerOptions {
99
99
  * Proxies requests to NEBULAS_API_URL with Auth0 session token or API key.
100
100
  *
101
101
  * Use in app/api/nebulas/[...path]/route.ts:
102
- * const handler = createNebulasProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.NEBULAS_API_KEY });
102
+ * const handler = createNebulasProxyHandler({ auth0, audience: "api://your-audience", apiKey: "your-api-key" });
103
103
  * export const GET = handler;
104
104
  * export const POST = handler;
105
105
  * export const PUT = handler;
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/server/nextjs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAiB9E;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,mBAAmB,qBAa9B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,sBAAsB,qBAsBjC;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,cAAc,CACZ,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,UAAU,EAAE,0BAA0B,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CACF,OAAO,EAAE,WAAW,EACpB,YAAY,CAAC,EAAE,YAAY,KACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoDnC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,0BAA0B,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,IAO3C,SAAS,WAAW,uBA0BnD;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmB5D;AAED,MAAM,WAAW,0CAA0C;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,OAAO,CAAC,EAAE,0CAA0C,IAEtB,SAAS,WAAW,uBAgCnD;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,0BAA0B,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,IAE/E,SAAS,WAAW,EACpB,KAAK;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,oCAiE/C"}
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/server/nextjs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAiB9E;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,mBAAmB,qBAa9B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,sBAAsB,qBAoBjC;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,cAAc,CACZ,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,UAAU,EAAE,0BAA0B,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CACF,OAAO,EAAE,WAAW,EACpB,YAAY,CAAC,EAAE,YAAY,KACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoDnC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,0BAA0B,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,IAO3C,SAAS,WAAW,uBA0BnD;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmB5D;AAED,MAAM,WAAW,0CAA0C;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,OAAO,CAAC,EAAE,0CAA0C,IAEtB,SAAS,WAAW,uBAgCnD;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,0BAA0B,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,IAE/E,SAAS,WAAW,EACpB,KAAK;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,oCAiE/C"}
@@ -48,7 +48,6 @@ export async function handleA2AConfigNextJsGET(request, options) {
48
48
  throw e;
49
49
  }
50
50
  }
51
- console.log("headers", headers);
52
51
  const config = await createConfigResponse({ includeAgentCard, headers });
53
52
  return new Response(JSON.stringify(config), {
54
53
  status: 200,
@@ -111,7 +110,7 @@ export function createGetHeadersForSession(options) {
111
110
  * Propagates Set-Cookie from Auth0 token refresh.
112
111
  *
113
112
  * Use in app/api/a2a/route.ts:
114
- * const handler = createA2AProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.A2A_API_KEY });
113
+ * const handler = createA2AProxyHandler({ auth0, audience: "api://your-audience", apiKey: "your-api-key" });
115
114
  * export const POST = handler;
116
115
  */
117
116
  export function createA2AProxyHandler(options) {
@@ -170,7 +169,7 @@ export function createGetHeadersROP(options) {
170
169
  * Next.js POST handler for the A2A proxy using service auth (Auth0 ROP or Entra client credentials), not Auth0 session.
171
170
  *
172
171
  * Use in app/api/a2a/route.ts:
173
- * export const POST = createA2AProxyHandlerFromEnvService({ apiKey: process.env.A2A_API_KEY });
172
+ * export const POST = createA2AProxyHandlerFromEnvService({ apiKey: "your-api-key" });
174
173
  */
175
174
  export function createA2AProxyHandlerFromEnvService(options) {
176
175
  return async function handler(request) {
@@ -205,7 +204,7 @@ export function createA2AProxyHandlerFromEnvService(options) {
205
204
  * Proxies requests to NEBULAS_API_URL with Auth0 session token or API key.
206
205
  *
207
206
  * Use in app/api/nebulas/[...path]/route.ts:
208
- * const handler = createNebulasProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.NEBULAS_API_KEY });
207
+ * const handler = createNebulasProxyHandler({ auth0, audience: "api://your-audience", apiKey: "your-api-key" });
209
208
  * export const GET = handler;
210
209
  * export const POST = handler;
211
210
  * export const PUT = handler;
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAM9B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,aAAa,CAAC,CAmFxB"}
1
+ {"version":3,"file":"proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,aAAa,CAAC,CAoFxB"}
@@ -3,13 +3,13 @@
3
3
  * Accepts a minimal request/response interface.
4
4
  */
5
5
  import { getAuthStrategy, getAuthHeaders, } from "./auth-strategies.js";
6
- import { nodeEnv } from "./node-env.js";
7
- const A2A_URL = nodeEnv("A2A_URL") || nodeEnv("NEXT_PUBLIC_A2A_URL") || "http://localhost:9999";
6
+ import { getNebulasServerConfig } from "./runtime-config.js";
8
7
  /**
9
8
  * Handle A2A proxy request. Returns response to send.
10
9
  */
11
10
  export async function handleA2AProxy(req, options = {}) {
12
- const url = A2A_URL.replace(/\/$/, "");
11
+ const a2aUrl = getNebulasServerConfig().a2aUrl ?? "http://localhost:9999";
12
+ const url = a2aUrl.replace(/\/$/, "");
13
13
  let headers;
14
14
  if (options.headers) {
15
15
  headers = {
@@ -27,7 +27,7 @@ export async function handleA2AProxy(req, options = {}) {
27
27
  else if (strategy === "session" && options.getSessionToken) {
28
28
  bearerToken = await options.getSessionToken(req);
29
29
  }
30
- if (strategy === "session" && !bearerToken && !nodeEnv("A2A_API_KEY")) {
30
+ if (strategy === "session" && !bearerToken && !getNebulasServerConfig().a2aApiKey) {
31
31
  return {
32
32
  status: 401,
33
33
  headers: { "Content-Type": "application/json" },
@@ -0,0 +1,45 @@
1
+ export type AuthProvider = "auth0" | "entra";
2
+ export interface Auth0RuntimeConfig {
3
+ domain: string;
4
+ clientId: string;
5
+ clientSecret: string;
6
+ audience?: string;
7
+ }
8
+ export interface Auth0ServiceUserRuntimeConfig {
9
+ username: string;
10
+ password: string;
11
+ }
12
+ export interface EntraCertificateRuntimeConfig {
13
+ certificatePem?: string;
14
+ certificatePath?: string;
15
+ privateKeyPem?: string;
16
+ privateKeyPath?: string;
17
+ }
18
+ export interface EntraServiceRuntimeConfig extends EntraCertificateRuntimeConfig {
19
+ tenantId: string;
20
+ clientId: string;
21
+ clientSecret?: string;
22
+ scope: string;
23
+ }
24
+ export interface EntraOboRuntimeConfig extends EntraCertificateRuntimeConfig {
25
+ tenantId: string;
26
+ clientId: string;
27
+ clientSecret?: string;
28
+ scope: string;
29
+ }
30
+ export interface NebulasServerRuntimeConfig {
31
+ a2aUrl?: string;
32
+ a2aAuthStrategy?: "session" | "client_credentials" | "resource_owner_password";
33
+ a2aApiKey?: string;
34
+ authProvider?: AuthProvider;
35
+ nebulasApiUrl?: string;
36
+ nebulasApiKey?: string;
37
+ nebulasProjectId?: string;
38
+ auth0?: Auth0RuntimeConfig;
39
+ auth0ServiceUser?: Auth0ServiceUserRuntimeConfig;
40
+ entraService?: EntraServiceRuntimeConfig;
41
+ entraObo?: EntraOboRuntimeConfig;
42
+ }
43
+ export declare function configureNebulasServer(config: Partial<NebulasServerRuntimeConfig>): void;
44
+ export declare function getNebulasServerConfig(): Readonly<NebulasServerRuntimeConfig>;
45
+ //# sourceMappingURL=runtime-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-config.d.ts","sourceRoot":"","sources":["../../src/server/runtime-config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,6BAA6B;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,yBAA0B,SAAQ,6BAA6B;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAsB,SAAQ,6BAA6B;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,SAAS,GAAG,oBAAoB,GAAG,yBAAyB,CAAC;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;IACjD,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAID,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAC1C,IAAI,CAeN;AAED,wBAAgB,sBAAsB,IAAI,QAAQ,CAAC,0BAA0B,CAAC,CAE7E"}
@@ -0,0 +1,20 @@
1
+ let runtimeConfig = {};
2
+ export function configureNebulasServer(config) {
3
+ runtimeConfig = {
4
+ ...runtimeConfig,
5
+ ...config,
6
+ auth0: config.auth0 ? { ...runtimeConfig.auth0, ...config.auth0 } : runtimeConfig.auth0,
7
+ auth0ServiceUser: config.auth0ServiceUser
8
+ ? { ...runtimeConfig.auth0ServiceUser, ...config.auth0ServiceUser }
9
+ : runtimeConfig.auth0ServiceUser,
10
+ entraService: config.entraService
11
+ ? { ...runtimeConfig.entraService, ...config.entraService }
12
+ : runtimeConfig.entraService,
13
+ entraObo: config.entraObo
14
+ ? { ...runtimeConfig.entraObo, ...config.entraObo }
15
+ : runtimeConfig.entraObo,
16
+ };
17
+ }
18
+ export function getNebulasServerConfig() {
19
+ return runtimeConfig;
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gnomondigital/nebulas-kit-core",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",