@adonis-agora/agent 0.94.0 → 0.95.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/CHANGELOG.md +10 -0
- package/dist/assets/spa/assets/{index-DUq09Q_k.js → index-DBu17cDY.js} +1 -1
- package/dist/assets/spa/index.html +1 -1
- package/dist/providers/poppy_connections_provider.d.ts +1 -1
- package/dist/providers/poppy_connections_provider.js +1 -1
- package/dist/providers/poppy_provider.d.ts +1 -1
- package/dist/providers/poppy_provider.d.ts.map +1 -1
- package/dist/providers/poppy_provider.js +6 -6
- package/dist/providers/poppy_provider.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/mcp/auth.d.ts +3 -3
- package/dist/src/mcp/auth.d.ts.map +1 -1
- package/dist/src/mcp/auth.js +2 -29
- package/dist/src/mcp/auth.js.map +1 -1
- package/dist/src/mcp/discovery.d.ts +3 -3
- package/dist/src/mcp/discovery.d.ts.map +1 -1
- package/dist/src/mcp/discovery.js +2 -2
- package/dist/src/poppy/auth.d.ts +20 -16
- package/dist/src/poppy/auth.d.ts.map +1 -1
- package/dist/src/poppy/auth.js.map +1 -1
- package/dist/src/poppy/conversations.d.ts +25 -25
- package/dist/src/poppy/conversations.d.ts.map +1 -1
- package/dist/src/poppy/conversations.js +37 -37
- package/dist/src/poppy/conversations.js.map +1 -1
- package/dist/src/poppy/define_config.d.ts +7 -7
- package/dist/src/poppy/define_config.d.ts.map +1 -1
- package/dist/src/poppy/define_config.js +1 -1
- package/dist/src/poppy/endpoints.d.ts +2 -2
- package/dist/src/poppy/endpoints.js +1 -1
- package/dist/src/poppy/handler.d.ts +5 -5
- package/dist/src/poppy/handler.d.ts.map +1 -1
- package/dist/src/poppy/handler.js +23 -21
- package/dist/src/poppy/handler.js.map +1 -1
- package/dist/src/poppy/index.d.ts +2 -2
- package/dist/src/poppy/index.d.ts.map +1 -1
- package/dist/src/poppy/index.js +1 -1
- package/dist/src/poppy/index.js.map +1 -1
- package/dist/src/poppy/protocol.d.ts +30 -23
- package/dist/src/poppy/protocol.d.ts.map +1 -1
- package/dist/src/poppy/protocol.js +16 -17
- package/dist/src/poppy/protocol.js.map +1 -1
- package/dist/src/poppy/redis-store.d.ts +1 -1
- package/dist/src/poppy/redis-store.js +1 -1
- package/dist/src/poppy/store.d.ts +7 -7
- package/dist/src/poppy/store.js +1 -1
- package/dist/src/poppy-client/api.d.ts +5 -4
- package/dist/src/poppy-client/api.d.ts.map +1 -1
- package/dist/src/poppy-client/api.js +14 -9
- package/dist/src/poppy-client/api.js.map +1 -1
- package/dist/src/poppy-client/browser.d.ts +12 -18
- package/dist/src/poppy-client/browser.d.ts.map +1 -1
- package/dist/src/poppy-client/browser.js +33 -73
- package/dist/src/poppy-client/browser.js.map +1 -1
- package/dist/src/poppy-client/cli/main.d.ts.map +1 -1
- package/dist/src/poppy-client/cli/main.js +48 -56
- package/dist/src/poppy-client/cli/main.js.map +1 -1
- package/dist/src/poppy-client/company.d.ts +43 -28
- package/dist/src/poppy-client/company.d.ts.map +1 -1
- package/dist/src/poppy-client/company.js +216 -160
- package/dist/src/poppy-client/company.js.map +1 -1
- package/dist/src/poppy-client/conversations.d.ts +12 -13
- package/dist/src/poppy-client/conversations.d.ts.map +1 -1
- package/dist/src/poppy-client/conversations.js +24 -22
- package/dist/src/poppy-client/conversations.js.map +1 -1
- package/dist/src/poppy-client/discovery.d.ts +32 -10
- package/dist/src/poppy-client/discovery.d.ts.map +1 -1
- package/dist/src/poppy-client/discovery.js +134 -68
- package/dist/src/poppy-client/discovery.js.map +1 -1
- package/dist/src/poppy-client/dpop.d.ts +2 -1
- package/dist/src/poppy-client/dpop.d.ts.map +1 -1
- package/dist/src/poppy-client/dpop.js +2 -1
- package/dist/src/poppy-client/dpop.js.map +1 -1
- package/dist/src/poppy-client/errors.d.ts +5 -4
- package/dist/src/poppy-client/errors.d.ts.map +1 -1
- package/dist/src/poppy-client/errors.js +5 -4
- package/dist/src/poppy-client/errors.js.map +1 -1
- package/dist/src/poppy-client/http.d.ts +4 -2
- package/dist/src/poppy-client/http.d.ts.map +1 -1
- package/dist/src/poppy-client/http.js +9 -5
- package/dist/src/poppy-client/http.js.map +1 -1
- package/dist/src/poppy-client/identity.d.ts +15 -15
- package/dist/src/poppy-client/identity.d.ts.map +1 -1
- package/dist/src/poppy-client/identity.js +17 -33
- package/dist/src/poppy-client/identity.js.map +1 -1
- package/dist/src/poppy-client/index.d.ts +6 -3
- package/dist/src/poppy-client/index.d.ts.map +1 -1
- package/dist/src/poppy-client/index.js +6 -3
- package/dist/src/poppy-client/index.js.map +1 -1
- package/dist/src/poppy-client/llm.js +4 -4
- package/dist/src/poppy-client/llm.js.map +1 -1
- package/dist/src/poppy-client/mcp.d.ts +3 -4
- package/dist/src/poppy-client/mcp.d.ts.map +1 -1
- package/dist/src/poppy-client/mcp.js +26 -38
- package/dist/src/poppy-client/mcp.js.map +1 -1
- package/dist/src/poppy-client/safe_fetch.d.ts +30 -0
- package/dist/src/poppy-client/safe_fetch.d.ts.map +1 -0
- package/dist/src/poppy-client/safe_fetch.js +210 -0
- package/dist/src/poppy-client/safe_fetch.js.map +1 -0
- package/dist/src/poppy-client/session_jwt.d.ts +20 -0
- package/dist/src/poppy-client/session_jwt.d.ts.map +1 -0
- package/dist/src/poppy-client/session_jwt.js +37 -0
- package/dist/src/poppy-client/session_jwt.js.map +1 -0
- package/dist/src/poppy-client/signin.d.ts +34 -11
- package/dist/src/poppy-client/signin.d.ts.map +1 -1
- package/dist/src/poppy-client/signin.js +134 -80
- package/dist/src/poppy-client/signin.js.map +1 -1
- package/dist/src/poppy-client/store.d.ts +23 -11
- package/dist/src/poppy-client/store.d.ts.map +1 -1
- package/dist/src/poppy-client/store.js +1 -1
- package/dist/src/poppy-client/store.js.map +1 -1
- package/dist/src/poppy-client/task_coverage.d.ts +13 -0
- package/dist/src/poppy-client/task_coverage.d.ts.map +1 -0
- package/dist/src/poppy-client/task_coverage.js +66 -0
- package/dist/src/poppy-client/task_coverage.js.map +1 -0
- package/dist/src/poppy-client/token_client.d.ts +36 -33
- package/dist/src/poppy-client/token_client.d.ts.map +1 -1
- package/dist/src/poppy-client/token_client.js +47 -47
- package/dist/src/poppy-client/token_client.js.map +1 -1
- package/dist/src/poppy-client/types.d.ts +81 -42
- package/dist/src/poppy-client/types.d.ts.map +1 -1
- package/dist/src/poppy-client/types.js +1 -1
- package/dist/src/poppy-client/util.d.ts +12 -3
- package/dist/src/poppy-client/util.d.ts.map +1 -1
- package/dist/src/poppy-client/util.js +29 -9
- package/dist/src/poppy-client/util.js.map +1 -1
- package/dist/src/poppy-connections/config.d.ts +2 -2
- package/dist/src/poppy-connections/config.js +1 -1
- package/dist/src/poppy-connections/config.js.map +1 -1
- package/dist/src/poppy-connections/crypto.d.ts +2 -2
- package/dist/src/poppy-connections/crypto.js +2 -2
- package/dist/src/poppy-connections/index.d.ts +1 -1
- package/dist/src/poppy-connections/index.js +1 -1
- package/dist/src/poppy-connections/service.d.ts +11 -10
- package/dist/src/poppy-connections/service.d.ts.map +1 -1
- package/dist/src/poppy-connections/service.js +33 -21
- package/dist/src/poppy-connections/service.js.map +1 -1
- package/dist/src/poppy-connections/store.d.ts +2 -2
- package/dist/src/poppy-connections/tools.d.ts.map +1 -1
- package/dist/src/poppy-connections/tools.js +5 -4
- package/dist/src/poppy-connections/tools.js.map +1 -1
- package/package.json +6 -6
- package/skills/agent-governance/SKILL.md +3 -3
- package/skills/agent-tools/SKILL.md +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/identity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAW,MAAM,MAAM,CAAC;AACzC,OAAO,EAAqC,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAEzF,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,yEAAyE;IACzE,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;CAC9D;AAED,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,cAAc,uBAAuB,CAAC;AACnD,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,QAAW,CAAC;AAE/C;;;GAGG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IAEtE,YAAY,GAAG,EAAE,cAAc,EAAE,GAAG,GAAE,eAAoB,EASzD;IAED,0EAA0E;IAC1E,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,uEAAuE;IACvE,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,QAAQ,IAAI,cAAc,CAazB;IAED,0DAA0D;IAC1D,IAAI,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAE1C;YAEa,IAAI;IAQlB;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU/C;IAED;;;OAGG;IACG,QAAQ,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAQpE;CACF"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { SignJWT } from 'jose';
|
|
2
|
-
import { importSigningKey } from './keys.js';
|
|
2
|
+
import { bareEcPublicJwk, importSigningKey } from './keys.js';
|
|
3
3
|
import { nowSeconds, randomId, requireSecureUrl } from './util.js';
|
|
4
|
-
/** Lifetime of
|
|
4
|
+
/** Lifetime of a client assertion (the guides suggest at most five minutes). */
|
|
5
5
|
export const ASSERTION_TTL_SECONDS = 60;
|
|
6
|
+
export const DELEGATION_TYP = 'pap-delegation+jwt';
|
|
7
|
+
/** How long a delegation lasts, within the 24 hours 5.2 allows. */
|
|
8
|
+
export const DELEGATION_TTL_SECONDS = 7 * 3600;
|
|
6
9
|
/**
|
|
7
10
|
* The Personal Agent's identity (4.1): its `client_id` URL, its metadata document, and the
|
|
8
|
-
* keys from `jwks_uri` that sign client assertions
|
|
11
|
+
* keys from `jwks_uri` that sign client assertions and the delegations of Session JWT keys.
|
|
9
12
|
*/
|
|
10
13
|
export class AgentIdentity {
|
|
11
14
|
baseUrl;
|
|
@@ -64,48 +67,29 @@ export class AgentIdentity {
|
|
|
64
67
|
return new SignJWT(payload).setProtectedHeader(header).sign(await importSigningKey(key));
|
|
65
68
|
}
|
|
66
69
|
/**
|
|
67
|
-
* `private_key_jwt` client assertion (RFC 7523
|
|
68
|
-
*
|
|
70
|
+
* `private_key_jwt` client assertion (4.1, RFC 7523): `iss` = `sub` = `client_id`, `aud` = the
|
|
71
|
+
* Company's issuer as a single string, short-lived, with `iat` and a fresh `jti`.
|
|
69
72
|
*/
|
|
70
|
-
clientAssertion(
|
|
73
|
+
clientAssertion(issuer) {
|
|
71
74
|
const iat = nowSeconds();
|
|
72
75
|
return this.sign({
|
|
73
76
|
iss: this.clientId,
|
|
74
77
|
sub: this.clientId,
|
|
75
|
-
aud:
|
|
78
|
+
aud: issuer,
|
|
76
79
|
iat,
|
|
77
80
|
exp: iat + ASSERTION_TTL_SECONDS,
|
|
78
81
|
jti: randomId(),
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
85
|
+
* A delegation (5.2): vouches for one delegated public key. It names no User or Company. Its
|
|
86
|
+
* times are rounded to the hour, as the guides suggest, so they say less about when it was made.
|
|
84
87
|
*/
|
|
85
|
-
|
|
86
|
-
const iat = nowSeconds();
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
aud: tokenEndpoint,
|
|
91
|
-
iat,
|
|
92
|
-
exp: iat + ASSERTION_TTL_SECONDS,
|
|
93
|
-
jti: randomId(),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/** Browser assertion (section 5), header `typ: poppy-browser+jwt`, `exp` <= `iat` + 60. */
|
|
97
|
-
browserAssertion(input) {
|
|
98
|
-
const iat = nowSeconds();
|
|
99
|
-
return this.sign({
|
|
100
|
-
iss: this.clientId,
|
|
101
|
-
sub: input.userId,
|
|
102
|
-
aud: input.endpoint,
|
|
103
|
-
session_id: input.sessionId,
|
|
104
|
-
return_to: input.returnTo,
|
|
105
|
-
iat,
|
|
106
|
-
exp: iat + ASSERTION_TTL_SECONDS,
|
|
107
|
-
jti: randomId(),
|
|
108
|
-
}, 'poppy-browser+jwt');
|
|
88
|
+
async delegate(publicJwk) {
|
|
89
|
+
const iat = Math.floor(nowSeconds() / 3600) * 3600;
|
|
90
|
+
const exp = iat + DELEGATION_TTL_SECONDS;
|
|
91
|
+
const jwt = await this.sign({ iss: this.clientId, cnf: { jwk: bareEcPublicJwk(publicJwk) }, iat, exp, jti: randomId() }, DELEGATION_TYP);
|
|
92
|
+
return { jwt, exp };
|
|
109
93
|
}
|
|
110
94
|
}
|
|
111
95
|
//# sourceMappingURL=identity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/poppy-client/identity.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/poppy-client/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { apiBaseUrl, callOpenApi, listApis, loadOpenApi, pickApi } from './api.js';
|
|
2
|
-
export {
|
|
2
|
+
export { authorizeBrowserJoin, browserJoinCode, browserSessionEndpoint } from './browser.js';
|
|
3
3
|
export { CompanyClient, PoppyAgent, type PoppyAgentOptions, type SignInResult, throwForResponse, } from './company.js';
|
|
4
4
|
export { ConversationClient, type FollowOptions, newMessageId, poppyProtocol, type StreamItem, } from './conversations.js';
|
|
5
|
-
export { authServerMetadataUrl, type Discovered, discover, HttpJsonCache,
|
|
5
|
+
export { authServerMetadataUrl, type Discovered, discover, HttpJsonCache, SUPPORTED_PROTOCOL_VERSIONS, validateMetadata, validatePoppyDocument, validateProtectedResourceMetadata, wellKnownUrlFor, } from './discovery.js';
|
|
6
6
|
export { DpopKey, htuOf } from './dpop.js';
|
|
7
7
|
export { ConversationError, DiscoveryError, OAuthError, PoppyError, ResourceAuthError, } from './errors.js';
|
|
8
8
|
export { PoppyHttp } from './http.js';
|
|
@@ -11,9 +11,12 @@ export { startIdentityServer, waitForRelayedCallback } from './identity_server.j
|
|
|
11
11
|
export { generateEs256Key, type StoredKey } from './keys.js';
|
|
12
12
|
export { ask, DEFAULT_MODEL } from './llm.js';
|
|
13
13
|
export { connectMcp, type McpConnection } from './mcp.js';
|
|
14
|
-
export {
|
|
14
|
+
export { createSafeFetch, isBlockedAddress, safeFetch } from './safe_fetch.js';
|
|
15
|
+
export { SESSION_JWT_TYP, signSessionJwt } from './session_jwt.js';
|
|
16
|
+
export { completeDirectSignIn, deviceSignIn, eligibleSignInTypes, type MediatedOutcome, mediatedExtension, mediatedSignIn, offeredSignInTypes, type PendingDirectSignIn, pollDeviceSignInOnce, type SignInType, startDirectSignIn, submitMediatedCode, } from './signin.js';
|
|
15
17
|
export { parseSse } from './sse.js';
|
|
16
18
|
export { defaultStatePath, StateStore } from './store.js';
|
|
19
|
+
export { excludedTasks, sendFeedback } from './task_coverage.js';
|
|
17
20
|
export { TokenClient } from './token_client.js';
|
|
18
21
|
export type * from './types.js';
|
|
19
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,YAAY,EACZ,aAAa,EACb,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,KAAK,UAAU,EACf,QAAQ,EACR,aAAa,EACb,2BAA2B,EAC3B,gBAAgB,EAChB,qBAAqB,EACrB,iCAAiC,EACjC,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,UAAU,EACV,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,KAAK,eAAe,EACpB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,UAAU,EACf,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,mBAAmB,YAAY,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { apiBaseUrl, callOpenApi, listApis, loadOpenApi, pickApi } from './api.js';
|
|
2
|
-
export {
|
|
2
|
+
export { authorizeBrowserJoin, browserJoinCode, browserSessionEndpoint } from './browser.js';
|
|
3
3
|
export { CompanyClient, PoppyAgent, throwForResponse, } from './company.js';
|
|
4
4
|
export { ConversationClient, newMessageId, poppyProtocol, } from './conversations.js';
|
|
5
|
-
export { authServerMetadataUrl, discover, HttpJsonCache,
|
|
5
|
+
export { authServerMetadataUrl, discover, HttpJsonCache, SUPPORTED_PROTOCOL_VERSIONS, validateMetadata, validatePoppyDocument, validateProtectedResourceMetadata, wellKnownUrlFor, } from './discovery.js';
|
|
6
6
|
export { DpopKey, htuOf } from './dpop.js';
|
|
7
7
|
export { ConversationError, DiscoveryError, OAuthError, PoppyError, ResourceAuthError, } from './errors.js';
|
|
8
8
|
export { PoppyHttp } from './http.js';
|
|
@@ -11,8 +11,11 @@ export { startIdentityServer, waitForRelayedCallback } from './identity_server.j
|
|
|
11
11
|
export { generateEs256Key } from './keys.js';
|
|
12
12
|
export { ask, DEFAULT_MODEL } from './llm.js';
|
|
13
13
|
export { connectMcp } from './mcp.js';
|
|
14
|
-
export {
|
|
14
|
+
export { createSafeFetch, isBlockedAddress, safeFetch } from './safe_fetch.js';
|
|
15
|
+
export { SESSION_JWT_TYP, signSessionJwt } from './session_jwt.js';
|
|
16
|
+
export { completeDirectSignIn, deviceSignIn, eligibleSignInTypes, mediatedExtension, mediatedSignIn, offeredSignInTypes, pollDeviceSignInOnce, startDirectSignIn, submitMediatedCode, } from './signin.js';
|
|
15
17
|
export { parseSse } from './sse.js';
|
|
16
18
|
export { defaultStatePath, StateStore } from './store.js';
|
|
19
|
+
export { excludedTasks, sendFeedback } from './task_coverage.js';
|
|
17
20
|
export { TokenClient } from './token_client.js';
|
|
18
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/poppy-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/poppy-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EACL,aAAa,EACb,UAAU,EAGV,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAElB,YAAY,EACZ,aAAa,GAEd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EAErB,QAAQ,EACR,aAAa,EACb,2BAA2B,EAC3B,gBAAgB,EAChB,qBAAqB,EACrB,iCAAiC,EACjC,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,UAAU,EACV,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAkB,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAsB,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EAEnB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAElB,oBAAoB,EAEpB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -9,7 +9,7 @@ function summarize(events) {
|
|
|
9
9
|
for (const ev of events) {
|
|
10
10
|
if (ev.type === 'message' && ev.message?.role !== 'user') {
|
|
11
11
|
out.push({
|
|
12
|
-
from: `company:${ev.message?.
|
|
12
|
+
from: `company:${ev.message?.author?.type}`,
|
|
13
13
|
text: ev.message?.text,
|
|
14
14
|
data: ev.message?.data,
|
|
15
15
|
});
|
|
@@ -109,7 +109,7 @@ export async function ask(company, task, opts) {
|
|
|
109
109
|
if (name === 'talk_to_company' && conv) {
|
|
110
110
|
const message = {
|
|
111
111
|
id: newMessageId(),
|
|
112
|
-
|
|
112
|
+
author: { type: 'agent' },
|
|
113
113
|
text: String(args.text ?? ''),
|
|
114
114
|
data: typeof args.data === 'object' && args.data
|
|
115
115
|
? args.data
|
|
@@ -126,13 +126,13 @@ export async function ask(company, task, opts) {
|
|
|
126
126
|
const { events, state } = await conv.collect(conversationId);
|
|
127
127
|
for (const ev of events) {
|
|
128
128
|
if (ev.type === 'message' && ev.message?.role !== 'user') {
|
|
129
|
-
opts.log(` company[${ev.message?.
|
|
129
|
+
opts.log(` company[${ev.message?.author?.type}]: ${ev.message?.text ?? ''}${ev.message?.data ? ` ${JSON.stringify(ev.message.data)}` : ''}`);
|
|
130
130
|
}
|
|
131
131
|
if (ev.type === 'user_requested') {
|
|
132
132
|
// 7.10: only the Personal Agent starts Direct Conversations; the user isn't here.
|
|
133
133
|
await conv.send(conversationId, {
|
|
134
134
|
id: newMessageId(),
|
|
135
|
-
|
|
135
|
+
author: { type: 'agent' },
|
|
136
136
|
text: 'The user is not available to talk right now.',
|
|
137
137
|
context: { user_available: false },
|
|
138
138
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/poppy-client/llm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAsB,MAAM,UAAU,CAAC;AAI1D,mGAAmG;AACnG,MAAM,CAAC,MAAM,aAAa,GAAG,4BAA4B,CAAC;AAC1D,MAAM,CAAC,MAAM,cAAc,GAAG,+CAA+C,CAAC;AA+B9E,SAAS,SAAS,CAAC,MAA2B;IAC5C,MAAM,GAAG,GAA8B,EAAE,CAAC;IAC1C,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YACzD,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/poppy-client/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,10 +7,9 @@ export interface McpConnection {
|
|
|
7
7
|
close(): Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Connects to a listed MCP server over Streamable HTTP
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* rejects the call with a {@link ResourceAuthError} carrying the needed `scope`.
|
|
10
|
+
* Connects to a listed MCP server over Streamable HTTP (section 7): the Session header on every
|
|
11
|
+
* request and, when signed in, a Bearer access token requested with `resource` set to the server's
|
|
12
|
+
* `url`. A challenge rejects the call with a {@link ResourceAuthError} naming the needed `scope`.
|
|
14
13
|
*/
|
|
15
14
|
export declare function connectMcp(company: CompanyClient, apiIndex?: number | undefined): Promise<McpConnection>;
|
|
16
15
|
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,aAAa,CAAC,CAiCxB"}
|
|
@@ -4,49 +4,37 @@ import { pickApi } from './api.js';
|
|
|
4
4
|
import { ResourceAuthError } from './errors.js';
|
|
5
5
|
import { wwwAuthError } from './util.js';
|
|
6
6
|
/**
|
|
7
|
-
* Connects to a listed MCP server over Streamable HTTP
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* rejects the call with a {@link ResourceAuthError} carrying the needed `scope`.
|
|
7
|
+
* Connects to a listed MCP server over Streamable HTTP (section 7): the Session header on every
|
|
8
|
+
* request and, when signed in, a Bearer access token requested with `resource` set to the server's
|
|
9
|
+
* `url`. A challenge rejects the call with a {@link ResourceAuthError} naming the needed `scope`.
|
|
11
10
|
*/
|
|
12
11
|
export async function connectMcp(company, apiIndex) {
|
|
13
12
|
const api = pickApi(company, 'mcp', apiIndex);
|
|
14
|
-
// `resource` MUST be the MCP server's `url` from poppy.json (4.3).
|
|
15
|
-
const resource = api.url;
|
|
16
|
-
let token = await company.bearerFor(resource);
|
|
17
13
|
const authedFetch = async (input, init) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
headers
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
(err.error === 'insufficient_scope' || err.error === 'sign_in_required')) {
|
|
41
|
-
await res.body?.cancel().catch(() => { });
|
|
42
|
-
throw new ResourceAuthError(err.error, {
|
|
43
|
-
status: 403,
|
|
44
|
-
description: err.description,
|
|
45
|
-
scope: err.scope,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
return res;
|
|
14
|
+
const headers = {};
|
|
15
|
+
new Headers(init?.headers).forEach((value, key) => {
|
|
16
|
+
headers[key] = value;
|
|
17
|
+
});
|
|
18
|
+
const res = await company.fetch(String(input), {
|
|
19
|
+
method: init?.method ?? 'GET',
|
|
20
|
+
headers,
|
|
21
|
+
...(typeof init?.body === 'string' ? { body: init.body } : {}),
|
|
22
|
+
...(init?.signal ? { signal: init.signal } : {}),
|
|
23
|
+
// `resource` MUST be the MCP server's `url` from poppy.json, and Bearer is MCP's baseline (7).
|
|
24
|
+
resource: api.url,
|
|
25
|
+
bearer: true,
|
|
26
|
+
});
|
|
27
|
+
const challenge = res.headers.get('www-authenticate');
|
|
28
|
+
if ((res.status === 401 || res.status === 403) && challenge) {
|
|
29
|
+
const err = wwwAuthError(challenge);
|
|
30
|
+
await res.body?.cancel().catch(() => { });
|
|
31
|
+
throw new ResourceAuthError(err.error ?? 'insufficient_scope', {
|
|
32
|
+
status: res.status,
|
|
33
|
+
description: err.description,
|
|
34
|
+
scope: err.scope,
|
|
35
|
+
});
|
|
49
36
|
}
|
|
37
|
+
return res;
|
|
50
38
|
};
|
|
51
39
|
const transport = new StreamableHTTPClientTransport(new URL(api.url), { fetch: authedFetch });
|
|
52
40
|
const client = new Client({ name: 'poppy-agent', version: '0.0.0' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/poppy-client/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAQzC
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/poppy-client/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAQzC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAsB,EACtB,QAA6B;IAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,KAAK,EAAE,KAAmB,EAAE,IAAkB,EAAqB,EAAE;QACvF,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAChD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC7C,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK;YAC7B,OAAO;YACP,GAAG,CAAC,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,+FAA+F;YAC/F,QAAQ,EAAE,GAAG,CAAC,GAAG;YACjB,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,IAAI,oBAAoB,EAAE;gBAC7D,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;aACjB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACrE,+FAA+F;IAC/F,MAAM,MAAM,CAAC,OAAO,CAAC,SAAwD,CAAC,CAAC;IAC/E,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type LookupAddress } from 'node:dns';
|
|
2
|
+
import type { FetchLike } from './util.js';
|
|
3
|
+
/**
|
|
4
|
+
* `fetch` for URLs a Company gave (section 3): HTTPS only, and never to a loopback, private or
|
|
5
|
+
* link-local address. The address is checked in the socket's own `lookup`, so what was checked is
|
|
6
|
+
* what gets connected to, with no window for DNS rebinding, and each request opens its own
|
|
7
|
+
* connection. Every redirect hop goes through the same check.
|
|
8
|
+
*/
|
|
9
|
+
export type LookupFn = (hostname: string, options: {
|
|
10
|
+
all: true;
|
|
11
|
+
}, callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void) => void;
|
|
12
|
+
export interface SafeFetchOptions {
|
|
13
|
+
/** Name resolution, for tests. Default: `dns.lookup`. */
|
|
14
|
+
lookup?: LookupFn | undefined;
|
|
15
|
+
/** Address policy, for tests. Default: {@link isBlockedAddress}. */
|
|
16
|
+
isBlocked?: ((address: string) => boolean) | undefined;
|
|
17
|
+
connectTimeoutMs?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Whether this client must not connect to `ip`. Anything that isn't an IP counts as blocked. */
|
|
20
|
+
export declare function isBlockedAddress(ip: string): boolean;
|
|
21
|
+
/** A `fetch` that refuses internal addresses (section 3). */
|
|
22
|
+
export declare function createSafeFetch(opts?: SafeFetchOptions): FetchLike;
|
|
23
|
+
/** The default `fetch` of this client, unless `insecureDev` asked for the plain one. */
|
|
24
|
+
export declare const safeFetch: FetchLike;
|
|
25
|
+
/**
|
|
26
|
+
* The `fetch` for a Company's URLs. `insecureDev` is the explicit opt-in that reaches local servers.
|
|
27
|
+
* A caller that injects its own `fetch` takes over this check.
|
|
28
|
+
*/
|
|
29
|
+
export declare function companyFetch(insecureDev: boolean | undefined): FetchLike;
|
|
30
|
+
//# sourceMappingURL=safe_fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe_fetch.d.ts","sourceRoot":"","sources":["../../../src/poppy-client/safe_fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAMnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG,CACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,EACtB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,IAAI,KAC9E,IAAI,CAAC;AAEV,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,oEAAoE;IACpE,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IACvD,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AA+CD,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAkCpD;AAwFD,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,IAAI,GAAE,gBAAqB,GAAG,SAAS,CAiCtE;AAED,wFAAwF;AACxF,eAAO,MAAM,SAAS,EAAE,SAA6B,CAAC;AAItD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAExE"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { lookup as dnsLookup } from 'node:dns';
|
|
2
|
+
import { request as httpsRequest } from 'node:https';
|
|
3
|
+
import { isIP } from 'node:net';
|
|
4
|
+
import { Readable } from 'node:stream';
|
|
5
|
+
import { PoppyError } from './errors.js';
|
|
6
|
+
const MAX_REDIRECTS = 5;
|
|
7
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = 15_000;
|
|
8
|
+
/** Headers that don't follow a redirect (section 3). */
|
|
9
|
+
const SECRET_HEADERS = ['authorization', 'cookie', 'dpop', 'poppy-session'];
|
|
10
|
+
const BLOCKED_V4 = [
|
|
11
|
+
['0.0.0.0', 8],
|
|
12
|
+
['10.0.0.0', 8],
|
|
13
|
+
['100.64.0.0', 10],
|
|
14
|
+
['127.0.0.0', 8],
|
|
15
|
+
['169.254.0.0', 16],
|
|
16
|
+
['172.16.0.0', 12],
|
|
17
|
+
['192.0.0.0', 24],
|
|
18
|
+
['192.0.2.0', 24],
|
|
19
|
+
['192.88.99.0', 24],
|
|
20
|
+
['192.168.0.0', 16],
|
|
21
|
+
['198.18.0.0', 15],
|
|
22
|
+
['198.51.100.0', 24],
|
|
23
|
+
['203.0.113.0', 24],
|
|
24
|
+
['224.0.0.0', 4],
|
|
25
|
+
['240.0.0.0', 4],
|
|
26
|
+
];
|
|
27
|
+
function ipv4ToInt(ip) {
|
|
28
|
+
return ip.split('.').reduce((acc, part) => (acc << 8) + Number(part), 0) >>> 0;
|
|
29
|
+
}
|
|
30
|
+
/** An IPv6 address as 8 groups of 16 bits. */
|
|
31
|
+
function ipv6Groups(ip) {
|
|
32
|
+
let addr = ip.toLowerCase().split('%')[0] ?? '';
|
|
33
|
+
const v4 = /(\d+\.\d+\.\d+\.\d+)$/.exec(addr)?.[1];
|
|
34
|
+
if (v4) {
|
|
35
|
+
const n = ipv4ToInt(v4);
|
|
36
|
+
addr = `${addr.slice(0, -v4.length)}${(n >>> 16).toString(16)}:${(n & 0xffff).toString(16)}`;
|
|
37
|
+
}
|
|
38
|
+
const [head, tail] = addr.split('::');
|
|
39
|
+
const h = head ? head.split(':') : [];
|
|
40
|
+
const t = tail ? tail.split(':') : [];
|
|
41
|
+
const fill = addr.includes('::') ? 8 - h.length - t.length : 0;
|
|
42
|
+
const groups = [...h, ...Array(Math.max(fill, 0)).fill('0'), ...t].map((g) => Number.parseInt(g || '0', 16));
|
|
43
|
+
return groups.length === 8 && groups.every((g) => g >= 0 && g <= 0xffff) ? groups : null;
|
|
44
|
+
}
|
|
45
|
+
/** Whether this client must not connect to `ip`. Anything that isn't an IP counts as blocked. */
|
|
46
|
+
export function isBlockedAddress(ip) {
|
|
47
|
+
const family = isIP(ip);
|
|
48
|
+
if (family === 4) {
|
|
49
|
+
const n = ipv4ToInt(ip);
|
|
50
|
+
return BLOCKED_V4.some(([base, bits]) => {
|
|
51
|
+
const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0;
|
|
52
|
+
return (n & mask) >>> 0 === (ipv4ToInt(base) & mask) >>> 0;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (family !== 6)
|
|
56
|
+
return true;
|
|
57
|
+
const g = ipv6Groups(ip);
|
|
58
|
+
if (!g)
|
|
59
|
+
return true;
|
|
60
|
+
const [a = 0, b = 0, c = 0] = g;
|
|
61
|
+
const g5 = g[5] ?? 0;
|
|
62
|
+
const g6 = g[6] ?? 0;
|
|
63
|
+
const g7 = g[7] ?? 0;
|
|
64
|
+
if (g.every((x) => x === 0))
|
|
65
|
+
return true; // ::
|
|
66
|
+
if (g.slice(0, 7).every((x) => x === 0) && g7 === 1)
|
|
67
|
+
return true; // ::1
|
|
68
|
+
// IPv4-mapped and IPv4-compatible: the IPv4 address decides.
|
|
69
|
+
// IPv4-translated (::ffff:0:a.b.c.d) and NAT64 (64:ff9b::a.b.c.d) also reach an IPv4 address.
|
|
70
|
+
const translated = g.slice(0, 4).every((x) => x === 0) && g[4] === 0xffff && g5 === 0;
|
|
71
|
+
const nat64 = g[0] === 0x64 && g[1] === 0xff9b && g.slice(2, 6).every((x) => x === 0);
|
|
72
|
+
if (translated || nat64)
|
|
73
|
+
return isBlockedAddress(`${g6 >> 8}.${g6 & 255}.${g7 >> 8}.${g7 & 255}`);
|
|
74
|
+
if (g.slice(0, 5).every((x) => x === 0) && (g5 === 0xffff || g5 === 0)) {
|
|
75
|
+
return isBlockedAddress(`${g6 >> 8}.${g6 & 255}.${g7 >> 8}.${g7 & 255}`);
|
|
76
|
+
}
|
|
77
|
+
if ((a & 0xfe00) === 0xfc00)
|
|
78
|
+
return true; // fc00::/7, unique local
|
|
79
|
+
if ((a & 0xffc0) === 0xfe80)
|
|
80
|
+
return true; // fe80::/10, link-local
|
|
81
|
+
if ((a & 0xffc0) === 0xfec0)
|
|
82
|
+
return true; // fec0::/10, site-local
|
|
83
|
+
if ((a & 0xff00) === 0xff00)
|
|
84
|
+
return true; // ff00::/8, multicast
|
|
85
|
+
if (a === 0x2001 && b === 0x0db8)
|
|
86
|
+
return true; // 2001:db8::/32, documentation
|
|
87
|
+
if (a === 0x64 && b === 0xff9b)
|
|
88
|
+
return true; // 64:ff9b::/96, NAT64
|
|
89
|
+
if (a === 0x2002)
|
|
90
|
+
return isBlockedAddress(`${b >> 8}.${b & 255}.${c >> 8}.${c & 255}`); // 6to4
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
function refused(message) {
|
|
94
|
+
return new PoppyError('blocked_address', message);
|
|
95
|
+
}
|
|
96
|
+
/** One request, one connection, the address checked in the socket's `lookup`. */
|
|
97
|
+
function requestOnce(url, init, opts) {
|
|
98
|
+
const isBlocked = opts.isBlocked ?? isBlockedAddress;
|
|
99
|
+
const resolve = opts.lookup ?? dnsLookup;
|
|
100
|
+
const host = url.hostname.replace(/^\[|\]$/g, '');
|
|
101
|
+
if (url.protocol !== 'https:')
|
|
102
|
+
return Promise.reject(refused(`${url.protocol} is not HTTPS`));
|
|
103
|
+
if (url.username || url.password)
|
|
104
|
+
return Promise.reject(refused('credentials in the URL'));
|
|
105
|
+
if (isIP(host) && isBlocked(host))
|
|
106
|
+
return Promise.reject(refused(`blocked address ${host}`));
|
|
107
|
+
const lookup = (hostname, options, callback) => {
|
|
108
|
+
resolve(hostname, { all: true }, (err, list) => {
|
|
109
|
+
if (err)
|
|
110
|
+
return callback(err);
|
|
111
|
+
const addresses = list ?? [];
|
|
112
|
+
const first = addresses[0];
|
|
113
|
+
if (!first)
|
|
114
|
+
return callback(refused(`no address for ${hostname}`));
|
|
115
|
+
// Any internal address refuses the name: the connection may try them all.
|
|
116
|
+
const bad = addresses.find((a) => isBlocked(a.address));
|
|
117
|
+
if (bad)
|
|
118
|
+
return callback(refused(`${hostname} resolves to a blocked address`));
|
|
119
|
+
if (options?.all)
|
|
120
|
+
return callback(null, addresses);
|
|
121
|
+
return callback(null, first.address, first.family);
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
return new Promise((done, reject) => {
|
|
125
|
+
const headers = {};
|
|
126
|
+
init.headers.forEach((value, key) => {
|
|
127
|
+
headers[key] = value;
|
|
128
|
+
});
|
|
129
|
+
const req = httpsRequest(url, {
|
|
130
|
+
method: init.method,
|
|
131
|
+
headers,
|
|
132
|
+
agent: false,
|
|
133
|
+
lookup: lookup,
|
|
134
|
+
...(init.signal ? { signal: init.signal } : {}),
|
|
135
|
+
}, done);
|
|
136
|
+
const timer = setTimeout(() => req.destroy(new PoppyError('connect_timeout', `timed out connecting to ${url.host}`)), opts.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS);
|
|
137
|
+
timer.unref();
|
|
138
|
+
req.once('socket', (socket) => {
|
|
139
|
+
socket.once('secureConnect', () => clearTimeout(timer));
|
|
140
|
+
});
|
|
141
|
+
req.once('close', () => clearTimeout(timer));
|
|
142
|
+
req.once('error', reject);
|
|
143
|
+
req.end(init.body);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function toResponse(res, url) {
|
|
147
|
+
const headers = new Headers();
|
|
148
|
+
for (let i = 0; i + 1 < res.rawHeaders.length; i += 2) {
|
|
149
|
+
headers.append(res.rawHeaders[i], res.rawHeaders[i + 1]);
|
|
150
|
+
}
|
|
151
|
+
const status = res.statusCode ?? 502;
|
|
152
|
+
const empty = status === 204 || status === 205 || status === 304;
|
|
153
|
+
if (empty)
|
|
154
|
+
res.resume();
|
|
155
|
+
const response = new Response(empty ? null : Readable.toWeb(res), { status, headers });
|
|
156
|
+
Object.defineProperty(response, 'url', { value: url.toString() });
|
|
157
|
+
return response;
|
|
158
|
+
}
|
|
159
|
+
/** A `fetch` that refuses internal addresses (section 3). */
|
|
160
|
+
export function createSafeFetch(opts = {}) {
|
|
161
|
+
return async (input, init = {}) => {
|
|
162
|
+
const request = input instanceof Request ? input : undefined;
|
|
163
|
+
let url = new URL(request ? request.url : input.toString());
|
|
164
|
+
let method = (init.method ?? request?.method ?? 'GET').toUpperCase();
|
|
165
|
+
const headers = new Headers(init.headers ?? request?.headers);
|
|
166
|
+
let body;
|
|
167
|
+
const raw = init.body ?? undefined;
|
|
168
|
+
if (typeof raw === 'string')
|
|
169
|
+
body = raw;
|
|
170
|
+
else if (raw !== undefined)
|
|
171
|
+
body = await new Response(raw).text();
|
|
172
|
+
else if (request?.body)
|
|
173
|
+
body = await request.text();
|
|
174
|
+
const signal = init.signal ?? request?.signal ?? null;
|
|
175
|
+
const mode = init.redirect ?? request?.redirect ?? 'follow';
|
|
176
|
+
for (let hop = 0;; hop++) {
|
|
177
|
+
const res = await requestOnce(url, { method, headers, body, signal }, opts);
|
|
178
|
+
const location = res.headers.location;
|
|
179
|
+
const isRedirect = (res.statusCode ?? 0) >= 300 && (res.statusCode ?? 0) < 400 && location;
|
|
180
|
+
if (!isRedirect || mode === 'manual')
|
|
181
|
+
return toResponse(res, url);
|
|
182
|
+
res.resume();
|
|
183
|
+
if (mode === 'error')
|
|
184
|
+
throw new TypeError(`unexpected redirect from ${url}`);
|
|
185
|
+
if (hop >= MAX_REDIRECTS)
|
|
186
|
+
throw new TypeError(`too many redirects from ${url}`);
|
|
187
|
+
url = new URL(location, url);
|
|
188
|
+
for (const name of SECRET_HEADERS)
|
|
189
|
+
headers.delete(name);
|
|
190
|
+
const status = res.statusCode;
|
|
191
|
+
if (status === 303 || ((status === 301 || status === 302) && method === 'POST')) {
|
|
192
|
+
method = 'GET';
|
|
193
|
+
body = undefined;
|
|
194
|
+
headers.delete('content-type');
|
|
195
|
+
headers.delete('content-length');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** The default `fetch` of this client, unless `insecureDev` asked for the plain one. */
|
|
201
|
+
export const safeFetch = createSafeFetch();
|
|
202
|
+
const plainFetch = (input, init) => globalThis.fetch(input, init);
|
|
203
|
+
/**
|
|
204
|
+
* The `fetch` for a Company's URLs. `insecureDev` is the explicit opt-in that reaches local servers.
|
|
205
|
+
* A caller that injects its own `fetch` takes over this check.
|
|
206
|
+
*/
|
|
207
|
+
export function companyFetch(insecureDev) {
|
|
208
|
+
return insecureDev ? plainFetch : safeFetch;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=safe_fetch.js.map
|