@aeolus-fleet/gateway 0.0.0 → 0.28.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.
Files changed (179) hide show
  1. package/README.md +11 -10
  2. package/dist/adapters/crypto/page-sessions.d.ts +15 -0
  3. package/dist/adapters/crypto/page-sessions.js +40 -0
  4. package/dist/adapters/crypto/page-sessions.js.map +1 -0
  5. package/dist/adapters/crypto/request-ids.d.ts +1 -1
  6. package/dist/adapters/crypto/request-ids.js +2 -9
  7. package/dist/adapters/crypto/request-ids.js.map +1 -1
  8. package/dist/adapters/crypto/sign-in-seals.d.ts +1 -1
  9. package/dist/adapters/crypto/sign-in-seals.js +7 -9
  10. package/dist/adapters/crypto/sign-in-seals.js.map +1 -1
  11. package/dist/adapters/fleet/actor-door.d.ts +20 -0
  12. package/dist/adapters/fleet/actor-door.js +75 -0
  13. package/dist/adapters/fleet/actor-door.js.map +1 -0
  14. package/dist/adapters/fleet/core-version.d.ts +8 -8
  15. package/dist/adapters/fleet/core-version.js +6 -47
  16. package/dist/adapters/fleet/core-version.js.map +1 -1
  17. package/dist/adapters/fleet/fleet-network.js +7 -17
  18. package/dist/adapters/fleet/fleet-network.js.map +1 -1
  19. package/dist/adapters/fleet/logged-verified-facts.d.ts +13 -0
  20. package/dist/adapters/fleet/logged-verified-facts.js +18 -0
  21. package/dist/adapters/fleet/logged-verified-facts.js.map +1 -0
  22. package/dist/adapters/fleet/proxy-ship-reads.d.ts +7 -0
  23. package/dist/adapters/fleet/proxy-ship-reads.js +24 -0
  24. package/dist/adapters/fleet/proxy-ship-reads.js.map +1 -0
  25. package/dist/adapters/fleet/proxy-ships-as-actor.d.ts +3 -0
  26. package/dist/adapters/fleet/proxy-ships-as-actor.js +25 -0
  27. package/dist/adapters/fleet/proxy-ships-as-actor.js.map +1 -0
  28. package/dist/adapters/fleet/rest-fleet-door.d.ts +2 -2
  29. package/dist/adapters/fleet/rest-fleet-door.js +23 -7
  30. package/dist/adapters/fleet/rest-fleet-door.js.map +1 -1
  31. package/dist/adapters/http/add-server-page.d.ts +7 -0
  32. package/dist/adapters/http/add-server-page.js +175 -0
  33. package/dist/adapters/http/add-server-page.js.map +1 -0
  34. package/dist/adapters/http/delivery-page.d.ts +24 -0
  35. package/dist/adapters/http/delivery-page.js +115 -0
  36. package/dist/adapters/http/delivery-page.js.map +1 -0
  37. package/dist/adapters/http/front-door.d.ts +8 -0
  38. package/dist/adapters/http/front-door.js +19 -0
  39. package/dist/adapters/http/front-door.js.map +1 -0
  40. package/dist/adapters/http/oauth-routes.d.ts +15 -3
  41. package/dist/adapters/http/oauth-routes.js +33 -1
  42. package/dist/adapters/http/oauth-routes.js.map +1 -1
  43. package/dist/adapters/http/outside-parties-page.d.ts +29 -2
  44. package/dist/adapters/http/outside-parties-page.js +15 -11
  45. package/dist/adapters/http/outside-parties-page.js.map +1 -1
  46. package/dist/adapters/http/outside-party-page.d.ts +7 -0
  47. package/dist/adapters/http/outside-party-page.js +212 -0
  48. package/dist/adapters/http/outside-party-page.js.map +1 -0
  49. package/dist/adapters/http/overview-page.d.ts +2 -1
  50. package/dist/adapters/http/overview-page.js +79 -36
  51. package/dist/adapters/http/overview-page.js.map +1 -1
  52. package/dist/adapters/http/parties-page.d.ts +2 -1
  53. package/dist/adapters/http/parties-page.js +8 -10
  54. package/dist/adapters/http/parties-page.js.map +1 -1
  55. package/dist/adapters/http/scope-rows.d.ts +10 -0
  56. package/dist/adapters/http/scope-rows.js +30 -0
  57. package/dist/adapters/http/scope-rows.js.map +1 -0
  58. package/dist/adapters/http/signal.d.ts +10 -1
  59. package/dist/adapters/http/signal.js +50 -7
  60. package/dist/adapters/http/signal.js.map +1 -1
  61. package/dist/adapters/pagasae/pagasae-client.js +7 -9
  62. package/dist/adapters/pagasae/pagasae-client.js.map +1 -1
  63. package/dist/adapters/prisma/account-grants.js +2 -2
  64. package/dist/adapters/prisma/account-grants.js.map +1 -1
  65. package/dist/adapters/prisma/client-calls.js +9 -0
  66. package/dist/adapters/prisma/client-calls.js.map +1 -1
  67. package/dist/adapters/prisma/generated/internal/class.js +4 -4
  68. package/dist/adapters/prisma/generated/internal/class.js.map +1 -1
  69. package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +1 -1
  70. package/dist/adapters/prisma/generated/internal/prismaNamespace.js +1 -1
  71. package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -1
  72. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +1 -1
  73. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +1 -1
  74. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
  75. package/dist/adapters/prisma/generated/models/AccountGrant.d.ts +33 -1
  76. package/dist/adapters/prisma/generated/models/ClientCall.d.ts +14 -14
  77. package/dist/adapters/prisma/generated/models/Party.d.ts +1 -29
  78. package/dist/adapters/prisma/oauth-stores.js +3 -0
  79. package/dist/adapters/prisma/oauth-stores.js.map +1 -1
  80. package/dist/adapters/prisma/party-store.js +0 -2
  81. package/dist/adapters/prisma/party-store.js.map +1 -1
  82. package/dist/adapters/prisma/pending-requests.js +7 -1
  83. package/dist/adapters/prisma/pending-requests.js.map +1 -1
  84. package/dist/adapters/trpc/router.d.ts +210 -12
  85. package/dist/adapters/trpc/router.js +159 -7
  86. package/dist/adapters/trpc/router.js.map +1 -1
  87. package/dist/app.js +67 -19
  88. package/dist/app.js.map +1 -1
  89. package/dist/core/actors/authenticate-actor.d.ts +21 -5
  90. package/dist/core/actors/authenticate-actor.js +14 -2
  91. package/dist/core/actors/authenticate-actor.js.map +1 -1
  92. package/dist/core/actors/credential-of.d.ts +27 -0
  93. package/dist/core/actors/credential-of.js +25 -0
  94. package/dist/core/actors/credential-of.js.map +1 -0
  95. package/dist/core/connection/connect.js +5 -4
  96. package/dist/core/connection/connect.js.map +1 -1
  97. package/dist/core/connection/ports.d.ts +6 -1
  98. package/dist/core/mcp-in/call-tool.d.ts +6 -6
  99. package/dist/core/mcp-in/call-tool.js +3 -3
  100. package/dist/core/mcp-in/call-tool.js.map +1 -1
  101. package/dist/core/mcp-in/client-call.d.ts +2 -2
  102. package/dist/core/mcp-in/client-call.js +2 -2
  103. package/dist/core/mcp-in/client-call.js.map +1 -1
  104. package/dist/core/mcp-in/collect-replies.d.ts +4 -11
  105. package/dist/core/mcp-in/collect-replies.js +52 -30
  106. package/dist/core/mcp-in/collect-replies.js.map +1 -1
  107. package/dist/core/mcp-in/list-tools.d.ts +4 -0
  108. package/dist/core/mcp-in/list-tools.js +1 -1
  109. package/dist/core/mcp-in/list-tools.js.map +1 -1
  110. package/dist/core/mcp-in/ports.d.ts +24 -1
  111. package/dist/core/mcp-out/hand-call.d.ts +2 -0
  112. package/dist/core/mcp-out/hand-call.js +4 -2
  113. package/dist/core/mcp-out/hand-call.js.map +1 -1
  114. package/dist/core/mcp-out/state-party.d.ts +2 -1
  115. package/dist/core/mcp-out/state-party.js +1 -1
  116. package/dist/core/mcp-out/state-party.js.map +1 -1
  117. package/dist/core/mcp-out/statement.d.ts +10 -0
  118. package/dist/core/mcp-out/statement.js +7 -5
  119. package/dist/core/mcp-out/statement.js.map +1 -1
  120. package/dist/core/oauth/ports.d.ts +2 -0
  121. package/dist/core/oauth/read-authorization.js +2 -2
  122. package/dist/core/oauth/read-authorization.js.map +1 -1
  123. package/dist/core/oauth/redirect-uri.d.ts +7 -0
  124. package/dist/core/oauth/redirect-uri.js +23 -0
  125. package/dist/core/oauth/redirect-uri.js.map +1 -1
  126. package/dist/core/outside-parties/ports.d.ts +1 -5
  127. package/dist/core/outside-parties/set-outside-parties.d.ts +5 -3
  128. package/dist/core/outside-parties/set-outside-parties.js +6 -2
  129. package/dist/core/outside-parties/set-outside-parties.js.map +1 -1
  130. package/dist/core/parties/approve-party.js +24 -8
  131. package/dist/core/parties/approve-party.js.map +1 -1
  132. package/dist/core/parties/change-party.d.ts +42 -0
  133. package/dist/core/parties/change-party.js +49 -0
  134. package/dist/core/parties/change-party.js.map +1 -0
  135. package/dist/core/parties/check-server.d.ts +24 -0
  136. package/dist/core/parties/check-server.js +21 -0
  137. package/dist/core/parties/check-server.js.map +1 -0
  138. package/dist/core/parties/list-parties.d.ts +28 -7
  139. package/dist/core/parties/list-parties.js +35 -4
  140. package/dist/core/parties/list-parties.js.map +1 -1
  141. package/dist/core/parties/party.d.ts +12 -6
  142. package/dist/core/parties/party.js +23 -1
  143. package/dist/core/parties/party.js.map +1 -1
  144. package/dist/core/parties/ports.d.ts +36 -1
  145. package/dist/core/parties/read-party-tools.d.ts +22 -0
  146. package/dist/core/parties/read-party-tools.js +22 -0
  147. package/dist/core/parties/read-party-tools.js.map +1 -0
  148. package/dist/core/parties/retire-party.d.ts +29 -0
  149. package/dist/core/parties/retire-party.js +43 -0
  150. package/dist/core/parties/retire-party.js.map +1 -0
  151. package/dist/core/parties/shown-party.d.ts +8 -2
  152. package/dist/core/parties/shown-party.js +3 -3
  153. package/dist/core/parties/shown-party.js.map +1 -1
  154. package/dist/core/requests/decide-request.js +9 -1
  155. package/dist/core/requests/decide-request.js.map +1 -1
  156. package/dist/core/requests/list-mine.d.ts +16 -0
  157. package/dist/core/requests/list-mine.js +20 -0
  158. package/dist/core/requests/list-mine.js.map +1 -0
  159. package/dist/core/requests/ports.d.ts +5 -0
  160. package/dist/core/shared/errors.d.ts +1 -1
  161. package/dist/core/shared/errors.js.map +1 -1
  162. package/dist/core/sign-in/account-token.d.ts +8 -4
  163. package/dist/core/sign-in/account-token.js +4 -4
  164. package/dist/core/sign-in/account-token.js.map +1 -1
  165. package/dist/core/sign-in/complete-sign-in.d.ts +15 -4
  166. package/dist/core/sign-in/complete-sign-in.js +27 -4
  167. package/dist/core/sign-in/complete-sign-in.js.map +1 -1
  168. package/dist/core/sign-in/ports.d.ts +37 -7
  169. package/dist/core/sign-in/sign-out.d.ts +10 -0
  170. package/dist/core/sign-in/sign-out.js +9 -0
  171. package/dist/core/sign-in/sign-out.js.map +1 -0
  172. package/dist/core/sign-in/start-page-sign-in.d.ts +25 -0
  173. package/dist/core/sign-in/start-page-sign-in.js +30 -0
  174. package/dist/core/sign-in/start-page-sign-in.js.map +1 -0
  175. package/package.json +3 -3
  176. package/src/adapters/prisma/migrations/20261020200000_account_grant_scopes/migration.sql +2 -0
  177. package/src/adapters/prisma/migrations/20261020210000_party_owner_from_fleet/migration.sql +2 -0
  178. package/src/adapters/prisma/migrations/20261020220000_client_call_deadline_optional/migration.sql +2 -0
  179. package/src/adapters/prisma/schema.prisma +3 -2
@@ -1,4 +1,5 @@
1
- import type { FleetId, ShipId } from '@aeolus-fleet/common';
1
+ import type { FleetId, ShipId, VerifiedFact } from '@aeolus-fleet/common';
2
+ import type { ActorCredential } from '../actors/credential-of.js';
2
3
  import type { FleetRefusal } from '../connection/ports.js';
3
4
  import type { Result } from '../shared/result.js';
4
5
  import type { Party } from './party.js';
@@ -36,4 +37,38 @@ export interface ProxyShipDoor {
36
37
  }): Promise<Result<{
37
38
  crewToken: string;
38
39
  }, FleetRefusal>>;
40
+ /** Sets the gateway's facts about the proxy ship whole (fleet.setVerifiedFacts, fleet:verify, decision 0059). */
41
+ setVerifiedFacts(crewToken: string, written: {
42
+ shipId: ShipId;
43
+ facts: readonly VerifiedFact[];
44
+ }): Promise<Result<undefined, FleetRefusal>>;
45
+ }
46
+ /** Outbound port: the fleet's calls on a party's proxy ship made as the actor (decision 0057), so the fleet checks its scopes and reach. */
47
+ export interface ProxyShipsAsActor {
48
+ /** Retires the proxy ship (fleet.retire); a ship retired already is refused with CONFLICT. */
49
+ retire(as: ActorCredential, ship: {
50
+ shipId: ShipId;
51
+ }): Promise<Result<undefined, FleetRefusal>>;
52
+ /** Sets the proxy ship's owner (fleet.setOwner, fleet:owner). */
53
+ setOwner(as: ActorCredential, ship: {
54
+ shipId: ShipId;
55
+ ownerShipId: ShipId;
56
+ }): Promise<Result<undefined, FleetRefusal>>;
57
+ /** Grants and revokes the proxy ship's scopes (fleet.grantScopes, scopes:grant): every scope it holds now. */
58
+ grantScopes(as: ActorCredential, change: {
59
+ shipId: ShipId;
60
+ grant: readonly string[];
61
+ revoke: readonly string[];
62
+ }): Promise<Result<{
63
+ scopes: string[];
64
+ }, FleetRefusal>>;
65
+ }
66
+ /** Outbound port: what the fleet holds for a proxy ship, read as the actor (fleet:read): its owner and scopes, neither outside the actor's read reach. */
67
+ export interface ProxyShipReads {
68
+ read(as: ActorCredential, ship: {
69
+ shipId: ShipId;
70
+ }): Promise<Result<{
71
+ ownerShipId: ShipId | null;
72
+ scopes: string[] | null;
73
+ }, FleetRefusal>>;
39
74
  }
@@ -0,0 +1,22 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import type { McpServers } from '../mcp-out/ports.js';
3
+ import { type DomainError } from '../shared/errors.js';
4
+ import { type Result } from '../shared/result.js';
5
+ import type { CheckedTool } from './check-server.js';
6
+ import type { PartyStore } from './ports.js';
7
+ export type ReadPartyTools = (party: {
8
+ fleetId: FleetId;
9
+ name: string;
10
+ }) => Promise<Result<{
11
+ tools: CheckedTool[];
12
+ }, DomainError<'NO_SUCH_PARTY' | 'SERVER_UNREACHABLE'>>>;
13
+ /**
14
+ * Use case: an outside MCP server's tools, as the server lists them now,
15
+ * asked with the credential the gateway keeps for it. It keeps nothing:
16
+ * the proxy ship's statement in the fleet is where the tools live, and
17
+ * core does not answer a statement to a reader yet, so the server is asked.
18
+ */
19
+ export declare function createReadPartyTools(deps: {
20
+ parties: PartyStore;
21
+ servers: McpServers;
22
+ }): ReadPartyTools;
@@ -0,0 +1,22 @@
1
+ import { refuse } from '../shared/errors.js';
2
+ import { ok } from '../shared/result.js';
3
+ /**
4
+ * Use case: an outside MCP server's tools, as the server lists them now,
5
+ * asked with the credential the gateway keeps for it. It keeps nothing:
6
+ * the proxy ship's statement in the fleet is where the tools live, and
7
+ * core does not answer a statement to a reader yet, so the server is asked.
8
+ */
9
+ export function createReadPartyTools(deps) {
10
+ return async ({ fleetId, name }) => {
11
+ const party = await deps.parties.find(fleetId, name);
12
+ if (party?.kind !== 'mcpServer') {
13
+ return refuse('NO_SUCH_PARTY', `There is no outside MCP server ${name}`);
14
+ }
15
+ const listed = await deps.servers.listTools({ url: party.url, credential: party.credential });
16
+ if (!listed.isOk) {
17
+ return refuse('SERVER_UNREACHABLE', `The MCP server of ${name} could not be listed: ${listed.error.reason}`);
18
+ }
19
+ return ok({ tools: listed.value.map(({ name: tool, description }) => ({ name: tool, ...(description === undefined ? {} : { description }) })) });
20
+ };
21
+ }
22
+ //# sourceMappingURL=read-party-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-party-tools.js","sourceRoot":"","sources":["../../../src/core/parties/read-party-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAMtD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAkD;IACrF,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,OAAO,MAAM,CAAC,eAAe,EAAE,kCAAkC,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC,oBAAoB,EAAE,qBAAqB,IAAI,yBAAyB,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/G,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACnJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { Actor } from '../actors/authenticate-actor.js';
2
+ import type { ActorCredential, CredentialOf } from '../actors/credential-of.js';
3
+ import type { IssuedTokens } from '../oauth/ports.js';
4
+ import { type DomainError } from '../shared/errors.js';
5
+ import { type Result } from '../shared/result.js';
6
+ import type { PartyStore, ProxyShipsAsActor } from './ports.js';
7
+ /** The scope that retires an outside party, as it retires any ship (decision 0056). */
8
+ export declare const RETIRING_SCOPE = "fleet:manage";
9
+ export type RetirePartyRefusal = DomainError<'NOT_A_MANAGER' | 'NO_SUCH_PARTY' | 'RETIRE_REFUSED' | 'FLEET_UNAVAILABLE' | 'NOT_AN_ACTOR'>;
10
+ export type RetireParty = (input: {
11
+ actor: Actor;
12
+ as: ActorCredential;
13
+ name: string;
14
+ }) => Promise<Result<undefined, RetirePartyRefusal>>;
15
+ /**
16
+ * Use case: an actor holding fleet:manage retires an outside party (decision
17
+ * 0056). Its proxy ship is retired in the fleet as the actor, so the fleet
18
+ * checks its manage reach, and only then does the gateway forget the party
19
+ * and revoke its client's tokens; its worker ends as the fleet ends the
20
+ * proxy ship's crew. A proxy ship retired already is retired. A party whose
21
+ * ship the gateway never learned asks the fleet nothing. Adding it again is
22
+ * a new request.
23
+ */
24
+ export declare function createRetireParty(deps: {
25
+ parties: PartyStore;
26
+ fleet: ProxyShipsAsActor;
27
+ tokens: Pick<IssuedTokens, 'revokeParty'>;
28
+ credentialOf: CredentialOf;
29
+ }): RetireParty;
@@ -0,0 +1,43 @@
1
+ import { refuse } from '../shared/errors.js';
2
+ import { ok } from '../shared/result.js';
3
+ /** The scope that retires an outside party, as it retires any ship (decision 0056). */
4
+ export const RETIRING_SCOPE = 'fleet:manage';
5
+ /** The fleet's code for a ship retired already: the only conflict a retire answers. */
6
+ const RETIRED_ALREADY = 'CONFLICT';
7
+ /**
8
+ * Use case: an actor holding fleet:manage retires an outside party (decision
9
+ * 0056). Its proxy ship is retired in the fleet as the actor, so the fleet
10
+ * checks its manage reach, and only then does the gateway forget the party
11
+ * and revoke its client's tokens; its worker ends as the fleet ends the
12
+ * proxy ship's crew. A proxy ship retired already is retired. A party whose
13
+ * ship the gateway never learned asks the fleet nothing. Adding it again is
14
+ * a new request.
15
+ */
16
+ export function createRetireParty(deps) {
17
+ return async ({ actor, as, name }) => {
18
+ if (!actor.scopes.includes(RETIRING_SCOPE)) {
19
+ return refuse('NOT_A_MANAGER', `Retiring an outside party needs ${RETIRING_SCOPE}`);
20
+ }
21
+ const party = await deps.parties.find(actor.fleetId, name);
22
+ if (party === undefined) {
23
+ return refuse('NO_SUCH_PARTY', `There is no outside party ${name}`);
24
+ }
25
+ if (party.proxyShipId !== null) {
26
+ const credential = await deps.credentialOf(actor, as);
27
+ if (!credential.isOk) {
28
+ return credential;
29
+ }
30
+ const retired = await deps.fleet.retire(credential.value, { shipId: party.proxyShipId });
31
+ if (!retired.isOk && retired.error.code === 'UNAVAILABLE') {
32
+ return refuse('FLEET_UNAVAILABLE', `The fleet did not retire ${name}'s proxy ship: ${retired.error.message}`);
33
+ }
34
+ if (!retired.isOk && retired.error.code !== RETIRED_ALREADY) {
35
+ return refuse('RETIRE_REFUSED', retired.error.message);
36
+ }
37
+ }
38
+ await deps.parties.remove(actor.fleetId, name);
39
+ await deps.tokens.revokeParty(actor.fleetId, name);
40
+ return ok(undefined);
41
+ };
42
+ }
43
+ //# sourceMappingURL=retire-party.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retire-party.js","sourceRoot":"","sources":["../../../src/core/parties/retire-party.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAGtD,uFAAuF;AACvF,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAE7C,uFAAuF;AACvF,MAAM,eAAe,GAAG,UAAU,CAAC;AAMnC;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA8H;IAC9J,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACnC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAC3C,OAAO,MAAM,CAAC,eAAe,EAAE,mCAAmC,cAAc,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC,eAAe,EAAE,6BAA6B,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACzF,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC1D,OAAO,MAAM,CAAC,mBAAmB,EAAE,4BAA4B,IAAI,kBAAkB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAChH,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC5D,OAAO,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnD,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC"}
@@ -3,11 +3,10 @@ import type { McpServerCredential } from '../vault/credential.js';
3
3
  import type { Party, PartyState } from './party.js';
4
4
  interface ShownPartyBase {
5
5
  name: string;
6
- ownerShipId: ShipId;
7
6
  state: PartyState;
8
7
  proxyShipId: ShipId | null;
9
8
  }
10
- /** A party as argo reads it: never its credential, secret or crew token. */
9
+ /** A party as the gateway keeps it, for any actor to read: never its credential, secret or crew token. */
11
10
  export type ShownParty = (ShownPartyBase & {
12
11
  kind: 'mcpServer';
13
12
  url: string;
@@ -17,5 +16,12 @@ export type ShownParty = (ShownPartyBase & {
17
16
  kind: 'mcpClient';
18
17
  clientId: string;
19
18
  });
19
+ /** What the fleet holds for a party's proxy ship (decision 0056): none while it has no proxy ship, or the fleet does not answer. */
20
+ export interface FromFleet {
21
+ ownerShipId: ShipId | null;
22
+ scopes: string[] | null;
23
+ }
24
+ /** A party with its proxy ship's owner and scopes, read from the fleet. */
25
+ export type ListedParty = ShownParty & FromFleet;
20
26
  export declare function shownPartyOf(party: Party): ShownParty;
21
27
  export {};
@@ -1,10 +1,10 @@
1
1
  export function shownPartyOf(party) {
2
- const { name, ownerShipId, state, proxyShipId } = party;
2
+ const { name, state, proxyShipId } = party;
3
3
  switch (party.kind) {
4
4
  case 'mcpServer':
5
- return { name, kind: party.kind, url: party.url, credentialKind: party.credential.kind, ownerShipId, concurrencyLimit: party.concurrencyLimit, state, proxyShipId };
5
+ return { name, kind: party.kind, url: party.url, credentialKind: party.credential.kind, concurrencyLimit: party.concurrencyLimit, state, proxyShipId };
6
6
  case 'mcpClient':
7
- return { name, kind: party.kind, clientId: party.clientId, ownerShipId, state, proxyShipId };
7
+ return { name, kind: party.kind, clientId: party.clientId, state, proxyShipId };
8
8
  }
9
9
  }
10
10
  //# sourceMappingURL=shown-party.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shown-party.js","sourceRoot":"","sources":["../../../src/core/parties/shown-party.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IACxD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QACtK,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACjG,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"shown-party.js","sourceRoot":"","sources":["../../../src/core/parties/shown-party.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAC3C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QACzJ,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACpF,CAAC;AACH,CAAC"}
@@ -6,7 +6,15 @@ export const APPROVING_SCOPE = 'gateway:approve';
6
6
  /** The scopes every app ship gets (decision 0046), so an approver need not hold them to grant them. */
7
7
  const EVERY_APP_SHIP_SCOPES = new Set(['messages:send', 'messages:receive']);
8
8
  function decidedByOf(actor) {
9
- return actor.kind === 'ship' ? { kind: 'ship', shipId: actor.shipId } : { kind: actor.kind };
9
+ switch (actor.kind) {
10
+ case 'ship':
11
+ return { kind: 'ship', shipId: actor.shipId };
12
+ case 'account':
13
+ return { kind: 'account', accountId: actor.accountId };
14
+ case 'operator':
15
+ case 'viewer':
16
+ return { kind: actor.kind };
17
+ }
10
18
  }
11
19
  /**
12
20
  * Use case: an actor holding gateway:approve decides a pending request
@@ -1 +1 @@
1
- {"version":3,"file":"decide-request.js","sourceRoot":"","sources":["../../../src/core/requests/decide-request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decide-request.js","sourceRoot":"","sources":["../../../src/core/requests/decide-request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Actor } from '../actors/authenticate-actor.js';
2
+ import type { Clock } from '../shared/clock.js';
3
+ import { type DomainError } from '../shared/errors.js';
4
+ import { type Result } from '../shared/result.js';
5
+ import type { PendingRequest, PendingRequests } from './ports.js';
6
+ export type ListMine = (actor: Actor) => Promise<Result<PendingRequest[], DomainError<'NOT_AN_ACCOUNT'>>>;
7
+ /**
8
+ * Use case: the requests an account asked, in any state, the newest first
9
+ * (decision 0056: Your requests on the overview). One still pending past its
10
+ * 7 days reads as expired, as the store marks it only when it is next
11
+ * opened. Only an account asks, so any other actor has none.
12
+ */
13
+ export declare function createListMine(deps: {
14
+ requests: PendingRequests;
15
+ clock: Clock;
16
+ }): ListMine;
@@ -0,0 +1,20 @@
1
+ import { refuse } from '../shared/errors.js';
2
+ import { ok } from '../shared/result.js';
3
+ import { stateAt } from './request-state.js';
4
+ /**
5
+ * Use case: the requests an account asked, in any state, the newest first
6
+ * (decision 0056: Your requests on the overview). One still pending past its
7
+ * 7 days reads as expired, as the store marks it only when it is next
8
+ * opened. Only an account asks, so any other actor has none.
9
+ */
10
+ export function createListMine(deps) {
11
+ return async (actor) => {
12
+ if (actor.kind !== 'account') {
13
+ return refuse('NOT_AN_ACCOUNT', 'Only a person signed in to the gateway has requests of their own');
14
+ }
15
+ const now = deps.clock.now();
16
+ const mine = await deps.requests.listMine(actor.fleetId, actor.accountId);
17
+ return ok(mine.map((request) => ({ ...request, state: stateAt(request, now) })));
18
+ };
19
+ }
20
+ //# sourceMappingURL=list-mine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-mine.js","sourceRoot":"","sources":["../../../src/core/requests/list-mine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI7C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAiD;IAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC,gBAAgB,EAAE,kEAAkE,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1E,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC;AACJ,CAAC"}
@@ -34,6 +34,9 @@ export type DecidedBy = {
34
34
  } | {
35
35
  readonly kind: 'ship';
36
36
  readonly shipId: ShipId;
37
+ } | {
38
+ readonly kind: 'account';
39
+ readonly accountId: string;
37
40
  };
38
41
  export interface PendingRequest {
39
42
  readonly fleetId: FleetId;
@@ -72,6 +75,8 @@ export interface PendingRequests {
72
75
  }): Promise<void>;
73
76
  /** The open requests not expired by now, the oldest first. */
74
77
  listOpen(fleetId: FleetId, now: Date): Promise<PendingRequest[]>;
78
+ /** The requests an account asked in the fleet, in any state, the newest first. */
79
+ listMine(fleetId: FleetId, accountId: string): Promise<PendingRequest[]>;
75
80
  /** Takes a pending request, not expired by now, for approving; false when it is not. */
76
81
  claim(fleetId: FleetId, claim: {
77
82
  requestId: string;
@@ -1,6 +1,6 @@
1
1
  import { type Err } from './result.js';
2
2
  /** Every reason the gateway's core refuses a request. */
3
- export type DomainErrorKind = 'ALREADY_CONNECTED' | 'SECRET_REFUSED' | 'OTHER_FLEET' | 'MISSING_SCOPES' | 'SCOPE_REFUSED' | 'NOT_THE_OPERATOR' | 'NOT_AN_ACTOR' | 'NOT_AN_APPROVER' | 'NO_SUCH_REQUEST' | 'ALREADY_DECIDED' | 'EXPIRED' | 'SCOPE_NOT_HELD' | 'SERVER_DETAILS_MISSING' | 'REQUEST_ID_USED' | 'FLEET_UNAVAILABLE' | 'NOT_CONNECTED' | 'PARTY_EXISTS' | 'COMMISSION_REFUSED' | 'NO_SUCH_PARTY' | 'NOT_AWAITING_CREW' | 'NOT_CREWED' | 'SERVER_UNREACHABLE' | 'STATEMENT_REFUSED' | 'INVALID_REDIRECT_URIS' | 'CLIENT_HAS_PARTY' | 'PARTY_NOT_CREWED' | 'NO_SUCH_TOOL' | 'INVALID_ARGUMENTS' | 'NOT_REACHABLE' | 'SEND_REFUSED' | 'NO_SUCH_CALL' | 'NOT_A_PERSON' | 'SIGNED_OUT' | 'NO_SUCH_DELIVERY' | 'NOT_A_NETWORKER' | 'OPEN_NETWORK' | 'OUTSIDE_PARTIES_OFF' | 'INVALID_SERVER_URL';
3
+ export type DomainErrorKind = 'ALREADY_CONNECTED' | 'SECRET_REFUSED' | 'OTHER_FLEET' | 'MISSING_SCOPES' | 'SCOPE_REFUSED' | 'NOT_THE_OPERATOR' | 'NOT_AN_ACTOR' | 'NOT_AN_APPROVER' | 'NO_SUCH_REQUEST' | 'ALREADY_DECIDED' | 'EXPIRED' | 'SCOPE_NOT_HELD' | 'SERVER_DETAILS_MISSING' | 'REQUEST_ID_USED' | 'FLEET_UNAVAILABLE' | 'NOT_CONNECTED' | 'PARTY_EXISTS' | 'COMMISSION_REFUSED' | 'NO_SUCH_PARTY' | 'NOT_AWAITING_CREW' | 'NOT_CREWED' | 'SERVER_UNREACHABLE' | 'STATEMENT_REFUSED' | 'INVALID_REDIRECT_URIS' | 'CLIENT_HAS_PARTY' | 'PARTY_NOT_CREWED' | 'NO_SUCH_TOOL' | 'INVALID_ARGUMENTS' | 'NOT_REACHABLE' | 'SEND_REFUSED' | 'NO_SUCH_CALL' | 'NOT_A_PERSON' | 'SIGNED_OUT' | 'NO_SUCH_DELIVERY' | 'NOT_A_NETWORKER' | 'OPEN_NETWORK' | 'OUTSIDE_PARTIES_OFF' | 'INVALID_SERVER_URL' | 'NOT_A_MANAGER' | 'RETIRE_REFUSED' | 'NOT_AN_ACCOUNT' | 'PARTY_NOT_COMMISSIONED' | 'CHANGE_REFUSED';
4
4
  /** Why the core refused a request. Adapters map the kind to their own error shape; the message is safe to show. */
5
5
  export interface DomainError<K extends DomainErrorKind = DomainErrorKind> {
6
6
  readonly kind: K;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/shared/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,MAAM,aAAa,CAAC;AAiD5C,qDAAqD;AACrD,MAAM,UAAU,MAAM,CAA4B,IAAO,EAAE,OAAe;IACxE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/shared/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,MAAM,aAAa,CAAC;AAsD5C,qDAAqD;AACrD,MAAM,UAAU,MAAM,CAA4B,IAAO,EAAE,OAAe;IACxE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -15,13 +15,17 @@ export type AccountTokenRefusal = {
15
15
  } | {
16
16
  readonly kind: 'pagasaeUnavailable';
17
17
  };
18
+ /** An account token to call with, and the account, person ship and scopes it names. */
19
+ export interface AccountToken {
20
+ readonly accountToken: string;
21
+ readonly accountId: string;
22
+ readonly personShipId: ShipId | null;
23
+ readonly scopes: readonly string[];
24
+ }
18
25
  export type AccountTokenOf = (grant: {
19
26
  fleetId: FleetId;
20
27
  grantId: string;
21
- }) => Promise<Result<{
22
- accountToken: string;
23
- personShipId: ShipId | null;
24
- }, AccountTokenRefusal>>;
28
+ }) => Promise<Result<AccountToken, AccountTokenRefusal>>;
25
29
  /**
26
30
  * Use case: the account token a signed-in person's call carries to core
27
31
  * (decisions 0054, 0058). It lasts 10 minutes; a minute before it ends the
@@ -17,7 +17,7 @@ export function createAccountTokenOf(deps) {
17
17
  return err({ kind: 'signedOut' });
18
18
  }
19
19
  if (grant.accountTokenExpiresAt.getTime() - ACCOUNT_TOKEN_MARGIN_MS > deps.clock.now().getTime()) {
20
- return ok({ accountToken: grant.accountToken, personShipId: grant.personShipId });
20
+ return ok({ accountToken: grant.accountToken, accountId: grant.accountId, personShipId: grant.personShipId, scopes: grant.scopes });
21
21
  }
22
22
  const refreshed = await deps.pagasae.refresh(grant.refreshToken);
23
23
  if (!refreshed.isOk && refreshed.error.kind === 'unavailable') {
@@ -28,9 +28,9 @@ export function createAccountTokenOf(deps) {
28
28
  await deps.tokens.revokeGrant(fleetId, grantId);
29
29
  return err({ kind: 'signedOut' });
30
30
  }
31
- const { refreshToken, accountToken, accountTokenExpiresAt, personShipId } = refreshed.value;
32
- await deps.grants.renew({ fleetId, grantId }, { refreshToken, accountToken, accountTokenExpiresAt, personShipId });
33
- return ok({ accountToken, personShipId });
31
+ const { refreshToken, accountToken, accountTokenExpiresAt, personShipId, scopes } = refreshed.value;
32
+ await deps.grants.renew({ fleetId, grantId }, { refreshToken, accountToken, accountTokenExpiresAt, personShipId, scopes });
33
+ return ok({ accountToken, accountId: grant.accountId, personShipId, scopes });
34
34
  };
35
35
  return (grant) => {
36
36
  const key = `${grant.fleetId}/${grant.grantId}`;
@@ -1 +1 @@
1
- {"version":3,"file":"account-token.js","sourceRoot":"","sources":["../../../src/core/sign-in/account-token.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAG3D,yHAAyH;AACzH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAW9C;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAqF;IACxH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsC,CAAC;IAEjE,MAAM,KAAK,GAAmB,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,KAAK,CAAC,qBAAqB,CAAC,OAAO,EAAE,GAAG,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;YACjG,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC9D,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC3D,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;QAC5F,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,CAAC,CAAC;QACnH,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"account-token.js","sourceRoot":"","sources":["../../../src/core/sign-in/account-token.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAG3D,yHAAyH;AACzH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAmB9C;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAqF;IACxH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsC,CAAC;IAEjE,MAAM,KAAK,GAAmB,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,KAAK,CAAC,qBAAqB,CAAC,OAAO,EAAE,GAAG,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;YACjG,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACtI,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC9D,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC3D,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;QACpG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3H,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC;IAEF,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -4,7 +4,7 @@ import type { AuthorizationRefusal, ReadAuthorization } from '../oauth/read-auth
4
4
  import type { AskForClient, ClientAnswer } from '../requests/ask-for-client.js';
5
5
  import type { Clock } from '../shared/clock.js';
6
6
  import { type Result } from '../shared/result.js';
7
- import type { AccountGrants, Pagasae, SignInSeals } from './ports.js';
7
+ import type { AccountGrants, Pagasae, PageSessions, SignInSeals } from './ports.js';
8
8
  /**
9
9
  * Why a sign-in gave the client no code, beside the request's own refusals:
10
10
  * - unknownSignIn: the gateway sealed no sign-in into this state, or its 10 minutes passed;
@@ -25,12 +25,19 @@ export type SignInRefusal = AuthorizationRefusal | {
25
25
  } | {
26
26
  readonly kind: 'outsidePartiesOff';
27
27
  };
28
- export type CompleteSignIn = (back: {
28
+ /** What a sign-in answers: the client's answer, or, for the gateway's pages, the page session to hold and the page to go back to. */
29
+ export type SignInAnswer = ClientAnswer | {
30
+ readonly kind: 'signedIn';
31
+ readonly session: string;
32
+ readonly redirectTo: string;
33
+ };
34
+ interface Back {
29
35
  state?: string | undefined;
30
36
  code?: string | undefined;
31
37
  error?: string | undefined;
32
38
  browserSecret?: string | undefined;
33
- }) => Promise<Result<ClientAnswer, SignInRefusal>>;
39
+ }
40
+ export type CompleteSignIn = (back: Back) => Promise<Result<SignInAnswer, SignInRefusal>>;
34
41
  /**
35
42
  * Use case: pagasae sends the person back. Their sign-in is opened from its
36
43
  * state, the client's request read again, and pagasae's code redeemed with
@@ -38,7 +45,9 @@ export type CompleteSignIn = (back: {
38
45
  * picked: the account's grant is kept, and the client is sent back with the
39
46
  * gateway's own code for it, acting in the fleet as the account with no
40
47
  * approval (orchestrator-1, slice 7 Q1); or the account asks for access for
41
- * the client, as an outside party (decision 0056).
48
+ * the client, as an outside party (decision 0056). A sign-in to the
49
+ * gateway's pages keeps the account's grant too, and answers a page session
50
+ * naming it, so the pages act as the account.
42
51
  */
43
52
  export declare function createCompleteSignIn(deps: {
44
53
  readAuthorization: ReadAuthorization;
@@ -52,4 +61,6 @@ export declare function createCompleteSignIn(deps: {
52
61
  /** Whether the gateway serves the fleet: connected to it, and switched on where an installation switches fleets (decision 0021). */
53
62
  servesFleet: (fleetId: FleetId) => Promise<boolean>;
54
63
  askForClient: AskForClient;
64
+ sessions: PageSessions;
55
65
  }): CompleteSignIn;
66
+ export {};
@@ -7,10 +7,30 @@ import { err, ok } from '../shared/result.js';
7
7
  * picked: the account's grant is kept, and the client is sent back with the
8
8
  * gateway's own code for it, acting in the fleet as the account with no
9
9
  * approval (orchestrator-1, slice 7 Q1); or the account asks for access for
10
- * the client, as an outside party (decision 0056).
10
+ * the client, as an outside party (decision 0056). A sign-in to the
11
+ * gateway's pages keeps the account's grant too, and answers a page session
12
+ * naming it, so the pages act as the account.
11
13
  */
12
14
  export function createCompleteSignIn(deps) {
13
- return async ({ state, code, error, browserSecret }) => {
15
+ /** A sign-in to the pages: the grant kept, and the session naming it; no client to send back, so pagasae's error is said. */
16
+ const signInToPages = async (signIn, { code, error }) => {
17
+ if (error !== undefined || code === undefined) {
18
+ return err({ kind: 'pagasaeRefused', message: error ?? 'pagasae sent no code' });
19
+ }
20
+ const redeemed = await deps.pagasae.redeemCode({ code, verifier: signIn.verifier });
21
+ if (!redeemed.isOk) {
22
+ return err({ kind: 'pagasaeRefused', message: redeemed.error.reason });
23
+ }
24
+ const { fleetId, accountId, personShipId, scopes, refreshToken, accountToken, accountTokenExpiresAt } = redeemed.value;
25
+ if (!(await deps.servesFleet(fleetId))) {
26
+ return err({ kind: 'fleetNotServed' });
27
+ }
28
+ const grantId = deps.secrets.newSecret();
29
+ await deps.grants.save({ grantId, fleetId, accountId, personShipId, scopes, refreshToken, accountToken, accountTokenExpiresAt });
30
+ return ok({ kind: 'signedIn', session: deps.sessions.seal({ fleetId, grantId }), redirectTo: signIn.returnTo });
31
+ };
32
+ return async (back) => {
33
+ const { state, code, error, browserSecret } = back;
14
34
  const signIn = state === undefined ? undefined : deps.seals.open(state);
15
35
  if (signIn === undefined || signIn.expiresAt.getTime() <= deps.clock.now().getTime()) {
16
36
  return err({ kind: 'unknownSignIn' });
@@ -18,6 +38,9 @@ export function createCompleteSignIn(deps) {
18
38
  if (browserSecret !== signIn.browserSecret) {
19
39
  return err({ kind: 'otherBrowser' });
20
40
  }
41
+ if (signIn.holder === 'page') {
42
+ return signInToPages(signIn, back);
43
+ }
21
44
  const read = await deps.readAuthorization(signIn.request);
22
45
  if (!read.isOk) {
23
46
  return read;
@@ -37,13 +60,13 @@ export function createCompleteSignIn(deps) {
37
60
  if (authorization.clientFleetId !== null && authorization.clientFleetId !== tokens.fleetId) {
38
61
  return err({ kind: 'invalidClient', message: `${authorization.clientName} is registered for another fleet` });
39
62
  }
40
- const { fleetId, accountId, personShipId, refreshToken, accountToken, accountTokenExpiresAt } = tokens;
63
+ const { fleetId, accountId, personShipId, scopes, refreshToken, accountToken, accountTokenExpiresAt } = tokens;
41
64
  if (signIn.holder === 'party') {
42
65
  const asked = await deps.askForClient({ fleetId, requester: { accountId, personShipId }, authorization, request: signIn.request, browserSecret: signIn.browserSecret });
43
66
  return asked.isOk ? asked : err({ kind: 'outsidePartiesOff' });
44
67
  }
45
68
  const grantId = deps.secrets.newSecret();
46
- await deps.grants.save({ grantId, fleetId, accountId, personShipId, refreshToken, accountToken, accountTokenExpiresAt });
69
+ await deps.grants.save({ grantId, fleetId, accountId, personShipId, scopes, refreshToken, accountToken, accountTokenExpiresAt });
47
70
  return ok({ kind: 'answered', redirectTo: await issueCode(deps, { fleetId, authorization, holder: { kind: 'account', grantId } }) });
48
71
  };
49
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"complete-sign-in.js","sourceRoot":"","sources":["../../../src/core/sign-in/complete-sign-in.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"complete-sign-in.js","sourceRoot":"","sources":["../../../src/core/sign-in/complete-sign-in.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,32 @@
1
1
  /**
2
2
  * A person signs in to the gateway through pagasae, the one identity
3
3
  * provider (decision 0054): the gateway is its OpenID Connect client, and
4
- * the person acts in the fleet as their account, by its account token.
4
+ * the person acts in the fleet as their account, by its account token, from
5
+ * their MCP client or on the gateway's own pages.
5
6
  */
6
7
  import type { FleetId, ShipId } from '@aeolus-fleet/common';
7
8
  import type { Result } from '../shared/result.js';
8
- /** A person's sign-in at pagasae under way: the client's authorization request, with the gateway's PKCE verifier. */
9
- export interface PendingSignIn {
9
+ /**
10
+ * A person's sign-in at pagasae under way, with the gateway's PKCE verifier:
11
+ * for an MCP client, its authorization request; for the gateway's pages, the
12
+ * page to go back to.
13
+ */
14
+ export type PendingSignIn = ClientSignIn | PageSignIn;
15
+ interface SignInUnderWay {
10
16
  readonly verifier: string;
11
17
  /** The secret the browser that started the sign-in holds, so no other browser finishes it (login CSRF). */
12
18
  readonly browserSecret: string;
19
+ readonly expiresAt: Date;
20
+ }
21
+ export interface ClientSignIn extends SignInUnderWay {
13
22
  readonly request: Readonly<Record<string, string | undefined>>;
14
23
  /** What the person picked the client to act as: their account, or a party they ask access for (Q1 a). */
15
24
  readonly holder: SignInHolder;
16
- readonly expiresAt: Date;
25
+ }
26
+ export interface PageSignIn extends SignInUnderWay {
27
+ readonly holder: 'page';
28
+ /** The gateway's own path the browser goes back to once signed in. */
29
+ readonly returnTo: string;
17
30
  }
18
31
  /** What a client acts as once its person signed in: the account itself, or an outside party (decision 0056). */
19
32
  export type SignInHolder = 'account' | 'party';
@@ -37,6 +50,8 @@ export interface PagasaeTokens {
37
50
  readonly accountId: string;
38
51
  /** The account's person ship in the fleet, if it has one (decision 0052). */
39
52
  readonly personShipId: ShipId | null;
53
+ /** The scopes the account token carries: what the account may do in the fleet. */
54
+ readonly scopes: readonly string[];
40
55
  }
41
56
  /** Outbound port: pagasae, where the gateway sends a person to sign in, and redeems the code they come back with. */
42
57
  export interface Pagasae {
@@ -61,12 +76,14 @@ export interface Pagasae {
61
76
  reason: string;
62
77
  }>>;
63
78
  }
64
- /** A person's sign-in kept for their MCP client: the account in the fleet, and pagasae's tokens to act as it. */
79
+ /** A person's sign-in kept for their MCP client or the gateway's pages: the account in the fleet, and pagasae's tokens to act as it. */
65
80
  export interface AccountGrant {
66
81
  readonly grantId: string;
67
82
  readonly fleetId: FleetId;
68
83
  readonly accountId: string;
69
84
  readonly personShipId: ShipId | null;
85
+ /** The scopes its account token carries. */
86
+ readonly scopes: readonly string[];
70
87
  readonly refreshToken: string;
71
88
  readonly accountToken: string;
72
89
  readonly accountTokenExpiresAt: Date;
@@ -76,10 +93,23 @@ export interface AccountGrants {
76
93
  find(fleetId: FleetId, grantId: string): Promise<AccountGrant | undefined>;
77
94
  /** Every grant of the account in the fleet: one per client it signed in from. */
78
95
  ofAccount(fleetId: FleetId, accountId: string): Promise<readonly AccountGrant[]>;
79
- /** Keeps pagasae's new tokens for the grant, and the person ship they name. */
96
+ /** Keeps pagasae's new tokens for the grant, and the person ship and scopes they name. */
80
97
  renew(grant: {
81
98
  fleetId: FleetId;
82
99
  grantId: string;
83
- }, tokens: Partial<Pick<AccountGrant, 'refreshToken' | 'accountToken' | 'accountTokenExpiresAt' | 'personShipId'>>): Promise<void>;
100
+ }, tokens: Partial<Pick<AccountGrant, 'refreshToken' | 'accountToken' | 'accountTokenExpiresAt' | 'personShipId' | 'scopes'>>): Promise<void>;
84
101
  end(fleetId: FleetId, grantId: string): Promise<void>;
85
102
  }
103
+ /** A browser signed in to the gateway's pages: the account's grant it acts by. */
104
+ export interface PageSession {
105
+ readonly fleetId: FleetId;
106
+ readonly grantId: string;
107
+ }
108
+ /** Outbound port: the page session a browser holds in the gateway's own cookie, sealed so no one forges or reads it. */
109
+ export interface PageSessions {
110
+ /** The cookie's value for the session. */
111
+ seal(session: PageSession): string;
112
+ /** The session a Cookie header carries; none when it carries none the gateway sealed. */
113
+ inCookie(cookie: string): PageSession | undefined;
114
+ }
115
+ export {};