@aeolus-fleet/core 0.27.1 → 0.28.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/dist/adapters/crypto/account-token-signatures.d.ts +12 -0
- package/dist/adapters/crypto/account-token-signatures.js +104 -0
- package/dist/adapters/crypto/account-token-signatures.js.map +1 -0
- package/dist/adapters/http/request-credentials.d.ts +7 -1
- package/dist/adapters/http/request-credentials.js +18 -5
- package/dist/adapters/http/request-credentials.js.map +1 -1
- package/dist/adapters/http/server.js +4 -2
- package/dist/adapters/http/server.js.map +1 -1
- package/dist/adapters/prisma/event-log.js +13 -1
- package/dist/adapters/prisma/event-log.js.map +1 -1
- package/dist/adapters/prisma/generated/browser.d.ts +30 -0
- package/dist/adapters/prisma/generated/client.d.ts +30 -0
- package/dist/adapters/prisma/generated/commonInputTypes.d.ts +120 -0
- package/dist/adapters/prisma/generated/enums.d.ts +25 -0
- package/dist/adapters/prisma/generated/enums.js +22 -1
- package/dist/adapters/prisma/generated/enums.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/class.d.ts +44 -0
- package/dist/adapters/prisma/generated/internal/class.js +4 -4
- package/dist/adapters/prisma/generated/internal/class.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +372 -9
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js +38 -11
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +39 -8
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +38 -11
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
- package/dist/adapters/prisma/generated/models/AccountCutOff.d.ts +944 -0
- package/dist/adapters/prisma/generated/models/AccountCutOff.js +2 -0
- package/dist/adapters/prisma/generated/models/AccountCutOff.js.map +1 -0
- package/dist/adapters/prisma/generated/models/ConsoleSession.d.ts +59 -1
- package/dist/adapters/prisma/generated/models/Event.d.ts +426 -1
- package/dist/adapters/prisma/generated/models/Fleet.d.ts +871 -0
- package/dist/adapters/prisma/generated/models/InstallationDeclaredNetworkRules.d.ts +1031 -0
- package/dist/adapters/prisma/generated/models/InstallationDeclaredNetworkRules.js +2 -0
- package/dist/adapters/prisma/generated/models/InstallationDeclaredNetworkRules.js.map +1 -0
- package/dist/adapters/prisma/generated/models/Label.d.ts +113 -39
- package/dist/adapters/prisma/generated/models/NetworkRulesDraft.d.ts +1133 -0
- package/dist/adapters/prisma/generated/models/NetworkRulesDraft.js +2 -0
- package/dist/adapters/prisma/generated/models/NetworkRulesDraft.js.map +1 -0
- package/dist/adapters/prisma/generated/models/NetworkSettings.d.ts +24 -255
- package/dist/adapters/prisma/generated/models/ReachRefusal.d.ts +1 -40
- package/dist/adapters/prisma/generated/models/Ship.d.ts +782 -6
- package/dist/adapters/prisma/generated/models/SignInTicket.d.ts +39 -1
- package/dist/adapters/prisma/generated/models/VerifiedFacts.d.ts +1325 -0
- package/dist/adapters/prisma/generated/models/VerifiedFacts.js +2 -0
- package/dist/adapters/prisma/generated/models/VerifiedFacts.js.map +1 -0
- package/dist/adapters/prisma/generated/models.d.ts +4 -0
- package/dist/adapters/prisma/history.js +1 -0
- package/dist/adapters/prisma/history.js.map +1 -1
- package/dist/adapters/prisma/identity.d.ts +3 -1
- package/dist/adapters/prisma/identity.js +41 -8
- package/dist/adapters/prisma/identity.js.map +1 -1
- package/dist/adapters/prisma/network.d.ts +7 -2
- package/dist/adapters/prisma/network.js +92 -65
- package/dist/adapters/prisma/network.js.map +1 -1
- package/dist/adapters/prisma/registry.js +19 -14
- package/dist/adapters/prisma/registry.js.map +1 -1
- package/dist/adapters/prisma/rows.d.ts +9 -4
- package/dist/adapters/prisma/rows.js +75 -19
- package/dist/adapters/prisma/rows.js.map +1 -1
- package/dist/adapters/prisma/unit-of-work.d.ts +4 -2
- package/dist/adapters/prisma/unit-of-work.js +5 -2
- package/dist/adapters/prisma/unit-of-work.js.map +1 -1
- package/dist/adapters/prisma/verified-facts.d.ts +4 -0
- package/dist/adapters/prisma/verified-facts.js +65 -0
- package/dist/adapters/prisma/verified-facts.js.map +1 -0
- package/dist/adapters/rest/rest-api.js +2 -2
- package/dist/adapters/rest/rest-api.js.map +1 -1
- package/dist/adapters/trpc/console.d.ts +3 -1
- package/dist/adapters/trpc/context.d.ts +22 -8
- package/dist/adapters/trpc/fleet.d.ts +259 -52
- package/dist/adapters/trpc/fleet.js +121 -84
- package/dist/adapters/trpc/fleet.js.map +1 -1
- package/dist/adapters/trpc/installation-token.d.ts +7 -0
- package/dist/adapters/trpc/installation-token.js +10 -0
- package/dist/adapters/trpc/installation-token.js.map +1 -0
- package/dist/adapters/trpc/installation.d.ts +32 -2
- package/dist/adapters/trpc/installation.js +14 -10
- package/dist/adapters/trpc/installation.js.map +1 -1
- package/dist/adapters/trpc/router.d.ts +307 -43
- package/dist/adapters/trpc/ship-contract.js +6 -4
- package/dist/adapters/trpc/ship-contract.js.map +1 -1
- package/dist/adapters/trpc/ship.d.ts +32 -1
- package/dist/adapters/trpc/ship.js +4 -2
- package/dist/adapters/trpc/ship.js.map +1 -1
- package/dist/adapters/trpc/trpc.d.ts +36 -13
- package/dist/adapters/trpc/trpc.js +117 -26
- package/dist/adapters/trpc/trpc.js.map +1 -1
- package/dist/app.d.ts +2 -0
- package/dist/app.js +22 -0
- package/dist/app.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/domain/identity/authenticate-account.d.ts +35 -0
- package/dist/domain/identity/authenticate-account.js +54 -0
- package/dist/domain/identity/authenticate-account.js.map +1 -0
- package/dist/domain/identity/authenticate-installation.d.ts +23 -0
- package/dist/domain/identity/authenticate-installation.js +20 -0
- package/dist/domain/identity/authenticate-installation.js.map +1 -0
- package/dist/domain/identity/authenticate.d.ts +2 -2
- package/dist/domain/identity/console-session.d.ts +6 -3
- package/dist/domain/identity/console-session.js.map +1 -1
- package/dist/domain/identity/cut-off-account.d.ts +29 -0
- package/dist/domain/identity/cut-off-account.js +37 -0
- package/dist/domain/identity/cut-off-account.js.map +1 -0
- package/dist/domain/identity/dismiss-notice.d.ts +2 -2
- package/dist/domain/identity/issue-sign-in-ticket.d.ts +9 -3
- package/dist/domain/identity/issue-sign-in-ticket.js +8 -2
- package/dist/domain/identity/issue-sign-in-ticket.js.map +1 -1
- package/dist/domain/identity/ports.d.ts +52 -5
- package/dist/domain/identity/read-account.d.ts +8 -4
- package/dist/domain/identity/read-account.js +1 -1
- package/dist/domain/identity/read-account.js.map +1 -1
- package/dist/domain/identity/read-guide.d.ts +2 -2
- package/dist/domain/identity/read-notices.d.ts +2 -2
- package/dist/domain/identity/record-guide-progress.d.ts +2 -2
- package/dist/domain/identity/redeem-sign-in-ticket.d.ts +2 -1
- package/dist/domain/identity/redeem-sign-in-ticket.js +3 -2
- package/dist/domain/identity/redeem-sign-in-ticket.js.map +1 -1
- package/dist/domain/identity/set-theme.d.ts +2 -2
- package/dist/domain/identity/sign-in-ticket.d.ts +3 -1
- package/dist/domain/identity/sign-in.d.ts +2 -2
- package/dist/domain/identity/sign-in.js +2 -0
- package/dist/domain/identity/sign-in.js.map +1 -1
- package/dist/domain/identity/sign-out.d.ts +2 -2
- package/dist/domain/identity/sign-out.js +1 -1
- package/dist/domain/identity/sign-out.js.map +1 -1
- package/dist/domain/identity/start-console-session.d.ts +4 -2
- package/dist/domain/identity/start-console-session.js +6 -4
- package/dist/domain/identity/start-console-session.js.map +1 -1
- package/dist/domain/identity/start-viewer-session.js +1 -0
- package/dist/domain/identity/start-viewer-session.js.map +1 -1
- package/dist/domain/messaging/delivery.d.ts +3 -1
- package/dist/domain/messaging/delivery.js +9 -6
- package/dist/domain/messaging/delivery.js.map +1 -1
- package/dist/domain/messaging/dismiss-delivery.d.ts +2 -2
- package/dist/domain/messaging/message.d.ts +3 -1
- package/dist/domain/messaging/message.js +1 -1
- package/dist/domain/messaging/message.js.map +1 -1
- package/dist/domain/messaging/ping-ship.d.ts +2 -2
- package/dist/domain/messaging/ping-ship.js +1 -1
- package/dist/domain/messaging/ping-ship.js.map +1 -1
- package/dist/domain/messaging/resend-delivery.d.ts +2 -2
- package/dist/domain/messaging/resend-delivery.js +1 -0
- package/dist/domain/messaging/resend-delivery.js.map +1 -1
- package/dist/domain/messaging/send-message.d.ts +3 -3
- package/dist/domain/messaging/send-message.js +1 -0
- package/dist/domain/messaging/send-message.js.map +1 -1
- package/dist/domain/registry/apply-network-rules.d.ts +32 -0
- package/dist/domain/registry/apply-network-rules.js +33 -0
- package/dist/domain/registry/apply-network-rules.js.map +1 -0
- package/dist/domain/registry/assign-crew.d.ts +2 -2
- package/dist/domain/registry/assign-crew.js +3 -2
- package/dist/domain/registry/assign-crew.js.map +1 -1
- package/dist/domain/registry/assign-label.d.ts +7 -5
- package/dist/domain/registry/assign-label.js +16 -6
- package/dist/domain/registry/assign-label.js.map +1 -1
- package/dist/domain/registry/change-label-values.d.ts +1 -1
- package/dist/domain/registry/change-label-values.js +4 -3
- package/dist/domain/registry/change-label-values.js.map +1 -1
- package/dist/domain/registry/check-reach.d.ts +45 -24
- package/dist/domain/registry/check-reach.js +76 -42
- package/dist/domain/registry/check-reach.js.map +1 -1
- package/dist/domain/registry/clear-request.d.ts +1 -1
- package/dist/domain/registry/clear-request.js +1 -1
- package/dist/domain/registry/clear-request.js.map +1 -1
- package/dist/domain/registry/commission-ship.d.ts +23 -14
- package/dist/domain/registry/commission-ship.js +167 -21
- package/dist/domain/registry/commission-ship.js.map +1 -1
- package/dist/domain/registry/confirm-crew-release.d.ts +2 -2
- package/dist/domain/registry/confirm-crew-release.js +3 -2
- package/dist/domain/registry/confirm-crew-release.js.map +1 -1
- package/dist/domain/registry/confirm-worktree-cleared.d.ts +2 -2
- package/dist/domain/registry/confirm-worktree-cleared.js +3 -2
- package/dist/domain/registry/confirm-worktree-cleared.js.map +1 -1
- package/dist/domain/registry/connect-plugin.d.ts +5 -4
- package/dist/domain/registry/connect-plugin.js +6 -7
- package/dist/domain/registry/connect-plugin.js.map +1 -1
- package/dist/domain/registry/crew-request.d.ts +2 -2
- package/dist/domain/registry/crew-request.js.map +1 -1
- package/dist/domain/registry/declare-network-rules.d.ts +9 -6
- package/dist/domain/registry/declare-network-rules.js +13 -8
- package/dist/domain/registry/declare-network-rules.js.map +1 -1
- package/dist/domain/registry/declare-scopes.d.ts +2 -2
- package/dist/domain/registry/declared-network-rules.d.ts +30 -21
- package/dist/domain/registry/declared-network-rules.js +46 -22
- package/dist/domain/registry/declared-network-rules.js.map +1 -1
- package/dist/domain/registry/define-label.d.ts +1 -1
- package/dist/domain/registry/define-label.js +5 -5
- package/dist/domain/registry/define-label.js.map +1 -1
- package/dist/domain/registry/delete-label.d.ts +1 -1
- package/dist/domain/registry/delete-label.js +4 -3
- package/dist/domain/registry/delete-label.js.map +1 -1
- package/dist/domain/registry/discard-network-rules-draft.d.ts +23 -0
- package/dist/domain/registry/discard-network-rules-draft.js +24 -0
- package/dist/domain/registry/discard-network-rules-draft.js.map +1 -0
- package/dist/domain/registry/discover.d.ts +11 -10
- package/dist/domain/registry/discover.js +11 -5
- package/dist/domain/registry/discover.js.map +1 -1
- package/dist/domain/registry/explain-crew-request.d.ts +2 -2
- package/dist/domain/registry/explain-crew-request.js +3 -2
- package/dist/domain/registry/explain-crew-request.js.map +1 -1
- package/dist/domain/registry/explain-reach.d.ts +21 -14
- package/dist/domain/registry/explain-reach.js +53 -53
- package/dist/domain/registry/explain-reach.js.map +1 -1
- package/dist/domain/registry/get-ship.d.ts +2 -2
- package/dist/domain/registry/get-starting-prompt.d.ts +4 -2
- package/dist/domain/registry/get-starting-prompt.js +7 -5
- package/dist/domain/registry/get-starting-prompt.js.map +1 -1
- package/dist/domain/registry/give-back-crew-request.d.ts +2 -2
- package/dist/domain/registry/give-back-crew-request.js +3 -2
- package/dist/domain/registry/give-back-crew-request.js.map +1 -1
- package/dist/domain/registry/grant-scopes.d.ts +8 -5
- package/dist/domain/registry/grant-scopes.js +14 -5
- package/dist/domain/registry/grant-scopes.js.map +1 -1
- package/dist/domain/registry/label.d.ts +69 -18
- package/dist/domain/registry/label.js +79 -28
- package/dist/domain/registry/label.js.map +1 -1
- package/dist/domain/registry/lease.d.ts +1 -1
- package/dist/domain/registry/list-fleet.d.ts +2 -0
- package/dist/domain/registry/list-fleet.js +1 -0
- package/dist/domain/registry/list-fleet.js.map +1 -1
- package/dist/domain/registry/list-scopes.d.ts +2 -1
- package/dist/domain/registry/list-scopes.js +2 -1
- package/dist/domain/registry/list-scopes.js.map +1 -1
- package/dist/domain/registry/managed-or-assigned.d.ts +12 -4
- package/dist/domain/registry/managed-or-assigned.js +25 -7
- package/dist/domain/registry/managed-or-assigned.js.map +1 -1
- package/dist/domain/registry/network-rules-draft.d.ts +45 -0
- package/dist/domain/registry/network-rules-draft.js +41 -0
- package/dist/domain/registry/network-rules-draft.js.map +1 -0
- package/dist/domain/registry/network-settings.d.ts +92 -122
- package/dist/domain/registry/network-settings.js +99 -159
- package/dist/domain/registry/network-settings.js.map +1 -1
- package/dist/domain/registry/ports.d.ts +47 -11
- package/dist/domain/registry/reach-refusal.d.ts +18 -4
- package/dist/domain/registry/read-assigned-crew-requests.d.ts +2 -2
- package/dist/domain/registry/read-built-in-rules.d.ts +4 -3
- package/dist/domain/registry/read-built-in-rules.js +7 -6
- package/dist/domain/registry/read-built-in-rules.js.map +1 -1
- package/dist/domain/registry/read-clear-requests.d.ts +2 -2
- package/dist/domain/registry/read-clear-requests.js.map +1 -1
- package/dist/domain/registry/read-declared-network-rules.d.ts +5 -5
- package/dist/domain/registry/read-declared-network-rules.js +4 -4
- package/dist/domain/registry/read-declared-network-rules.js.map +1 -1
- package/dist/domain/registry/read-network-rules-draft-changes.d.ts +22 -0
- package/dist/domain/registry/read-network-rules-draft-changes.js +53 -0
- package/dist/domain/registry/read-network-rules-draft-changes.js.map +1 -0
- package/dist/domain/registry/read-network-rules.d.ts +30 -0
- package/dist/domain/registry/read-network-rules.js +18 -0
- package/dist/domain/registry/read-network-rules.js.map +1 -0
- package/dist/domain/registry/read-on-behalf.d.ts +3 -3
- package/dist/domain/registry/read-on-behalf.js.map +1 -1
- package/dist/domain/registry/read-reach-refusals.d.ts +6 -5
- package/dist/domain/registry/read-reach-refusals.js +13 -8
- package/dist/domain/registry/read-reach-refusals.js.map +1 -1
- package/dist/domain/registry/read-reach.d.ts +6 -8
- package/dist/domain/registry/read-reach.js +21 -16
- package/dist/domain/registry/read-reach.js.map +1 -1
- package/dist/domain/registry/recrew-ship.d.ts +2 -2
- package/dist/domain/registry/recrew-ship.js +3 -3
- package/dist/domain/registry/recrew-ship.js.map +1 -1
- package/dist/domain/registry/release-ship.d.ts +3 -2
- package/dist/domain/registry/release-ship.js +4 -3
- package/dist/domain/registry/release-ship.js.map +1 -1
- package/dist/domain/registry/remove-crew-request.d.ts +2 -2
- package/dist/domain/registry/remove-crew-request.js +4 -3
- package/dist/domain/registry/remove-crew-request.js.map +1 -1
- package/dist/domain/registry/rename-ship.d.ts +1 -1
- package/dist/domain/registry/rename-ship.js +4 -3
- package/dist/domain/registry/rename-ship.js.map +1 -1
- package/dist/domain/registry/report-crew-status.d.ts +2 -2
- package/dist/domain/registry/report-crew-status.js +3 -2
- package/dist/domain/registry/report-crew-status.js.map +1 -1
- package/dist/domain/registry/request-crew.d.ts +3 -3
- package/dist/domain/registry/request-crew.js +4 -3
- package/dist/domain/registry/request-crew.js.map +1 -1
- package/dist/domain/registry/request-worktree-clear.d.ts +2 -2
- package/dist/domain/registry/request-worktree-clear.js +4 -3
- package/dist/domain/registry/request-worktree-clear.js.map +1 -1
- package/dist/domain/registry/retire-ship.d.ts +16 -12
- package/dist/domain/registry/retire-ship.js +28 -21
- package/dist/domain/registry/retire-ship.js.map +1 -1
- package/dist/domain/registry/save-network-rules-draft.d.ts +31 -0
- package/dist/domain/registry/save-network-rules-draft.js +27 -0
- package/dist/domain/registry/save-network-rules-draft.js.map +1 -0
- package/dist/domain/registry/scope-grant.d.ts +19 -19
- package/dist/domain/registry/scope-grant.js +8 -9
- package/dist/domain/registry/scope-grant.js.map +1 -1
- package/dist/domain/registry/set-built-in-rule.d.ts +3 -3
- package/dist/domain/registry/set-built-in-rule.js +5 -9
- package/dist/domain/registry/set-built-in-rule.js.map +1 -1
- package/dist/domain/registry/set-owner.d.ts +9 -6
- package/dist/domain/registry/set-owner.js +14 -8
- package/dist/domain/registry/set-owner.js.map +1 -1
- package/dist/domain/registry/set-verified-facts.d.ts +36 -0
- package/dist/domain/registry/set-verified-facts.js +58 -0
- package/dist/domain/registry/set-verified-facts.js.map +1 -0
- package/dist/domain/registry/ship.d.ts +52 -18
- package/dist/domain/registry/ship.js +76 -18
- package/dist/domain/registry/ship.js.map +1 -1
- package/dist/domain/registry/statement.d.ts +2 -2
- package/dist/domain/registry/statement.js +2 -2
- package/dist/domain/registry/statement.js.map +1 -1
- package/dist/domain/registry/turn.d.ts +2 -2
- package/dist/domain/registry/turn.js +2 -2
- package/dist/domain/registry/turn.js.map +1 -1
- package/dist/domain/registry/unassign-label.d.ts +8 -5
- package/dist/domain/registry/unassign-label.js +17 -6
- package/dist/domain/registry/unassign-label.js.map +1 -1
- package/dist/domain/registry/verified-facts.d.ts +75 -0
- package/dist/domain/registry/verified-facts.js +107 -0
- package/dist/domain/registry/verified-facts.js.map +1 -0
- package/dist/domain/registry/whoami.d.ts +2 -2
- package/dist/domain/shared/caller.d.ts +40 -6
- package/dist/domain/shared/caller.js +20 -0
- package/dist/domain/shared/caller.js.map +1 -1
- package/dist/domain/shared/errors.d.ts +1 -1
- package/dist/domain/shared/errors.js.map +1 -1
- package/dist/domain/shared/events.d.ts +13 -2
- package/dist/domain/shared/events.js.map +1 -1
- package/dist/domain/shared/history.d.ts +3 -1
- package/dist/domain/shared/history.js.map +1 -1
- package/dist/domain/shared/read-fleet-limits.d.ts +2 -2
- package/dist/domain/shared/read-health.d.ts +2 -2
- package/dist/domain/shared/read-inbox.d.ts +2 -2
- package/dist/domain/shared/read-message.d.ts +2 -2
- package/dist/domain/shared/read-needs-attention.d.ts +2 -2
- package/dist/domain/shared/read-sent-message.d.ts +2 -2
- package/dist/domain/shared/read-ship-messages.d.ts +2 -2
- package/dist/domain/shared/read-ship-timeline.d.ts +2 -2
- package/dist/domain/shared/read-ship-way.d.ts +2 -2
- package/dist/domain/shared/read-ship-way.js +1 -1
- package/dist/domain/shared/read-ship-way.js.map +1 -1
- package/dist/start.js +1 -0
- package/dist/start.js.map +1 -1
- package/dist/testing/account-token-issuer.d.ts +30 -0
- package/dist/testing/account-token-issuer.js +48 -0
- package/dist/testing/account-token-issuer.js.map +1 -0
- package/dist/testing/fleet.d.ts +2 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/wiring.d.ts +21 -8
- package/dist/wiring.js +32 -13
- package/dist/wiring.js.map +1 -1
- package/package.json +2 -5
- package/src/adapters/prisma/migrations/20261019200000_account_cut_offs/migration.sql +10 -0
- package/src/adapters/prisma/migrations/20261019210000_event_actors/migration.sql +32 -0
- package/src/adapters/prisma/migrations/20261020090000_argos_jobs_as_scopes/migration.sql +65 -0
- package/src/adapters/prisma/migrations/20261020100000_installation_labels/migration.sql +7 -0
- package/src/adapters/prisma/migrations/20261020110000_installation_declared_network_rules/migration.sql +10 -0
- package/src/adapters/prisma/migrations/20261020120000_commissioning_actors/migration.sql +14 -0
- package/src/adapters/prisma/migrations/20261020130000_console_sign_in_accounts/migration.sql +4 -0
- package/src/adapters/prisma/migrations/20261020140000_event_signed_in_accounts/migration.sql +4 -0
- package/src/adapters/prisma/migrations/20261020150000_account_cut_off_ends_console_sessions/migration.sql +2 -0
- package/src/adapters/prisma/migrations/20261020160000_network_in_core/migration.sql +30 -0
- package/src/adapters/prisma/migrations/20261020170000_verify_scope/migration.sql +64 -0
- package/src/adapters/prisma/migrations/20261020180000_verified_facts/migration.sql +21 -0
- package/src/adapters/prisma/migrations/20261020190000_verified_facts_by_writer/migration.sql +3 -0
- package/src/adapters/prisma/schema.prisma +132 -23
- package/dist/domain/registry/read-network-plugin.d.ts +0 -23
- package/dist/domain/registry/read-network-plugin.js +0 -15
- package/dist/domain/registry/read-network-plugin.js.map +0 -1
- package/dist/domain/registry/register-network-plugin.d.ts +0 -28
- package/dist/domain/registry/register-network-plugin.js +0 -26
- package/dist/domain/registry/register-network-plugin.js.map +0 -1
- package/dist/domain/registry/set-network-rules.d.ts +0 -31
- package/dist/domain/registry/set-network-rules.js +0 -27
- package/dist/domain/registry/set-network-rules.js.map +0 -1
- package/dist/domain/registry/unregister-network-plugin.d.ts +0 -27
- package/dist/domain/registry/unregister-network-plugin.js +0 -25
- package/dist/domain/registry/unregister-network-plugin.js.map +0 -1
package/dist/config.js
CHANGED
|
@@ -30,6 +30,7 @@ const environmentSchema = z.object({
|
|
|
30
30
|
.transform((origin) => new URL(origin).origin)
|
|
31
31
|
.optional(),
|
|
32
32
|
INSTALLATION_TOKEN: z.string().min(INSTALLATION_TOKEN_MIN_LENGTH, `must be at least ${String(INSTALLATION_TOKEN_MIN_LENGTH)} characters`).optional(),
|
|
33
|
+
ACCOUNT_TOKEN_ISSUER: z.url({ protocol: /^https$/, error: 'must be an https:// URL' }).optional(),
|
|
33
34
|
});
|
|
34
35
|
/** What `aeolus-core migrate` reads: the database alone. */
|
|
35
36
|
const databaseEnvironmentSchema = environmentSchema.pick({ DATABASE_URL: true });
|
|
@@ -59,7 +60,7 @@ export function loadConfig(environment) {
|
|
|
59
60
|
if (!result.success) {
|
|
60
61
|
throw configErrorOf(result.error);
|
|
61
62
|
}
|
|
62
|
-
const { DATABASE_URL, PUBLIC_URL, HOST, PORT, LOG_LEVEL, TRUST_PROXY, COOKIE_DOMAIN, CONSOLE_ORIGIN, INSTALLATION_TOKEN } = result.data;
|
|
63
|
+
const { DATABASE_URL, PUBLIC_URL, HOST, PORT, LOG_LEVEL, TRUST_PROXY, COOKIE_DOMAIN, CONSOLE_ORIGIN, INSTALLATION_TOKEN, ACCOUNT_TOKEN_ISSUER } = result.data;
|
|
63
64
|
return {
|
|
64
65
|
databaseUrl: DATABASE_URL,
|
|
65
66
|
publicUrl: PUBLIC_URL,
|
|
@@ -70,6 +71,7 @@ export function loadConfig(environment) {
|
|
|
70
71
|
cookieDomain: COOKIE_DOMAIN,
|
|
71
72
|
consoleOrigin: CONSOLE_ORIGIN ?? new URL(PUBLIC_URL).origin,
|
|
72
73
|
installationToken: INSTALLATION_TOKEN,
|
|
74
|
+
accountTokenIssuer: ACCOUNT_TOKEN_ISSUER,
|
|
73
75
|
};
|
|
74
76
|
}
|
|
75
77
|
/**
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sFAAsF;AACtF,MAAM,WAAW,GAAG,oEAAoE,CAAC;AAEzF,yGAAyG;AACzG,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,CACL,GAAG,KAAK,IAAI;QACZ,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,GAAG;QACpB,GAAG,CAAC,MAAM,KAAK,EAAE;QACjB,GAAG,CAAC,IAAI,KAAK,EAAE;QACf,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACpB,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CACrB,CAAC;AACJ,CAAC;AAED,kGAAkG;AAClG,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEzC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC;IACzG,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACxF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9D,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjG,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC3F,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,wCAAwC,CAAC,CAAC,QAAQ,EAAE;IACjG,cAAc,EAAE,CAAC;SACd,GAAG,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;SAC7E,MAAM,CAAC,QAAQ,EAAE,oEAAoE,CAAC;SACtF,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;SAC7C,QAAQ,EAAE;IACb,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,6BAA6B,EAAE,oBAAoB,MAAM,CAAC,6BAA6B,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sFAAsF;AACtF,MAAM,WAAW,GAAG,oEAAoE,CAAC;AAEzF,yGAAyG;AACzG,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,CACL,GAAG,KAAK,IAAI;QACZ,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,GAAG;QACpB,GAAG,CAAC,MAAM,KAAK,EAAE;QACjB,GAAG,CAAC,IAAI,KAAK,EAAE;QACf,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACpB,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CACrB,CAAC;AACJ,CAAC;AAED,kGAAkG;AAClG,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEzC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC;IACzG,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACxF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9D,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjG,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC3F,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,wCAAwC,CAAC,CAAC,QAAQ,EAAE;IACjG,cAAc,EAAE,CAAC;SACd,GAAG,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;SAC7E,MAAM,CAAC,QAAQ,EAAE,oEAAoE,CAAC;SACtF,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;SAC7C,QAAQ,EAAE;IACb,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,6BAA6B,EAAE,oBAAoB,MAAM,CAAC,6BAA6B,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IACpJ,oBAAoB,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC,QAAQ,EAAE;CAClG,CAAC,CAAC;AAEH,4DAA4D;AAC5D,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AAgCjF,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,GAAG,aAAa,CAAC;CAC/B;AAED,8DAA8D;AAC9D,SAAS,aAAa,CAAC,KAAiB;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,OAAO,IAAI,WAAW,CAAC,2BAA2B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,eAAe,CAAC,WAA+C;IAC7E,MAAM,MAAM,GAAG,yBAAyB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,WAA+C;IACxE,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAC9J,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,SAAS,EAAE,UAAU;QACrB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,gBAAgB,EAAE,WAAW,KAAK,MAAM;QACxC,YAAY,EAAE,aAAa;QAC3B,aAAa,EAAE,cAAc,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM;QAC3D,iBAAiB,EAAE,kBAAkB;QACrC,kBAAkB,EAAE,oBAAoB;KACzC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAmD;IACjF,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAC9E,OAAO;QACL,gBAAgB,CAAC,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC;QAChD,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,CAAC,aAAa,CAAC;KACnF,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AccountCaller, ShipCaller } from '../shared/caller.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 { AccountCutOffLookup, AccountTokenSignatures, HostedFleets } from './ports.js';
|
|
6
|
+
/** How long pagasae's account token lives (decision 0058). */
|
|
7
|
+
export declare const ACCOUNT_TOKEN_LIFE_MS: number;
|
|
8
|
+
/** The allowance between core's clock and pagasae's, on a token's end and issue (decision 0058). */
|
|
9
|
+
export declare const ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS = 30000;
|
|
10
|
+
/**
|
|
11
|
+
* Why an account token makes no caller: it ended, so whoever presented it
|
|
12
|
+
* fetches a fresh one; or it is not to be trusted here at all, one refusal
|
|
13
|
+
* that names no reason, so a forger learns nothing.
|
|
14
|
+
*/
|
|
15
|
+
export type AccountTokenRefusal = DomainError<'ACCOUNT_TOKEN_ENDED' | 'ACCOUNT_TOKEN_INVALID'>;
|
|
16
|
+
export type AuthenticateAccount = (token: string, presented: {
|
|
17
|
+
through: ShipCaller | null;
|
|
18
|
+
}) => Promise<Result<AccountCaller, AccountTokenRefusal>>;
|
|
19
|
+
/**
|
|
20
|
+
* Use case: turns an account token into the account as the caller (decision
|
|
21
|
+
* 0058), checked on every call. pagasae's key signed it, naming pagasae (the
|
|
22
|
+
* signatures port); it is for this fleet: the fleet of the ship that
|
|
23
|
+
* presented it, or with none, a fleet this installation hosts; it has not
|
|
24
|
+
* ended, with 30 seconds of allowance; it lives no longer than the 10
|
|
25
|
+
* minutes pagasae gives one, so a misconfigured issuer cannot widen a
|
|
26
|
+
* leaver's window, and was not issued later than now, so it cannot outlive
|
|
27
|
+
* a cut-off; and its account was not cut off after it was issued. Core
|
|
28
|
+
* stores nothing of the account.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createAuthenticateAccount(deps: {
|
|
31
|
+
signatures: AccountTokenSignatures;
|
|
32
|
+
cutOffs: AccountCutOffLookup;
|
|
33
|
+
fleets: HostedFleets;
|
|
34
|
+
clock: Clock;
|
|
35
|
+
}): AuthenticateAccount;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
/** How long pagasae's account token lives (decision 0058). */
|
|
4
|
+
export const ACCOUNT_TOKEN_LIFE_MS = 10 * 60_000;
|
|
5
|
+
/** The allowance between core's clock and pagasae's, on a token's end and issue (decision 0058). */
|
|
6
|
+
export const ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS = 30_000;
|
|
7
|
+
/**
|
|
8
|
+
* Use case: turns an account token into the account as the caller (decision
|
|
9
|
+
* 0058), checked on every call. pagasae's key signed it, naming pagasae (the
|
|
10
|
+
* signatures port); it is for this fleet: the fleet of the ship that
|
|
11
|
+
* presented it, or with none, a fleet this installation hosts; it has not
|
|
12
|
+
* ended, with 30 seconds of allowance; it lives no longer than the 10
|
|
13
|
+
* minutes pagasae gives one, so a misconfigured issuer cannot widen a
|
|
14
|
+
* leaver's window, and was not issued later than now, so it cannot outlive
|
|
15
|
+
* a cut-off; and its account was not cut off after it was issued. Core
|
|
16
|
+
* stores nothing of the account.
|
|
17
|
+
*/
|
|
18
|
+
export function createAuthenticateAccount(deps) {
|
|
19
|
+
return async (token, { through }) => {
|
|
20
|
+
const claims = await deps.signatures.verify(token);
|
|
21
|
+
if (!claims || !(await isForThisFleet(deps.fleets, { claims, through }))) {
|
|
22
|
+
return refuseInvalid();
|
|
23
|
+
}
|
|
24
|
+
const now = deps.clock.now().getTime();
|
|
25
|
+
if (now > claims.endsAt.getTime() + ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS) {
|
|
26
|
+
return refuse('ACCOUNT_TOKEN_ENDED', 'This account token has ended; present a fresh one');
|
|
27
|
+
}
|
|
28
|
+
const life = claims.endsAt.getTime() - claims.issuedAt.getTime();
|
|
29
|
+
if (life > ACCOUNT_TOKEN_LIFE_MS + ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS || claims.issuedAt.getTime() > now + ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS) {
|
|
30
|
+
return refuseInvalid();
|
|
31
|
+
}
|
|
32
|
+
const cutOffAt = await deps.cutOffs.cutOffAt(claims.accountId, deps.clock.now());
|
|
33
|
+
if (cutOffAt !== undefined && claims.issuedAt < cutOffAt) {
|
|
34
|
+
return refuseInvalid();
|
|
35
|
+
}
|
|
36
|
+
return ok({
|
|
37
|
+
kind: 'account',
|
|
38
|
+
accountId: claims.accountId,
|
|
39
|
+
fleetId: claims.fleetId,
|
|
40
|
+
scopes: claims.scopes,
|
|
41
|
+
groupValues: claims.groupValues,
|
|
42
|
+
personShipId: claims.personShipId,
|
|
43
|
+
throughShipId: through?.shipId ?? null,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function isForThisFleet(fleets, token) {
|
|
48
|
+
const { claims, through } = token;
|
|
49
|
+
return through === null ? fleets.isHosted(claims.fleetId) : claims.fleetId === through.fleetId;
|
|
50
|
+
}
|
|
51
|
+
function refuseInvalid() {
|
|
52
|
+
return refuse('ACCOUNT_TOKEN_INVALID', 'Present an account token pagasae signed for this fleet');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=authenticate-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate-account.js","sourceRoot":"","sources":["../../../src/domain/identity/authenticate-account.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAGtD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,MAAM,CAAC;AAEjD,oGAAoG;AACpG,MAAM,CAAC,MAAM,gCAAgC,GAAG,MAAM,CAAC;AAWvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAKzC;IACC,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QACvC,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,gCAAgC,EAAE,CAAC;YACrE,OAAO,MAAM,CAAC,qBAAqB,EAAE,mDAAmD,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACjE,IAAI,IAAI,GAAG,qBAAqB,GAAG,gCAAgC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,gCAAgC,EAAE,CAAC;YAC1I,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACjF,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC;YACzD,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,CAAC;YACR,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI;SACvC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAoB,EAAE,KAAiE;IACnH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAClC,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC;AACjG,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,MAAM,CAAC,uBAAuB,EAAE,wDAAwD,CAAC,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FleetId, Scope } from '@aeolus-fleet/common';
|
|
2
|
+
import type { InstallationCaller } from '../shared/caller.js';
|
|
3
|
+
import { type DomainError } from '../shared/errors.js';
|
|
4
|
+
import { type Result } from '../shared/result.js';
|
|
5
|
+
import type { HostedFleets } from './ports.js';
|
|
6
|
+
/**
|
|
7
|
+
* The scopes the installation holds in every fleet it hosts (decision 0020):
|
|
8
|
+
* what its jobs need of the catalogue, in its order (decision 0053): reading
|
|
9
|
+
* the fleet, managing, defining and assigning labels, commissioning person
|
|
10
|
+
* ships. Until a call lets argo change them, they are the same in every fleet.
|
|
11
|
+
*/
|
|
12
|
+
export declare const INSTALLATION_SCOPES: readonly Scope[];
|
|
13
|
+
export type AuthenticateInstallation = (call: {
|
|
14
|
+
fleetId: FleetId;
|
|
15
|
+
}) => Promise<Result<InstallationCaller, DomainError<'FLEET_NOT_FOUND'>>>;
|
|
16
|
+
/**
|
|
17
|
+
* Use case: the installation, whose token the API adapter checked, acts in
|
|
18
|
+
* one fleet it hosts through the same fleet calls as any actor (decision
|
|
19
|
+
* 0057), with its scopes there and its built-in manage rule.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createAuthenticateInstallation(deps: {
|
|
22
|
+
fleets: HostedFleets;
|
|
23
|
+
}): AuthenticateInstallation;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
/**
|
|
4
|
+
* The scopes the installation holds in every fleet it hosts (decision 0020):
|
|
5
|
+
* what its jobs need of the catalogue, in its order (decision 0053): reading
|
|
6
|
+
* the fleet, managing, defining and assigning labels, commissioning person
|
|
7
|
+
* ships. Until a call lets argo change them, they are the same in every fleet.
|
|
8
|
+
*/
|
|
9
|
+
export const INSTALLATION_SCOPES = ['fleet:read', 'fleet:manage', 'labels:define', 'labels:assign', 'fleet:person', 'labels:any'];
|
|
10
|
+
/**
|
|
11
|
+
* Use case: the installation, whose token the API adapter checked, acts in
|
|
12
|
+
* one fleet it hosts through the same fleet calls as any actor (decision
|
|
13
|
+
* 0057), with its scopes there and its built-in manage rule.
|
|
14
|
+
*/
|
|
15
|
+
export function createAuthenticateInstallation(deps) {
|
|
16
|
+
return async ({ fleetId }) => (await deps.fleets.isHosted(fleetId))
|
|
17
|
+
? ok({ kind: 'installation', fleetId, scopes: INSTALLATION_SCOPES })
|
|
18
|
+
: refuse('FLEET_NOT_FOUND', `This installation hosts no fleet ${fleetId}`);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=authenticate-installation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate-installation.js","sourceRoot":"","sources":["../../../src/domain/identity/authenticate-installation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqB,CAAC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;AAIpJ;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAA8B;IAC3E,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAC3B,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QACpE,CAAC,CAAC,MAAM,CAAC,iBAAiB,EAAE,oCAAoC,OAAO,EAAE,CAAC,CAAC;AACjF,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type LeaseEnded } from '../registry/public.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ShipCaller, Crew } from '../shared/caller.js';
|
|
3
3
|
import type { Clock } from '../shared/clock.js';
|
|
4
4
|
import { type DomainError } from '../shared/errors.js';
|
|
5
5
|
import { type Result } from '../shared/result.js';
|
|
@@ -8,7 +8,7 @@ import type { ConsoleSessionEndReason } from './console-session.js';
|
|
|
8
8
|
import type { CallerLookup } from './ports.js';
|
|
9
9
|
export interface ConsoleSessionUse {
|
|
10
10
|
/** argo, crewed under the lease the session holds, or the viewer ship, holding none. */
|
|
11
|
-
caller:
|
|
11
|
+
caller: ShipCaller | Crew;
|
|
12
12
|
/** The session's new expiry: its idle limit after this use, never past the moment it ends by. */
|
|
13
13
|
expiresAt: Date;
|
|
14
14
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConsoleSessionId, FleetId, LeaseId, ShipId } from '@aeolus-fleet/common';
|
|
1
|
+
import type { AccountId, ConsoleSessionId, FleetId, LeaseId, ShipId } from '@aeolus-fleet/common';
|
|
2
2
|
import type { Location } from '../registry/public.js';
|
|
3
3
|
/**
|
|
4
4
|
* A console session: the operator crewing `argo`, or a person viewing the
|
|
@@ -17,6 +17,8 @@ export interface ConsoleSession {
|
|
|
17
17
|
endsBy: Date | null;
|
|
18
18
|
/** The device it signed in from, as the browser told: "Mac · Chrome". */
|
|
19
19
|
device: string;
|
|
20
|
+
/** The account that signed in as argo, by its id only; null for argo's own sign-in and a viewer (decision 0054). */
|
|
21
|
+
accountId: AccountId | null;
|
|
20
22
|
tokenHash: string;
|
|
21
23
|
createdAt: Date;
|
|
22
24
|
lastUsedAt: Date;
|
|
@@ -27,10 +29,11 @@ export interface ConsoleSession {
|
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* Why a console session ended: the operator signed in somewhere else and took
|
|
30
|
-
* argo over, signed out,
|
|
32
|
+
* argo over, signed out, the password was reset, or the installation cut off
|
|
33
|
+
* the account it signed in as argo (decision 0055). An expired session never
|
|
31
34
|
* ended; it simply stopped working.
|
|
32
35
|
*/
|
|
33
|
-
export type ConsoleSessionEndReason = 'takenOver' | 'signedOut' | 'passwordReset';
|
|
36
|
+
export type ConsoleSessionEndReason = 'takenOver' | 'signedOut' | 'passwordReset' | 'accountCutOff';
|
|
34
37
|
/** The operator's console session stays valid this long after its last use. */
|
|
35
38
|
export declare const CONSOLE_SESSION_IDLE_LIMIT_MS: number;
|
|
36
39
|
/** A viewer session stays valid this long after its last use (decision 0022). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console-session.js","sourceRoot":"","sources":["../../../src/domain/identity/console-session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"console-session.js","sourceRoot":"","sources":["../../../src/domain/identity/console-session.ts"],"names":[],"mappings":"AAwCA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtE,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE/B,iFAAiF;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,GAAG,OAAO,CAAC;AAExD,sFAAsF;AACtF,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,OAAO,CAAC;AAEvD,+CAA+C;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,MAAY;IAC/C,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,6BAA6B,CAAC,CAAC;AACpE,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,kBAAkB,CAAC,EAAQ;IACzC,OAAO;QACL,WAAW,EAAE,4BAA4B;QACzC,MAAM,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,0BAA0B,CAAC;QAC3D,SAAS,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,4BAA4B,CAAC;KACjE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AccountId, IdGenerator } from '@aeolus-fleet/common';
|
|
2
|
+
import { type LeaseTx } from '../registry/public.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
5
|
+
import type { AccountCutOffRepository, ConsoleSessionRepository } from './ports.js';
|
|
6
|
+
export interface CutOffAccountTx extends LeaseTx {
|
|
7
|
+
consoleSessions: ConsoleSessionRepository;
|
|
8
|
+
}
|
|
9
|
+
export type CutOffAccount = (input: {
|
|
10
|
+
accountId: AccountId;
|
|
11
|
+
}) => Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Use case: pagasae, as the installation, cuts off a disabled account
|
|
14
|
+
* (decisions 0055, 0058). Every token of it issued before now is refused in
|
|
15
|
+
* every fleet of the installation, until the longest of them has ended; then
|
|
16
|
+
* core forgets the account. Recording one forgets those that ended. The
|
|
17
|
+
* cut-off itself writes no event: it belongs to the installation, not to a
|
|
18
|
+
* fleet, and names no ship.
|
|
19
|
+
*
|
|
20
|
+
* Every console sign-in as argo by the account ends too, in every fleet, and
|
|
21
|
+
* with it the lease on argo it held, the installation the actor. pagasae calls
|
|
22
|
+
* again when a call fails: both halves are safe to repeat.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createCutOffAccount(deps: {
|
|
25
|
+
cutOffs: AccountCutOffRepository;
|
|
26
|
+
uow: UnitOfWork<CutOffAccountTx>;
|
|
27
|
+
clock: Clock;
|
|
28
|
+
ids: IdGenerator;
|
|
29
|
+
}): CutOffAccount;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { endLease } from '../registry/public.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
import { ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS, ACCOUNT_TOKEN_LIFE_MS } from './authenticate-account.js';
|
|
4
|
+
/**
|
|
5
|
+
* How long a cut-off is kept: the longest a token issued before it is
|
|
6
|
+
* accepted, its life and the allowance on it, and the allowance on its end.
|
|
7
|
+
*/
|
|
8
|
+
const CUT_OFF_KEPT_MS = ACCOUNT_TOKEN_LIFE_MS + 2 * ACCOUNT_TOKEN_CLOCK_ALLOWANCE_MS;
|
|
9
|
+
const INSTALLATION = { kind: 'installation' };
|
|
10
|
+
/**
|
|
11
|
+
* Use case: pagasae, as the installation, cuts off a disabled account
|
|
12
|
+
* (decisions 0055, 0058). Every token of it issued before now is refused in
|
|
13
|
+
* every fleet of the installation, until the longest of them has ended; then
|
|
14
|
+
* core forgets the account. Recording one forgets those that ended. The
|
|
15
|
+
* cut-off itself writes no event: it belongs to the installation, not to a
|
|
16
|
+
* fleet, and names no ship.
|
|
17
|
+
*
|
|
18
|
+
* Every console sign-in as argo by the account ends too, in every fleet, and
|
|
19
|
+
* with it the lease on argo it held, the installation the actor. pagasae calls
|
|
20
|
+
* again when a call fails: both halves are safe to repeat.
|
|
21
|
+
*/
|
|
22
|
+
export function createCutOffAccount(deps) {
|
|
23
|
+
return async ({ accountId }) => {
|
|
24
|
+
const now = deps.clock.now();
|
|
25
|
+
await deps.cutOffs.forget(now);
|
|
26
|
+
await deps.cutOffs.record({ accountId, cutOffAt: now, forgetAt: new Date(now.getTime() + CUT_OFF_KEPT_MS) });
|
|
27
|
+
await deps.uow.run(async (tx) => {
|
|
28
|
+
for (const session of await tx.consoleSessions.endAllOfAccount(accountId, { at: now, reason: 'accountCutOff' })) {
|
|
29
|
+
if (session.leaseId !== null) {
|
|
30
|
+
await endLease({ tx, ids: deps.ids }, { fleetId: session.fleetId, leaseId: session.leaseId, actor: INSTALLATION, at: now, reason: 'accountCutOff' });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return ok(undefined);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=cut-off-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cut-off-account.js","sourceRoot":"","sources":["../../../src/domain/identity/cut-off-account.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AAG/D,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAEzC,OAAO,EAAE,gCAAgC,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGpG;;;GAGG;AACH,MAAM,eAAe,GAAG,qBAAqB,GAAG,CAAC,GAAG,gCAAgC,CAAC;AAErF,MAAM,YAAY,GAAU,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AAQrD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAKnC;IACC,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAE7G,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YAC9B,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC,eAAe,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;gBAChH,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;oBAC7B,MAAM,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;gBACvJ,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShipCaller } from '../shared/caller.js';
|
|
2
2
|
import type { Clock } from '../shared/clock.js';
|
|
3
3
|
import { type DomainError } from '../shared/errors.js';
|
|
4
4
|
import { type Result } from '../shared/result.js';
|
|
5
5
|
import type { NoticeDismissals, NoticeRepository } from './ports.js';
|
|
6
6
|
export type DismissNoticeRefusal = DomainError<'NOTICE_NOT_FOUND' | 'NOTICE_NOT_DISMISSIBLE'>;
|
|
7
|
-
export type DismissNotice = (caller:
|
|
7
|
+
export type DismissNotice = (caller: ShipCaller, input: {
|
|
8
8
|
noticeId: string;
|
|
9
9
|
}) => Promise<Result<undefined, DismissNoticeRefusal>>;
|
|
10
10
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FleetId, IdGenerator } from '@aeolus-fleet/common';
|
|
1
|
+
import type { AccountId, FleetId, IdGenerator } from '@aeolus-fleet/common';
|
|
2
2
|
import { type ShipTx } from '../registry/public.js';
|
|
3
3
|
import type { Clock } from '../shared/clock.js';
|
|
4
4
|
import { type DomainError } from '../shared/errors.js';
|
|
@@ -13,11 +13,15 @@ export interface IssueSignInTicketTx extends ShipTx {
|
|
|
13
13
|
signInTickets: SignInTicketRepository;
|
|
14
14
|
events: EventLog;
|
|
15
15
|
}
|
|
16
|
-
export type IssueSignInTicketRefusal = DomainError<'FLEET_NOT_FOUND' | 'FLEET_HAS_NO_VIEWER'>;
|
|
16
|
+
export type IssueSignInTicketRefusal = DomainError<'FLEET_NOT_FOUND' | 'FLEET_HAS_NO_VIEWER' | 'VIEWER_TICKET_NAMES_NO_ACCOUNT'>;
|
|
17
17
|
export type IssueSignInTicket = (input: {
|
|
18
18
|
fleetId: FleetId;
|
|
19
19
|
/** Whom it signs in as: the operator when left out, or a viewer of a fleet with a viewer ship (decision 0022). */
|
|
20
20
|
as?: SignInAs;
|
|
21
|
+
/** The account it signs in as argo, by its id only (decision 0054); argo's operator ticket when left out. */
|
|
22
|
+
account?: {
|
|
23
|
+
id: AccountId;
|
|
24
|
+
};
|
|
21
25
|
}) => Promise<Result<{
|
|
22
26
|
ticket: string;
|
|
23
27
|
}, IssueSignInTicketRefusal>>;
|
|
@@ -26,7 +30,9 @@ export type IssueSignInTicket = (input: {
|
|
|
26
30
|
* operator, or for a viewer of a fleet with a viewer ship (docs/blueprint.md,
|
|
27
31
|
* "Installation"; decision 0022): the hosting service hands it to the
|
|
28
32
|
* person's browser, and the console redeems it for a session. Only
|
|
29
|
-
* its hash is stored; it is valid 2 minutes and signs in once.
|
|
33
|
+
* its hash is stored; it is valid 2 minutes and signs in once. An operator's
|
|
34
|
+
* ticket may name the account it signs in as argo, by its id only, never
|
|
35
|
+
* a viewer's (decision 0054). Each ticket
|
|
30
36
|
* stands alone: a new one leaves an earlier unused one to expire.
|
|
31
37
|
*/
|
|
32
38
|
export declare function createIssueSignInTicket(deps: {
|
|
@@ -8,14 +8,19 @@ import { SIGN_IN_TICKET_PREFIX, SIGN_IN_TICKET_VALID_MS } from './sign-in-ticket
|
|
|
8
8
|
* operator, or for a viewer of a fleet with a viewer ship (docs/blueprint.md,
|
|
9
9
|
* "Installation"; decision 0022): the hosting service hands it to the
|
|
10
10
|
* person's browser, and the console redeems it for a session. Only
|
|
11
|
-
* its hash is stored; it is valid 2 minutes and signs in once.
|
|
11
|
+
* its hash is stored; it is valid 2 minutes and signs in once. An operator's
|
|
12
|
+
* ticket may name the account it signs in as argo, by its id only, never
|
|
13
|
+
* a viewer's (decision 0054). Each ticket
|
|
12
14
|
* stands alone: a new one leaves an earlier unused one to expire.
|
|
13
15
|
*/
|
|
14
16
|
export function createIssueSignInTicket(deps) {
|
|
15
|
-
return ({ fleetId, as = 'operator' }) => deps.uow.run(async (tx) => {
|
|
17
|
+
return ({ fleetId, as = 'operator', account }) => deps.uow.run(async (tx) => {
|
|
16
18
|
if (!(await tx.operatorAccounts.findForFleet(fleetId))) {
|
|
17
19
|
return refuse('FLEET_NOT_FOUND', `The installation hosts no fleet ${fleetId}`);
|
|
18
20
|
}
|
|
21
|
+
if (as === 'viewer' && account !== undefined) {
|
|
22
|
+
return refuse('VIEWER_TICKET_NAMES_NO_ACCOUNT', 'A viewer ticket names no account: the viewer is no account');
|
|
23
|
+
}
|
|
19
24
|
if (as === 'viewer') {
|
|
20
25
|
const viewer = await findViewerShip(tx, fleetId);
|
|
21
26
|
if (!viewer.isOk) {
|
|
@@ -27,6 +32,7 @@ export function createIssueSignInTicket(deps) {
|
|
|
27
32
|
await tx.signInTickets.create({
|
|
28
33
|
fleetId,
|
|
29
34
|
as,
|
|
35
|
+
accountId: account?.id ?? null,
|
|
30
36
|
tokenHash: deps.hasher.hash(ticket),
|
|
31
37
|
issuedAt: at,
|
|
32
38
|
expiresAt: new Date(at.getTime() + SIGN_IN_TICKET_VALID_MS),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-sign-in-ticket.js","sourceRoot":"","sources":["../../../src/domain/identity/issue-sign-in-ticket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAe,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAItD,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAiB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"issue-sign-in-ticket.js","sourceRoot":"","sources":["../../../src/domain/identity/issue-sign-in-ticket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAe,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAItD,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAiB,MAAM,qBAAqB,CAAC;AAkBpG;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAMvC;IACC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,CAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAiE,EAAE;QACvF,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,OAAO,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,MAAM,CAAC,gCAAgC,EAAE,4DAA4D,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;YAC5B,OAAO;YACP,EAAE;YACF,SAAS,EAAE,OAAO,EAAE,EAAE,IAAI,IAAI;YAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACnC,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,uBAAuB,CAAC;YAC3D,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QACH,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACjJ,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ConsoleSessionId, CredentialId, FleetId, LeaseId, OperatorId, ShipId, Theme } from '@aeolus-fleet/common';
|
|
2
|
-
import type {
|
|
1
|
+
import type { AccountId, AccountTokenClaims, ConsoleSessionId, CredentialId, FleetId, LeaseId, OperatorId, ShipId, Theme } from '@aeolus-fleet/common';
|
|
2
|
+
import type { ShipCaller, Crew } from '../shared/caller.js';
|
|
3
3
|
import type { ConsoleSession, ConsoleSessionEndReason } from './console-session.js';
|
|
4
4
|
import type { Credential } from './credential.js';
|
|
5
5
|
import type { Guide, GuideProgress } from './guide.js';
|
|
@@ -7,7 +7,7 @@ import type { Notice } from './notice.js';
|
|
|
7
7
|
import type { OperatorAccount } from './operator-account.js';
|
|
8
8
|
import type { SignInAs, SignInTicket } from './sign-in-ticket.js';
|
|
9
9
|
/** The ship a crew token or a console session token belongs to, as the caller it makes. */
|
|
10
|
-
export type AuthenticatedShip = Omit<
|
|
10
|
+
export type AuthenticatedShip = Omit<ShipCaller, 'consoleSessionId'>;
|
|
11
11
|
/** The ship a crew token crews, and the open lease the token belongs to. */
|
|
12
12
|
export type AuthenticatedCrew = AuthenticatedShip & {
|
|
13
13
|
leaseId: LeaseId;
|
|
@@ -96,9 +96,10 @@ export interface SignInTicketRepository {
|
|
|
96
96
|
redeem(tokenHash: string, at: Date): Promise<{
|
|
97
97
|
fleetId: FleetId;
|
|
98
98
|
as: SignInAs;
|
|
99
|
+
accountId: AccountId | null;
|
|
99
100
|
} | undefined>;
|
|
100
101
|
}
|
|
101
|
-
/** Outbound port: console sessions,
|
|
102
|
+
/** Outbound port: console sessions, within one fleet but for the account's, which spans the installation. */
|
|
102
103
|
export interface ConsoleSessionRepository {
|
|
103
104
|
create(session: ConsoleSession): Promise<void>;
|
|
104
105
|
/** The session, read without a lock. */
|
|
@@ -118,6 +119,15 @@ export interface ConsoleSessionRepository {
|
|
|
118
119
|
at: Date;
|
|
119
120
|
reason: ConsoleSessionEndReason;
|
|
120
121
|
}): Promise<ConsoleSession[]>;
|
|
122
|
+
/**
|
|
123
|
+
* Ends every session the account signed in to as argo that has not ended, in
|
|
124
|
+
* every fleet of the installation, and returns them: a cut-off belongs to the
|
|
125
|
+
* installation, not to a fleet (decision 0055).
|
|
126
|
+
*/
|
|
127
|
+
endAllOfAccount(accountId: AccountId, ending: {
|
|
128
|
+
at: Date;
|
|
129
|
+
reason: ConsoleSessionEndReason;
|
|
130
|
+
}): Promise<ConsoleSession[]>;
|
|
121
131
|
}
|
|
122
132
|
/**
|
|
123
133
|
* Outbound port: who is calling. Each lookup is one query that returns the
|
|
@@ -146,7 +156,7 @@ export interface CallerLookup {
|
|
|
146
156
|
tokenHash: string;
|
|
147
157
|
now: Date;
|
|
148
158
|
}): Promise<{
|
|
149
|
-
caller:
|
|
159
|
+
caller: ShipCaller | Crew;
|
|
150
160
|
expiresAt: Date;
|
|
151
161
|
} | undefined>;
|
|
152
162
|
/** Why the console session with this token hash ended; undefined when it has not, or no session has the hash. */
|
|
@@ -191,3 +201,40 @@ export interface GuideProgressRepository {
|
|
|
191
201
|
at: Date;
|
|
192
202
|
} & GuideProgress): Promise<void>;
|
|
193
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Outbound port: pagasae's signature on an account token (decision 0058).
|
|
206
|
+
* Core trusts one issuer and its published keys.
|
|
207
|
+
*/
|
|
208
|
+
export interface AccountTokenSignatures {
|
|
209
|
+
/**
|
|
210
|
+
* The token's claims when a key the issuer publishes signed it as an
|
|
211
|
+
* access token naming that issuer; undefined for any other token. Says
|
|
212
|
+
* nothing of its fleet, its end or a cut-off: the use case checks those.
|
|
213
|
+
*/
|
|
214
|
+
verify(token: string): Promise<AccountTokenClaims | undefined>;
|
|
215
|
+
}
|
|
216
|
+
/** An account pagasae cut off (decision 0058): its tokens issued before `cutOffAt` are refused until `forgetAt`. */
|
|
217
|
+
export interface AccountCutOff {
|
|
218
|
+
accountId: AccountId;
|
|
219
|
+
cutOffAt: Date;
|
|
220
|
+
forgetAt: Date;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Outbound port: the accounts pagasae cut off (decision 0058), kept by the
|
|
224
|
+
* installation for every fleet it hosts, each until the longest token it
|
|
225
|
+
* refuses has ended. Not scoped by fleet: an account's tokens go to several
|
|
226
|
+
* fleets, and the cut-off holds in each (ADR 0007, the installation).
|
|
227
|
+
*/
|
|
228
|
+
export interface AccountCutOffRepository {
|
|
229
|
+
/** Keeps the cut-off; one kept for the account with a later cut-off stays as it was. */
|
|
230
|
+
record(cutOff: AccountCutOff): Promise<void>;
|
|
231
|
+
/** When the account was last cut off, while that cut-off is kept at `at`; undefined otherwise. */
|
|
232
|
+
cutOffAt(accountId: AccountId, at: Date): Promise<Date | undefined>;
|
|
233
|
+
/** Forgets every cut-off kept no longer than `at`. */
|
|
234
|
+
forget(at: Date): Promise<void>;
|
|
235
|
+
}
|
|
236
|
+
export type AccountCutOffLookup = Pick<AccountCutOffRepository, 'cutOffAt'>;
|
|
237
|
+
/** Outbound port: whether this installation hosts a fleet, so a token for any other is refused. */
|
|
238
|
+
export interface HostedFleets {
|
|
239
|
+
isHosted(fleetId: FleetId): Promise<boolean>;
|
|
240
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Theme } from '@aeolus-fleet/common';
|
|
2
|
-
import type {
|
|
1
|
+
import type { AccountId, Theme } from '@aeolus-fleet/common';
|
|
2
|
+
import type { ShipCaller } from '../shared/caller.js';
|
|
3
3
|
import { type DomainError } from '../shared/errors.js';
|
|
4
4
|
import { type Result } from '../shared/result.js';
|
|
5
5
|
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
@@ -13,17 +13,21 @@ interface SessionView {
|
|
|
13
13
|
device: string;
|
|
14
14
|
since: Date;
|
|
15
15
|
}
|
|
16
|
+
/** The operator's session, with the account that signed in as argo, by its id, or none for argo's own sign-in (decision 0054). */
|
|
17
|
+
interface OperatorSessionView extends SessionView {
|
|
18
|
+
accountId: AccountId | null;
|
|
19
|
+
}
|
|
16
20
|
/** The operator's account with this session, or a viewer's session alone: a viewer has no email and no theme (decision 0022). */
|
|
17
21
|
export type AccountView = {
|
|
18
22
|
kind: 'operator';
|
|
19
23
|
email: string;
|
|
20
24
|
theme: Theme;
|
|
21
|
-
session:
|
|
25
|
+
session: OperatorSessionView;
|
|
22
26
|
} | {
|
|
23
27
|
kind: 'viewer';
|
|
24
28
|
session: SessionView;
|
|
25
29
|
};
|
|
26
|
-
export type ReadAccount = (caller:
|
|
30
|
+
export type ReadAccount = (caller: ShipCaller) => Promise<Result<AccountView, DomainError<'NOT_THE_OPERATOR_SHIP'>>>;
|
|
27
31
|
/**
|
|
28
32
|
* Use case: the signed-in operator's account, for the AccountMenu: their
|
|
29
33
|
* email, their theme, and this console session; for a viewer session, the
|
|
@@ -20,7 +20,7 @@ export function createReadAccount(deps) {
|
|
|
20
20
|
kind: 'operator',
|
|
21
21
|
email: account.email,
|
|
22
22
|
theme: account.theme,
|
|
23
|
-
session: { device: session.device, since: session.createdAt },
|
|
23
|
+
session: { device: session.device, since: session.createdAt, accountId: session.accountId },
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-account.js","sourceRoot":"","sources":["../../../src/domain/identity/read-account.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"read-account.js","sourceRoot":"","sources":["../../../src/domain/identity/read-account.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAyBtD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwC;IACxE,OAAO,CAAC,MAAM,EAAE,EAAE,CAChB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAsE,EAAE;QAC5F,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC;QACpC,MAAM,OAAO,GAAG,gBAAgB,IAAI,CAAC,MAAM,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACtG,IAAI,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,uBAAuB,EAAE,6DAA6D,CAAC,CAAC;QACxG,CAAC;QACD,OAAO,EAAE,CAAC;YACR,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;SAC5F,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShipCaller } from '../shared/caller.js';
|
|
2
2
|
import { type GuideProgress, type GuideStep } from './guide.js';
|
|
3
3
|
import type { GuideProgressRepository, GuideRepository } from './ports.js';
|
|
4
|
-
export type ReadGuide = (caller:
|
|
4
|
+
export type ReadGuide = (caller: ShipCaller) => Promise<{
|
|
5
5
|
steps: readonly GuideStep[];
|
|
6
6
|
progress: GuideProgress;
|
|
7
7
|
} | null>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShipCaller } from '../shared/caller.js';
|
|
2
2
|
import { type Notice } from './notice.js';
|
|
3
3
|
import type { NoticeDismissals, NoticeRepository } from './ports.js';
|
|
4
|
-
export type ReadNotices = (caller:
|
|
4
|
+
export type ReadNotices = (caller: ShipCaller) => Promise<Notice[]>;
|
|
5
5
|
/**
|
|
6
6
|
* Use case: the notices a console session shows above every page (decision
|
|
7
7
|
* 0023): those of its audience, in the installation's order, less the
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShipCaller } from '../shared/caller.js';
|
|
2
2
|
import type { Clock } from '../shared/clock.js';
|
|
3
3
|
import { type DomainError } from '../shared/errors.js';
|
|
4
4
|
import { type Result } from '../shared/result.js';
|
|
5
5
|
import type { GuideProgress } from './guide.js';
|
|
6
6
|
import type { GuideProgressRepository, GuideRepository } from './ports.js';
|
|
7
7
|
export type RecordGuideProgressRefusal = DomainError<'GUIDE_NOT_FOUND' | 'GUIDE_STEP_NOT_FOUND'>;
|
|
8
|
-
export type RecordGuideProgress = (caller:
|
|
8
|
+
export type RecordGuideProgress = (caller: ShipCaller, progress: GuideProgress) => Promise<Result<undefined, RecordGuideProgressRefusal>>;
|
|
9
9
|
/**
|
|
10
10
|
* Use case: a console session records where it is in the guide, for itself
|
|
11
11
|
* only (decision 0024): open at a step, skipped or finished; open at the
|
|
@@ -19,7 +19,8 @@ export type RedeemSignInTicket = (input: {
|
|
|
19
19
|
}) => Promise<Result<SignedIn, RedeemSignInTicketRefusal>>;
|
|
20
20
|
/**
|
|
21
21
|
* Use case: the console redeems a sign-in ticket the installation issued. An
|
|
22
|
-
* operator's ticket starts the session exactly as after a password sign-in
|
|
22
|
+
* operator's ticket starts the session exactly as after a password sign-in,
|
|
23
|
+
* keeping the account it names, if any (decision 0054):
|
|
23
24
|
* it takes argo's lease over and ends any previous session. A viewer's starts
|
|
24
25
|
* a viewer session beside any others (decision 0022). A ticket signs in once and
|
|
25
26
|
* only before it expires; used, expired and unknown tickets are one refusal,
|
|
@@ -4,7 +4,8 @@ import { startConsoleSession } from './start-console-session.js';
|
|
|
4
4
|
import { startViewerSession } from './start-viewer-session.js';
|
|
5
5
|
/**
|
|
6
6
|
* Use case: the console redeems a sign-in ticket the installation issued. An
|
|
7
|
-
* operator's ticket starts the session exactly as after a password sign-in
|
|
7
|
+
* operator's ticket starts the session exactly as after a password sign-in,
|
|
8
|
+
* keeping the account it names, if any (decision 0054):
|
|
8
9
|
* it takes argo's lease over and ends any previous session. A viewer's starts
|
|
9
10
|
* a viewer session beside any others (decision 0022). A ticket signs in once and
|
|
10
11
|
* only before it expires; used, expired and unknown tickets are one refusal,
|
|
@@ -17,7 +18,7 @@ export function createRedeemSignInTicket(deps) {
|
|
|
17
18
|
if (redeemed === undefined) {
|
|
18
19
|
return refuse('SIGN_IN_TICKET_INVALID', 'This sign-in link is used or expired: sign in again');
|
|
19
20
|
}
|
|
20
|
-
const session = { fleetId: redeemed.fleetId, device: input.device ?? UNKNOWN_DEVICE, at };
|
|
21
|
+
const session = { fleetId: redeemed.fleetId, device: input.device ?? UNKNOWN_DEVICE, accountId: redeemed.accountId, at };
|
|
21
22
|
const starting = { tx, ids: deps.ids, hasher: deps.hasher, random: deps.random };
|
|
22
23
|
return redeemed.as === 'viewer' ? startViewerSession(starting, session) : startConsoleSession(starting, session);
|
|
23
24
|
});
|